diff --git a/InventoryManager.txt b/InventoryManager.txt
index 21252a4..43e6ae7 100644
--- a/InventoryManager.txt
+++ b/InventoryManager.txt
@@ -2,7 +2,7 @@
## APIVersion: 100019
## OptionalDependsOn: LibAddonMenu-2.0
## SavedVariables: IMSavedVars
-## Version: 1.3.1
+## Version: 1.4.0
## Author: iwontsay
## Description: iwontsay's Inventory Manager
diff --git a/Modules/Banking.lua b/Modules/Banking.lua
index 44de1e0..29e0352 100644
--- a/Modules/Banking.lua
+++ b/Modules/Banking.lua
@@ -15,7 +15,7 @@ local function CreateReverseCache(bagType)
local _revCache = { }
local _empties = { }
- for i = 0, GetBagSize(bagType)-1, 1 do
+ for i = 0, GetBagUseableSize(bagType)-1, 1 do
local curStack, maxStack = GetSlotStackSize(bagType, i)
if curStack > 0 then
local id = GetItemInstanceId(bagType, i)
@@ -34,8 +34,9 @@ end
local function CreateReverseCaches()
RevCaches = { }
Empties = { }
- RevCaches[BAG_BACKPACK], Empties[BAG_BACKPACK] = CreateReverseCache(BAG_BACKPACK)
- RevCaches[BAG_BANK], Empties[BAG_BANK] = CreateReverseCache(BAG_BANK)
+ RevCaches[BAG_SUBSCRIBER_BANK], Empties[BAG_SUBSCRIBER_BANK] = CreateReverseCache(BAG_SUBSCRIBER_BANK)
+ RevCaches[BAG_BACKPACK], Empties[BAG_BACKPACK] = CreateReverseCache(BAG_BACKPACK)
+ RevCaches[BAG_BANK], Empties[BAG_BANK] = CreateReverseCache(BAG_BANK)
end
local function UpdateCaches(srcBagType, srcSlotId, tgtBagType, tgtSlotId, count)
@@ -72,49 +73,79 @@ local function UpdateCaches(srcBagType, srcSlotId, tgtBagType, tgtSlotId, count)
end
end
--- Returns (empties source?), tgtSlotId, transferCount
+-- Returns tgtSlotId, count
+local function FindStackToFill(id, count, tgtBagType)
+ local stacks = RevCaches[tgtBagType][id]
+ if not stacks then return nil end
+
+ local tgtSlotId = nil
+ local tgtCount = 0
+
+ for slotId, v in pairs(stacks) do
+ local missing = v[2] - v[1]
+ if missing >= count then return slotId, count end
+ if missing > tgtCount then
+ tgtSlotId = slotId
+ tgtCount = missing
+ end
+ end
+
+ return tgtSlotId, tgtCount
+end
+
+-- Returns (empties source?), tgtSlotId, transferCount, tgtBagType
+-- We try the subscriber bank before the regular one, to keep the slots of the regular one free in case
+-- someone unsubs.
local function FindTargetSlot(srcBagType, srcSlotId, tgtBagType)
local curStack, maxStack = GetSlotStackSize(srcBagType, srcSlotId)
local id = GetItemInstanceId(srcBagType, srcSlotId)
- local stacks = RevCaches[tgtBagType][id]
- if stacks then
- -- First, try to find a stack small enough to hold the entirety of the source
- for tgtSlotId, v in pairs(stacks) do
- if v[2]-v[1] >= curStack then
- UpdateCaches(srcBagType, srcSlotId, tgtBagType, tgtSlotId, curStack)
- return true, tgtSlotId, curStack
- end
- end
-
- -- Now, fill any incomplete stack we might have, splitting the source stack
- for tgtSlotId, v in pairs(stacks) do
- local missing = v[2] - v[1]
- if missing > 0 then
- UpdateCaches(srcBagType, srcSlotId, tgtBagType, tgtSlotId, missing)
- return false, tgtSlotId, missing
- end
- end
+ local tgtSlotId = nil
+ local transferCount = nil
+
+ -- Try the subscriber bank before the regular one if we target the bank
+ if tgtBagType == BAG_BANK then
+ tgtSlotId, transferCount = FindStackToFill(id, curStack, BAG_SUBSCRIBER_BANK)
end
-
+ if tgtSlotId ~= nil then
+ tgtBagType = BAG_SUBSCRIBER_BANK
+ else
+ tgtSlotId, transferCount = FindStackToFill(id, curStack, tgtBagType)
+ end
+
+ if tgtSlotId ~= nil then
+ UpdateCaches(srcBagType, srcSlotId, tgtBagType, tgtSlotId, transferCount)
+ return ( transferCount == curStack ), tgtSlotId, transferCount, tgtBagType
+ end
+
-- All the stacks we might have found are already full, we need to find a free slot
- local empties = Empties[tgtBagType]
+ local empties = { }
+
+ -- Again, try the subscriber bank before the regular one if we target the bank
+ if tgtBagType == BAG_BANK then
+ empties = Empties[BAG_SUBSCRIBER_BANK]
+ end
+
+ if #empties ~= 0 then
+ tgtBagType = BAG_SUBSCRIBER_BANK
+ else
+ empties = Empties[tgtBagType]
+ end
-- No such luck?
- if #empties == 0 then return false, -1, 0 end
+ if #empties == 0 then return false, -1, 0, tgtBagType end
- -- It's a complete move, remove the empty slot from the target list, and create a new one on the source list
+ -- It's a complete move, remove the empty slot from the target list
local tgtSlotId = empties[#empties]
empties[#empties] = nil
UpdateCaches(srcBagType, srcSlotId, tgtBagType, tgtSlotId, curStack)
- return true, tgtSlotId, curStack
+ return true, tgtSlotId, curStack, tgtBagType
end
-local function CollectSingleDirection(action)
- local bagType = (action == InventoryManager.ACTION_STASH and BAG_BACKPACK) or BAG_BANK
+local function CollectSingleDirection(action, bagType)
local _moveSlots = { }
InventoryManager:SetCurrentInventory(bagType)
@@ -128,16 +159,25 @@ local function CollectSingleDirection(action)
return _moveSlots
end
-local function CalculateSingleMove(direction)
- local srcBagType = (direction == 1 and BAG_BACKPACK) or BAG_BANK
- local tgtBagType = (direction == 1 and BAG_BANK) or BAG_BACKPACK
+local function CalculateSingleMove(srcBagType, tgtBagType)
+
+ local srcSlotRepo = Moves[srcBagType]
+
+ -- If we draw from the pending moves from the regular bank and there are none,
+ -- try the subscriber bank.
+ if #srcSlotRepo == 0 and srcBagType == BAG_BANK then
+ srcBagType = BAG_SUBSCRIBER_BANK
+ srcSlotRepo = Moves[srcBagType]
+ end
- local srcSlotRepo = Moves[(direction == 1 and "stash") or "retrieve"]
if #srcSlotRepo == 0 then return "src_empty" end
local srcSlotId = srcSlotRepo[#srcSlotRepo]
- local empties, tgtSlotId, count = FindTargetSlot(srcBagType, srcSlotId, tgtBagType)
+ -- if we target the bank, FindTargetSlot returns the subscriber bank first, if possible
+ local empties, tgtSlotId, count
+ empties, tgtSlotId, count, tgtBagType = FindTargetSlot(srcBagType, srcSlotId, tgtBagType)
+
if count == 0 then return "tgt_full" end
if empties then srcSlotRepo[#srcSlotRepo] = nil end
@@ -160,15 +200,16 @@ local function CalculateMoves()
InventoryManager.currentRuleset:ResetCounters()
Moves = {
- ["stash"] = CollectSingleDirection(IM.ACTION_STASH),
- ["retrieve"] = CollectSingleDirection(IM.ACTION_RETRIEVE)
+ [BAG_BACKPACK] = CollectSingleDirection(IM.ACTION_STASH, BAG_BACKPACK),
+ [BAG_BANK] = CollectSingleDirection(IM.ACTION_RETRIEVE, BAG_BANK),
+ [BAG_SUBSCRIBER_BANK] = CollectSingleDirection(IM.ACTION_RETRIEVE, BAG_SUBSCRIBER_BANK),
}
-- We alternate between stashing and retrieving to minimize the chance of one
-- of the inventories running full.
while continue do
- local leftres, leftentry = CalculateSingleMove(1)
- local rightres, rightentry = CalculateSingleMove(-1)
+ local leftres, leftentry = CalculateSingleMove(BAG_BACKPACK, BAG_BANK)
+ local rightres, rightentry = CalculateSingleMove(BAG_BANK, BAG_BACKPACK)
-- ZOS Spam limitation
if #_moveStack > 95 then
diff --git a/Modules/Data.lua b/Modules/Data.lua
index 52c7ff5..2e486d8 100644
--- a/Modules/Data.lua
+++ b/Modules/Data.lua
@@ -33,6 +33,7 @@ InventoryManager.ACTION_RETRIEVE = 20
IM_Ruleset.ITEM_TRAIT_TYPE_ANY = -1
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKOTHERS = -2
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN = -3
+IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT = -4
InventoryManager.filterorder = {
@@ -124,7 +125,8 @@ InventoryManager.actionorder = {
InventoryManager.traitsorder = {
["IM_FILTER_ANY"] = {
0, -- Redefined to "don't care about traits"
- IM_Ruleset.ITEM_TRAIT_TYPE_ANY,
+ IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT,
+ IM_Ruleset.ITEM_TRAIT_TYPE_ANY,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKOTHERS,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN,
ITEM_TRAIT_TYPE_WEAPON_INTRICATE,
@@ -132,6 +134,7 @@ InventoryManager.traitsorder = {
},
["IM_FILTER_WEAPON"] = {
0, -- Redefined to "don't care about traits"
+ IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT,
IM_Ruleset.ITEM_TRAIT_TYPE_ANY,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKOTHERS,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN,
@@ -149,6 +152,7 @@ InventoryManager.traitsorder = {
},
["IM_FILTER_APPAREL"] = {
0, -- Redefined to "don't care about traits"
+ IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT,
IM_Ruleset.ITEM_TRAIT_TYPE_ANY,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKOTHERS,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN,
@@ -166,6 +170,7 @@ InventoryManager.traitsorder = {
},
["IM_FILTERSPEC_JEWELRY"] = {
0, -- Redefined to "don't care about traits"
+ IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT,
IM_Ruleset.ITEM_TRAIT_TYPE_ANY,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKOTHERS,
IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN,
diff --git a/Modules/Extractor.lua b/Modules/Extractor.lua
index 94b96b5..5fdf1a8 100644
--- a/Modules/Extractor.lua
+++ b/Modules/Extractor.lua
@@ -101,6 +101,10 @@ local function InitDeconstruction(tradeskill)
function(data) return filter_for_deconstruction(tradeskill, data) end,
list)
+ list = IM:CreateInventoryList(BAG_SUBSCRIBER_BANK,
+ function(data) return filter_for_deconstruction(tradeskill, data) end,
+ list)
+
IM:DoEventProcessing(list,
function(data) return extract_single_item(tradeskill, data) end,
function() end,
diff --git a/Rulesets.lua b/Rulesets.lua
index 8686d8f..4828715 100644
--- a/Rulesets.lua
+++ b/Rulesets.lua
@@ -47,6 +47,7 @@ function IM_Rule:ToString()
if self.traitType then
local which = (self.filterType == "IM_FILTER_CONSUMABLE" and 1) or 0
if self.traitType < 0 then
+ if self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT then which = 2 end
local str = (self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_ANY and "") or GetString("IM_META_TRAIT_TYPE", -self.traitType)
itemDescription = zo_strformat(
GetString("IM_META_TRAIT_TYPE_FORMAT", which),
@@ -145,6 +146,8 @@ function IM_Rule:Filter(data)
if self.traitType then
if self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_ANY then
if traitType == ITEM_TRAIT_TYPE_NONE then return false end
+ elseif self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT then
+ if traitType ~= ITEM_TRAIT_TYPE_NONE then return false end
elseif self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKOTHERS then
if not data.unknownothers then return false end
elseif self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN then
diff --git a/lang/de.lua b/lang/de.lua
index 695a10d..9e6eee0 100644
--- a/lang/de.lua
+++ b/lang/de.lua
@@ -80,10 +80,12 @@ local lang = {
IM_META_TRAIT_TYPE_FORMAT0 = "<<1>> mit jeder Eigenschaft, die <<2>> ist",
IM_META_TRAIT_TYPE_FORMAT1 = "<<1>> welches <<2>> ist",
+ IM_META_TRAIT_TYPE_FORMAT2 = "<<1>> ohne eine Eigenschaft",
IM_META_TRAIT_TYPE0 = "(irrelevant)",
IM_META_TRAIT_TYPE1 = "jede Eigenschaft",
IM_META_TRAIT_TYPE2 = "unbekannt für andere",
IM_META_TRAIT_TYPE3 = "unbekannt",
+ IM_META_TRAIT_TYPE4 = "keine Eigenschaft",
IM_RE_CURRENTRULES = "Derzeitige Regeln",
IM_RE_DELETERULE = "Regel löschen",
diff --git a/lang/en.lua b/lang/en.lua
index 23137dc..5637a8b 100644
--- a/lang/en.lua
+++ b/lang/en.lua
@@ -80,10 +80,12 @@ local lang = {
IM_META_TRAIT_TYPE_FORMAT0 = "<<1>> with any trait <<2>>",
IM_META_TRAIT_TYPE_FORMAT1 = "<<1>> which is <<2>>",
+ IM_META_TRAIT_TYPE_FORMAT2 = "<<1>> with no trait",
IM_META_TRAIT_TYPE0 = "(irrelevant)",
IM_META_TRAIT_TYPE1 = "any trait",
IM_META_TRAIT_TYPE2 = "unknown to others",
IM_META_TRAIT_TYPE3 = "unknown",
+ IM_META_TRAIT_TYPE4 = "no trait",
IM_RE_CURRENTRULES = "Current Rules",
IM_RE_DELETERULE = "Delete Rule",