player = Turbine.Gameplay.LocalPlayer.GetInstance()
backpack = player:GetBackpack()
size =backpack:GetSize()
function Sort()
import "Turbine.UI";
--An attempt to make as many variables local to this proc as possible. May avoid the crash? Either way it "feels" right to have as much data disappear as possible.
local VirtPack
local item
local Category
local CategoryText
local CatWeight
local FirstStart
local Name
local Quality
local QualWeight
local Slot
local Start
Timer=Turbine.UI.Control()
function Timer:Start()
Turbine.Shell.WriteLine("<rgb=#888888>Sort Started")
FirstStart= Turbine.Engine.GetGameTime()
VirtPack=analysepack()
Slot=1
Start= Turbine.Engine.GetGameTime()
Timer:SetWantsUpdates(true)
end
function Timer:Update()
local Time = Turbine.Engine.GetGameTime()
local elapsed = Time - Start
if Slot>size then
Timer:SetWantsUpdates(false)
Timer=nil
backpack=nil
Turbine.Shell.WriteLine("<rgb=#888888>Sort finished after "..Time-FirstStart.." seconds.")
return
end
--Get the name of the target item
target=VirtPack[Slot].Name
--Get item in current slot
item=backpack:GetItem(Slot)
--Get the name of the item in the current slot. If empty return that name as "zEmpty"
if item~=nil then Name=item:GetName() else Name="zEmpty" end
--Turbine.Shell.WriteLine("<rgb=#888888>Slot "..Slot.." should contain "..target.." but contains ".. Name)
--If the Name of the current item is equal to the target name, move on.
if Name==target then Slot=Slot+1 return end
if elapsed>0.2 then
--Search for the item in the rest of the pack.
for i=Slot+1,size do
item=backpack:GetItem(i)
if item~=nil then item=item:GetName() else item="zEmpty" end
if item==target then
swop(i,Slot)
Start= Turbine.Engine.GetGameTime()
return
end
end
Turbine.Shell.WriteLine("<rgb=#888888>Should never get here! Error in Update function. Did your inventory change during the sort? Restarting!")
Timer:SetWantsUpdates(false)
Timer:Start()
end
end
function swop(i,j)
if backpack:GetItem(j)==backpack:GetItem(i) then return end
item=backpack:GetItem(j)
if item~=nil then
backpack:PerformItemDrop(item,i, false)
return
end
item=backpack:GetItem(i)
if item~=nil then
backpack:PerformItemDrop(item,j, false)
return
end
Turbine.Shell.WriteLine("<rgb=#888888>Should never be seen. Error in Swop function.")
Timer:SetWantsUpdates(false)
Timer:Start()
end
Timer:Start()
end
function weight(i)
--Calculate the weight
local Weight = 0
item = backpack:GetItem(i)
if item == nil then
--Empty slots have no name, quality, category etc
Category=0
Quality=0
else
Category=item:GetCategory()
Quality=item:GetQuality()
if Quality==nil then Quality=0 end
end
CategoryText=ItemCategory[Category]
if CategoryText~=nil then
CatWeight=value[CategoryText] --First scan the CategoryText using the value table
else
--This item has not been given a category number by turbine - it is missing from the category text list.
Turbine.Shell.WriteLine("<rgb=#888888>"..item:GetName().." has not been given category text by Turbine. Dammit. It's number is "..Category.." Please inform MrJackdaw!")
end
QualWeight=Quality
Weight=CatWeight*10--+QualWeight
if item==nil then Weight = 99999 end
return Weight
end
function strip(str)
--Strip numbers first 7 characters to make the sort more logical
local left=string.sub(str, 1, 7)
local right=string.sub(str, 8)
left=string.gsub(left,"[^%a]","")
str= left .. right
--Strip all spaces now!
str=string.gsub(str,"[%s]","")
return str
end
function analysepack()
local VirtPack={}
for i=1,size do
VirtPack[i]={}
VirtPack[i].id=i
item = backpack:GetItem(i)
if item~=nil then
VirtPack[i].Name=item:GetName()
local Category=item:GetCategory()
local CategoryText=ItemCategory[Category]
for j=1,#Groups do
for k=1,#Groups[j] do
if Groups[j][k]==CategoryText then VirtPack[i].Group=j end
end
end
else
VirtPack[i].Name="zEmpty"
end
end
for i=1,size do
VirtPack[i].Weight=weight(i)
end
--Sort VirtPack. If the weight of two items is the same compare the Names, after removing some characters. This way "2 Morale Potions" will get sorted with "Morale Potions"
table.sort(VirtPack, function (a,b)
if a.Weight == b.Weight then
--return a.Name < b.Name
return strip(a.Name)< strip(b.Name)
else
return (a.Weight < b.Weight)
end
end)
return VirtPack
end