diff --git a/CraftStoreLink.lua b/CraftStoreLink.lua index fb98927..43a3cca 100644 --- a/CraftStoreLink.lua +++ b/CraftStoreLink.lua @@ -6,6 +6,9 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end +local IM = InventoryManager + local CSL = {} local Used_CS @@ -13,7 +16,7 @@ local Used_CSA local hasCS = nil -InventoryManager.CSL = CSL +IM.CSL = CSL local function SplitLink(link,nr) local split = {SplitString(':', link)} diff --git a/FCOISLink.lua b/FCOISLink.lua index 446811a..ed76912 100644 --- a/FCOISLink.lua +++ b/FCOISLink.lua @@ -5,7 +5,10 @@ d local function _tr(str) return str end - + +if not InventoryManager then InventoryManager = {} end +local IM = InventoryManager + local TXT_NO_CARE local TXT_NO_MARK local TXT_ANY_MARK @@ -21,7 +24,7 @@ local hasFCOIS = nil local staticIconList = nil local protection_fns = nil -InventoryManager.FCOISL = FCOISL +IM.FCOISL = FCOISL local DIList = nil local DIChoices = nil @@ -52,13 +55,13 @@ function FCOISL:hasAddon() } protected_actions = { - [InventoryManager.ACTION_DESTROY] = FCOIS.IsDestroyLocked, - [InventoryManager.ACTION_SELL] = { + [IM.ACTION_DESTROY] = FCOIS.IsDestroyLocked, + [IM.ACTION_SELL] = { [false] = FCOIS.IsVendorSellLocked, [true] = FCOIS.IsFenceSellLocked }, - [InventoryManager.ACTION_LAUNDER] = FCOIS.IsLaunderLocked, - [InventoryManager.ACTION_DECONSTRUCT] = { + [IM.ACTION_LAUNDER] = FCOIS.IsLaunderLocked, + [IM.ACTION_DECONSTRUCT] = { [false] = FCOIS.IsDeconstructionLocked, [true] = FCOIS.IsEnchantingExtractionLocked }, diff --git a/InventoryManager.lua b/InventoryManager.lua index 97274f9..fe32149 100644 --- a/InventoryManager.lua +++ b/InventoryManager.lua @@ -6,47 +6,29 @@ local function _tr(str) return str end -InventoryManager = {} - +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager -InventoryManager.LAM = LibStub:GetLibrary("LibAddonMenu-2.0") +IM.LAM = LibStub:GetLibrary("LibAddonMenu-2.0") -InventoryManager.name = "InventoryManager" -InventoryManager.loadedAddons = {} +IM.name = "InventoryManager" +IM.loadedAddons = {} -- The current inventory we're working on -InventoryManager.currentInventory = nil -InventoryManager.currentBagType = nil +IM.currentInventory = nil +IM.currentBagType = nil -- The current ruleset we're working with -InventoryManager.currentRuleset = { } - -function InventoryManager:ProcessSingleItem(dryrun, data) - local action = data.action - - if not dryrun then - -- Destroying is only done as an afterthought, junk at most for now. - if action == self.ACTION_DESTROY then - action = self.ACTION_JUNK - end +IM.currentRuleset = { } - if action == self.ACTION_JUNK then - SetItemIsJunk(data.bagId, data.slotId, true) - elseif action == self.ACTION_SELL then - SellInventoryItem(data.bagId, data.slotId, data.count ) - elseif action == self.ACTION_LAUNDER then - LaunderItem(data.bagId, data.slotId, data.count ) - elseif action == self.ACTION_GB_STASH then - TransferToGuildBank(data.bagId, data.slotId) - elseif action == self.ACTION_GB_RETRIEVE then - TransferFromGuildBank(data.slotId) - end - end - IM:ReportAction(data, dryrun, action, data.index, data.text) +function IM:ProcessSingleItem(dryrun, data) + if not dryrun then IM.actionfunctions[data.action](data) end + IM:ReportAction(data, dryrun, data.action, data.index, data.text) end -function InventoryManager:ReportAction(data, dryrun, action, rIndex, rString) +function IM:ReportAction(data, dryrun, action, rIndex, rString) + if not rIndex then return end + local index = (dryrun and 0) or 1 if self.FCOISL:IsProtectedAction(data.action, data.bagId, data.slotId) then index = 2 @@ -59,14 +41,14 @@ function InventoryManager:ReportAction(data, dryrun, action, rIndex, rString) rString or "")) end -function InventoryManager:SetCurrentInventory(bagType) +function IM:SetCurrentInventory(bagType) self.currentInventory = SHARED_INVENTORY:GetOrCreateBagCache(bagType) self.currentBagType = bagType end -function InventoryManager:SetShownInventory() +function IM:SetShownInventory() local bagType = nil if SCENE_MANAGER.currentScene == SCENE_MANAGER.scenes.inventory then @@ -86,7 +68,7 @@ function InventoryManager:SetShownInventory() return bagType end -function InventoryManager:GetItemData(slotId, _inv) +function IM:GetItemData(slotId, _inv) local data = {} local inv = nil @@ -137,30 +119,23 @@ function InventoryManager:GetItemData(slotId, _inv) return data end -function InventoryManager:listrules() - CHAT_SYSTEM:AddMessage(GetString(IM_LIST_NUM_RULES) .. #InventoryManager.currentRuleset.rules) - - for i = 1, #InventoryManager.currentRuleset.rules, 1 do - if not InventoryManager.currentRuleset.rules[i] then - break - end - CHAT_SYSTEM:AddMessage(GetString(IM_LIST_RULE) .. i .. ":" .. InventoryManager.currentRuleset.rules[i]:ToString()) - end +function IM:listrules() + IM.currentRuleset:List() end -function InventoryManager:dryrun() +function IM:dryrun() self:WorkBackpack(true) end -function InventoryManager:run() +function IM:run() self:WorkBackpack(false) end -function InventoryManager:OpenSettings() +function IM:OpenSettings() self.LAM:OpenToPanel(self.UI.panel) end -function InventoryManager:help() +function IM:help() -- self:SetCurrentInventory(BAG_BACKPACK) -- for i, entry in pairs(self.currentInventory) do -- local knownString = "" @@ -179,7 +154,7 @@ function InventoryManager:help() CHAT_SYSTEM:AddMessage("/im settings - Open up the settings menu") end -function InventoryManager:SlashCommand(argv) +function IM:SlashCommand(argv) local options = {} local searchResult = { string.match(argv,"^(%S*)%s*(.-)$") } for i,v in pairs(searchResult) do @@ -203,16 +178,16 @@ function InventoryManager:SlashCommand(argv) end end -InventoryManager.UI = { } -InventoryManager.UI.RuleEdit = { } -InventoryManager.UI.ProfileEdit = { } -InventoryManager.UI.Settings = { } +IM.UI = { } +IM.UI.RuleEdit = { } +IM.UI.ProfileEdit = { } +IM.UI.Settings = { } -local RuleEdit = InventoryManager.UI.RuleEdit -local ProfileEdit = InventoryManager.UI.ProfileEdit -local Settings = InventoryManager.UI.Settings +local RuleEdit = IM.UI.RuleEdit +local ProfileEdit = IM.UI.ProfileEdit +local Settings = IM.UI.Settings -function InventoryManager:InitializeUI() +function IM:InitializeUI() local panelData = { type = "panel", name = "InventoryManager", @@ -245,40 +220,28 @@ function InventoryManager:InitializeUI() self.LAM:RegisterOptionControls("iwontsayInventoryManager", mainPanel) end -local function ctorandload(ctor, ctorob, data) - local _new = ctor(ctorob) - for k,v in pairs(data) do - if v then _new[k] = v end - end - return _new -end - -local function loadRule(ruleData) - return ctorandload(InventoryManager.IM_Ruleset.NewRule, InventoryManager.IM_Ruleset, ruleData) -end - -local function loadRulelist(rulelistData) - local _new = { } - for k,v in pairs(rulelistData) do - _new[k] = loadRule(v) - end - return _new -end - local function loadProfile(profileData) local _new = { } for k,v in pairs(profileData) do - _new[k] = { } - _new[k]["name"] = v["name"] - _new[k]["rules"] = loadRulelist(v["rules"]) + _new[k] = IM.IM_RulesetV2.Clone(v) + _new[k].name = v.name + _new[k].settings = profileData.settings or { } + _new[k].settings.Version = 3 end return _new end -function InventoryManager:Update() +function IM:Update() local version = self.settings.Version or 1 + + if version < 3 then + self.currentRuleset = IM.IM_Ruleset:New() + self.currentRuleset.rules = self.charVariables.currentRules or { } + self.currentRuleset = self.currentRuleset:Clone() + end + if version < 2 then - local _rule = self.IM_Ruleset:NewRule() + local _rule = self.IM_Rule:New() _rule.action = self.ACTION_SELL _rule.junk = true local rs = self.currentRuleset.rules @@ -286,25 +249,29 @@ function InventoryManager:Update() CHAT_SYSTEM:AddMessage(GetString(IM_INIT_UPDATE_V2_NOTE)) end - self.settings.Version = 2 + if version < 3 then + self.currentRuleset = IM.IM_RulesetV2.Clone(self.currentRuleset) + CHAT_SYSTEM:AddMessage(GetString(IM_INIT_UPDATE_V3_NOTE)) + end + + self.settings.Version = 3 self:Save() end -function InventoryManager:Init() - self.currentRuleset = self.IM_Ruleset:New() - +function IM:Init() + self.charDefaults = { - ["currentRules"] = self.currentRuleset["rules"], - ["settings"] = { + ["settings"] = { ["destroyThreshold"] = 5, - ["bankMoveDelay"] = 20, - ["bankInitDelay"] = 1000, + ["bankMoveDelay"] = 20, + ["bankInitDelay"] = 1000, ["statusChangeDelay"] = 20, - ["maxGold"] = 5000, - ["minGold"] = 1000, - ["maxTV"] = 10, - ["minTV"] = 0, - ["autosell"] = true, + ["maxGold"] = 5000, + ["minGold"] = 1000, + ["maxTV"] = 10, + ["minTV"] = 0, + ["autosell"] = true, + ["Version"] = 3, } } @@ -324,12 +291,17 @@ function InventoryManager:Init() nil, self.charDefaults) - self.Profiles = loadProfile(self.accVariables.Profiles) - self.currentRuleset.rules = loadRulelist(self.charVariables.currentRules) - self.settings = self.charVariables.settings + self.Profiles = loadProfile(self.accVariables.Profiles) + self.presetProfiles = loadProfile(self.presetProfiles) + + if self.charVariables.currentRuleset then + self.currentRuleset = IM.IM_RulesetV2.Clone(self.charVariables.currentRuleset) + else + self.currentRuleset = IM.IM_RulesetV2:New() + end + + self.settings = self.charVariables.settings - self.presetProfiles = loadProfile(self.presetProfiles) - self.CSL.hasCSAddon() self.FCOISL:hasAddon() @@ -341,20 +313,20 @@ function InventoryManager:Init() end -function InventoryManager:Save() - self.charVariables.settings = self.settings - self.charVariables.currentRules = self.currentRuleset.rules - self.charVariables.Profiles = nil +function IM:Save() + self.charVariables.settings = self.settings + self.charVariables.currentRuleset = self.currentRuleset + self.charVariables.Profiles = nil - self.accVariables.Profiles = self.Profiles - self.accVariables.currentRules = nil + self.accVariables.Profiles = self.Profiles + self.accVariables.currentRules = nil end local function OnAddOnLoaded(eventCode, addonName) - if addonName == InventoryManager.name then - InventoryManager:Init() + if addonName == IM.name then + IM:Init() else - InventoryManager.loadedAddons[addonName] = true + IM.loadedAddons[addonName] = true end end @@ -364,8 +336,8 @@ local function OnPCCreated() Settings:PopulateUI() end -EVENT_MANAGER:RegisterForEvent(InventoryManager.name, EVENT_ADD_ON_LOADED, OnAddOnLoaded) +EVENT_MANAGER:RegisterForEvent(IM.name, EVENT_ADD_ON_LOADED, OnAddOnLoaded) -SLASH_COMMANDS["/im"] = function(argv) InventoryManager:SlashCommand(argv) end +SLASH_COMMANDS["/im"] = function(argv) IM:SlashCommand(argv) end CALLBACK_MANAGER:RegisterCallback("LAM-PanelControlsCreated", OnPCCreated) diff --git a/InventoryManager.txt b/InventoryManager.txt index 24e01fb..4663acc 100644 --- a/InventoryManager.txt +++ b/InventoryManager.txt @@ -2,7 +2,7 @@ ## APIVersion: 100019 ## OptionalDependsOn: LibAddonMenu-2.0 ## SavedVariables: IMSavedVars -## Version: 1.5.1 +## Version: 2.0.0 ## Author: iwontsay ## Description: iwontsay's Inventory Manager @@ -25,8 +25,8 @@ libs/LibAddonMenu-2.0/controls/slider.lua libs/LibAddonMenu-2.0/controls/texture.lua InventoryManager.lua -Modules/DelayedProcessor.lua Modules/Data.lua +Modules/DelayedProcessor.lua Modules/Banking.lua Modules/GuildBanking.lua Modules/Junker.lua @@ -38,6 +38,7 @@ FCOISLink.lua ItemSaverLink.lua Rulesets.lua +RulesetsV2.lua UI/RuleEdit.lua UI/ProfileEdit.lua UI/Settings.lua diff --git a/ItemSaverLink.lua b/ItemSaverLink.lua index 1c1541c..d0defc8 100644 --- a/ItemSaverLink.lua +++ b/ItemSaverLink.lua @@ -6,6 +6,9 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end +local IM = InventoryManager + local TXT_NO_CARE local TXT_NO_MARK local TXT_ANY_MARK @@ -15,7 +18,6 @@ local I_NO_MARK = -2 local I_ANY_MARK = -1 local ISL = { } -local IM = InventoryManager IM.ISL = ISL; diff --git a/Modules/Banking.lua b/Modules/Banking.lua index f0c5910..8b00dbd 100644 --- a/Modules/Banking.lua +++ b/Modules/Banking.lua @@ -6,10 +6,12 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager local RevCaches = nil local Empties = nil +local Moves = nil local function CreateReverseCache(bagType) local _revCache = { } @@ -97,7 +99,7 @@ end -- 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 curStack, _ = GetSlotStackSize(srcBagType, srcSlotId) local id = GetItemInstanceId(srcBagType, srcSlotId) local tgtSlotId = nil @@ -136,7 +138,7 @@ local function FindTargetSlot(srcBagType, srcSlotId, tgtBagType) if #empties == 0 then return false, -1, 0, tgtBagType end -- It's a complete move, remove the empty slot from the target list - local tgtSlotId = empties[#empties] + tgtSlotId = empties[#empties] empties[#empties] = nil UpdateCaches(srcBagType, srcSlotId, tgtBagType, tgtSlotId, curStack) @@ -199,11 +201,11 @@ local function CalculateMoves() InventoryManager.currentRuleset:ResetCounters() - Moves = { - [BAG_BACKPACK] = CollectSingleDirection(IM.ACTION_STASH, BAG_BACKPACK), - [BAG_BANK] = CollectSingleDirection(IM.ACTION_RETRIEVE, BAG_BANK), + Moves = { + [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. @@ -244,7 +246,7 @@ end InventoryManager.moveStatus = nil -function ProcessMove(move) +local function ProcessMove(move) local bagIdFrom = move["srcbag"] local slotIdFrom = move["srcslot"] local bagIdTo = move["tgtbag"] @@ -254,7 +256,7 @@ function ProcessMove(move) InventoryManager.currentBagType = bagIdFrom local data = InventoryManager:GetItemData(slotIdFrom, SHARED_INVENTORY:GetOrCreateBagCache(bagIdFrom)) - InventoryManager:ReportAction(data, false, action) + InventoryManager:ReportAction(data, false, action, "", "") if IsProtectedFunction("RequestMoveItem") then CallSecureProtected("RequestMoveItem", bagIdFrom, slotIdFrom, bagIdTo, slotIdTo, qtyToMove) diff --git a/Modules/Data.lua b/Modules/Data.lua index 9504710..687b171 100644 --- a/Modules/Data.lua +++ b/Modules/Data.lua @@ -1,7 +1,10 @@ +if not InventoryManager then InventoryManager = {} end +local IM = InventoryManager + local function generateFiltertypes() local _new = { } - for _, f in pairs(InventoryManager.filterorder) do + for _, f in pairs(IM.filterorder) do local _innernew = { } for _, ff in pairs(f[2]) do _innernew[ff[1]] = ff[2] @@ -11,26 +14,26 @@ local function generateFiltertypes() return _new end -InventoryManager.IM_Ruleset = { } +if not IM.IM_Ruleset then IM.IM_Ruleset = ZO_Object:Subclass() end -local IM_Ruleset = InventoryManager.IM_Ruleset +local IM_Ruleset = IM.IM_Ruleset -function InventoryManager:getIQString(itemQuality) +function IM:getIQString(itemQuality) return GetItemQualityColor(itemQuality):Colorize(GetString("SI_ITEMQUALITY", itemQuality)) end -InventoryManager.ACTION_KEEP = 0 -InventoryManager.ACTION_JUNK = 1 -InventoryManager.ACTION_DESTROY = 2 -InventoryManager.ACTION_SELL = 3 -InventoryManager.ACTION_LAUNDER = 4 -InventoryManager.ACTION_DECONSTRUCT = 5 -InventoryManager.ACTION_LOCK = 6 -InventoryManager.ACTION_UNLOCK = 7 -InventoryManager.ACTION_STASH = 10 -InventoryManager.ACTION_GB_STASH = 11 -InventoryManager.ACTION_RETRIEVE = 20 -InventoryManager.ACTION_GB_RETRIEVE = 21 +IM.ACTION_KEEP = 0 +IM.ACTION_JUNK = 1 +IM.ACTION_DESTROY = 2 +IM.ACTION_SELL = 3 +IM.ACTION_LAUNDER = 4 +IM.ACTION_DECONSTRUCT = 5 +IM.ACTION_LOCK = 6 +IM.ACTION_UNLOCK = 7 +IM.ACTION_STASH = 10 +IM.ACTION_GB_STASH = 11 +IM.ACTION_RETRIEVE = 20 +IM.ACTION_GB_RETRIEVE = 21 IM_Ruleset.ITEM_TRAIT_TYPE_ANY = -1 IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKOTHERS = -2 @@ -38,7 +41,7 @@ IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN = -3 IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT = -4 -InventoryManager.filterorder = { +IM.filterorder = { { "IM_FILTER_ANY" , { { "IM_FILTERSPEC_ANY" , { } }, } }, @@ -102,31 +105,58 @@ InventoryManager.filterorder = { } }, } -InventoryManager.filtertypes = generateFiltertypes() +IM.filtertypes = generateFiltertypes() + +IM.qualityorder = { + { IM:getIQString(ITEM_QUALITY_TRASH), ITEM_QUALITY_TRASH }, + { IM:getIQString(ITEM_QUALITY_NORMAL), ITEM_QUALITY_NORMAL }, + { IM:getIQString(ITEM_QUALITY_MAGIC), ITEM_QUALITY_MAGIC }, + { IM:getIQString(ITEM_QUALITY_ARCANE), ITEM_QUALITY_ARCANE }, + { IM:getIQString(ITEM_QUALITY_ARTIFACT), ITEM_QUALITY_ARTIFACT }, + { IM:getIQString(ITEM_QUALITY_LEGENDARY), ITEM_QUALITY_LEGENDARY } +} -InventoryManager.qualityorder = { - { InventoryManager:getIQString(ITEM_QUALITY_TRASH), ITEM_QUALITY_TRASH }, - { InventoryManager:getIQString(ITEM_QUALITY_NORMAL), ITEM_QUALITY_NORMAL }, - { InventoryManager:getIQString(ITEM_QUALITY_MAGIC), ITEM_QUALITY_MAGIC }, - { InventoryManager:getIQString(ITEM_QUALITY_ARCANE), ITEM_QUALITY_ARCANE }, - { InventoryManager:getIQString(ITEM_QUALITY_ARTIFACT), ITEM_QUALITY_ARTIFACT }, - { InventoryManager:getIQString(ITEM_QUALITY_LEGENDARY), ITEM_QUALITY_LEGENDARY } +IM.actionorder = { + { IM.ACTION_JUNK }, + { IM.ACTION_DESTROY }, + { IM.ACTION_STASH }, + { IM.ACTION_RETRIEVE }, + { IM.ACTION_GB_STASH }, + { IM.ACTION_GB_RETRIEVE }, + { IM.ACTION_SELL }, + { IM.ACTION_LAUNDER }, + { IM.ACTION_DECONSTRUCT }, } -InventoryManager.actionorder = { - { InventoryManager.ACTION_KEEP }, - { InventoryManager.ACTION_JUNK }, - { InventoryManager.ACTION_DESTROY }, - { InventoryManager.ACTION_STASH }, - { InventoryManager.ACTION_RETRIEVE }, - { InventoryManager.ACTION_GB_STASH }, - { InventoryManager.ACTION_GB_RETRIEVE }, - { InventoryManager.ACTION_SELL }, - { InventoryManager.ACTION_LAUNDER }, - { InventoryManager.ACTION_DECONSTRUCT }, +IM.xreforder = { + { IM.ACTION_KEEP }, + { IM.ACTION_JUNK }, + { IM.ACTION_DESTROY }, + { IM.ACTION_STASH }, + { IM.ACTION_RETRIEVE }, + { IM.ACTION_GB_STASH }, + { IM.ACTION_GB_RETRIEVE }, + { IM.ACTION_SELL }, + { IM.ACTION_LAUNDER }, + { IM.ACTION_DECONSTRUCT }, +} + +IM.actionfunctions = { + [IM.ACTION_KEEP] = function(data) end, -- Do nothing + [IM.ACTION_JUNK] = function(data) SetItemIsJunk(data.bagId, data.slotId, true) end, + [IM.ACTION_DESTROY] = function(data) DestroyItem(data.bagId, data.slotId) end, + [IM.ACTION_SELL] = function(data) SellInventoryItem(data.bagId, data.slotId, data.count) end, + [IM.ACTION_LAUNDER] = function(data) LaunderItem(data.bagId, data.slotId, data.count) end, + [IM.ACTION_GB_STASH] = function(data) TransferToGuildBank(data.bagId, data.slotId) end, + [IM.ACTION_GB_RETRIEVE] = function(data) TransferFromGuildBank(data.slotId) end, + [IM.ACTION_DECONSTRUCT] = function(data) end, -- Added in Extractor.lua + [IM.ACTION_STASH] = function(data) end, -- Bank moves are handled differently + [IM.ACTION_RETRIEVE] = function(data) end, + [IM.ACTION_LOCK] = nil, -- RFU + [IM.ACTION_UNLOCK] = nil, } -InventoryManager.traitsorder = { +IM.traitsorder = { ["IM_FILTER_ANY"] = { 0, -- Redefined to "don't care about traits" IM_Ruleset.ITEM_TRAIT_TYPE_NOTRAIT, @@ -195,7 +225,7 @@ InventoryManager.traitsorder = { }, } -InventoryManager.presetProfiles = { +IM.presetProfiles = { [1] = { ["rules"] = @@ -206,11 +236,8 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 10, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = -2, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [2] = { @@ -218,11 +245,8 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 10, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = 9, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [3] = { @@ -230,11 +254,8 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 1, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = 10, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [4] = { @@ -242,19 +263,13 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 20, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = -3, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [5] = { ["minQuality"] = 0, - ["Filter"] = nil, -- invalid value type [function] used ["action"] = 1, - ["New"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used ["maxQuality"] = 5, ["filterSubType"] = "IM_FILTERSPEC_TRASH", ["filterType"] = "IM_FILTER_MISC", @@ -272,11 +287,8 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 20, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = -3, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [2] = { @@ -284,11 +296,8 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 10, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = -2, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [3] = { @@ -296,11 +305,8 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 20, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = 9, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [4] = { @@ -308,19 +314,13 @@ InventoryManager.presetProfiles = { ["filterType"] = "IM_FILTER_ANY", ["filterSubType"] = "IM_FILTERSPEC_ANY", ["action"] = 1, - ["New"] = nil, -- invalid value type [function] used ["traitType"] = 10, ["maxQuality"] = 5, - ["Filter"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used }, [5] = { ["minQuality"] = 0, - ["Filter"] = nil, -- invalid value type [function] used ["action"] = 1, - ["New"] = nil, -- invalid value type [function] used - ["ToString"] = nil, -- invalid value type [function] used ["maxQuality"] = 5, ["filterSubType"] = "IM_FILTERSPEC_TRASH", ["filterType"] = "IM_FILTER_MISC", diff --git a/Modules/DelayedProcessor.lua b/Modules/DelayedProcessor.lua index 964b007..7dfae20 100644 --- a/Modules/DelayedProcessor.lua +++ b/Modules/DelayedProcessor.lua @@ -2,6 +2,7 @@ local DEBUG = -- function() end d +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager local _Pending = nil diff --git a/Modules/Extractor.lua b/Modules/Extractor.lua index 03f2554..1dd5752 100644 --- a/Modules/Extractor.lua +++ b/Modules/Extractor.lua @@ -6,6 +6,7 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager local _waitforpanel = nil @@ -80,17 +81,18 @@ local function filter_for_deconstruction(tradeskill, data) return true end -local function extract_single_item(tradeskill, data) - if tradeskill == CRAFTING_TYPE_ENCHANTING then +local used_tradeskill = nil +IM.actionfunctions[IM.ACTION_DECONSTRUCT] = function(data) + if used_tradeskill == CRAFTING_TYPE_ENCHANTING then ExtractEnchantingItem(data.bagId, data.slotId) else ExtractOrRefineSmithingItem(data.bagId, data.slotId) end - IM:ReportAction(data, false, data.action, data.index, data.text) end local function InitDeconstruction(tradeskill) - InventoryManager.currentRuleset:ResetCounters() + used_tradeskill = tradeskill + IM.currentRuleset:ResetCounters() local list = IM:CreateInventoryList(BAG_BACKPACK, IM.ACTION_DECONSTRUCT, function(data) return filter_for_deconstruction(tradeskill, data) end) @@ -104,11 +106,11 @@ local function InitDeconstruction(tradeskill) list) IM:DoEventProcessing(list, - function(data) return extract_single_item(tradeskill, data) end, + function(data) IM:ProcessSingleItem(false, data) end, function() end, EVENT_CRAFT_COMPLETED, EVENT_END_CRAFTING_STATION_INTERACT, - InventoryManager.settings.bankMoveDelay) + IM.settings.bankMoveDelay) end local function WaitPanel() diff --git a/Modules/GuildBanking.lua b/Modules/GuildBanking.lua index 6556b84..b6c910b 100644 --- a/Modules/GuildBanking.lua +++ b/Modules/GuildBanking.lua @@ -6,6 +6,7 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager local current_gn = nil diff --git a/Modules/Junker.lua b/Modules/Junker.lua index 3ed5f32..c9f7818 100644 --- a/Modules/Junker.lua +++ b/Modules/Junker.lua @@ -2,50 +2,31 @@ local DEBUG = -- function() end d - +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager -function IM:CheckAndDestroy() +function IM:CheckAndDestroy(dryrun) if GetNumBagFreeSlots(BAG_BACKPACK) >= IM.settings.destroyThreshold then return end - InventoryManager.currentRuleset:ResetCounters() - - self:SetCurrentInventory(BAG_BACKPACK) - for i,_ in pairs(self.currentInventory) do - local data = self:GetItemData(i) - local action, index, text = IM.currentRuleset:Match(data) - if action == self.ACTION_DESTROY and not - self.FCOISL:IsProtectedAction(action, BAG_BACKPACK, i) then - self:ReportAction(data, false, action, index, text) - DestroyItem(BAG_BACKPACK, i) - end - end -end - -local function filter_for_backpack_action(dryrun, data) - if data.action == IM.ACTION_JUNK then - return not data.junk - end - if data.action == IM.ACTION_DESTROY then - return true - end - - -- List other inventory actions only if it's a dryrun. - -- Else we need to get to the specific stations to actually perform them - if data.action ~= IM.ACTION_KEEP and data.action ~= IM.ACTION_RETRIEVE and data.action ~= IM.ACTION_GB_RETRIEVE and dryrun then - return true - end - return false + IM.currentRuleset:ResetCounters() + IM:ProcessBag(BAG_BACKPACK, IM.ACTION_DESTROY, + function(data) return data.junk and not IM.FCOISL:IsProtectedAction(data.action, data.bagId, data.slotId) end, + function(data) IM:ProcessSingleItem(dryrun, data) end, + function() end, + IM.settings.statusChangeDelay) end function IM:WorkBackpack(dryrun) - InventoryManager.currentRuleset:ResetCounters() - self:ProcessBag(BAG_BACKPACK, nil, - function(data) return filter_for_backpack_action(dryrun, data) end, + local action = IM.ACTION_JUNK + if dryrun then action = nil end + + IM.currentRuleset:ResetCounters() + IM:ProcessBag(BAG_BACKPACK, action, + function(data) return dryrun or not data.junk end, function(data) IM:ProcessSingleItem(dryrun, data) end, - function() IM:CheckAndDestroy() end, + function() IM:CheckAndDestroy(dryrun) end, IM.settings.statusChangeDelay) end @@ -56,19 +37,17 @@ function IM:UnJunk() end function IM:OnInvSlotUpdate(bagId, slotId) - self:SetCurrentInventory(bagId) - local data = self:GetItemData(slotId) + IM:SetCurrentInventory(bagId) + local data = IM:GetItemData(slotId) if not data then return end if not self.currentRuleset or not self.currentRuleset.Match then return end - data.action, data.index, data.text = self.currentRuleset:Match(data) - if filter_for_backpack_action(false, data) then - IM:ProcessSingleItem(false, data) - end + data.action, data.index, data.text = self.currentRuleset:Match(data, IM.ACTION_JUNK) + IM:ProcessSingleItem(false, data) - self:CheckAndDestroy() + IM:CheckAndDestroy() end local function OnInvSlotUpdate(eventCode, bagId, slotId, isNewItem, itemSoundCategory, inventoryUpdateReason, stackCountChange) diff --git a/Modules/Seller.lua b/Modules/Seller.lua index 6f50554..2d6eeea 100644 --- a/Modules/Seller.lua +++ b/Modules/Seller.lua @@ -6,20 +6,23 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end +local IM = InventoryManager + local _Gain = nil local function do_sell(data, eventCode, itemName, itemQuantity, money) if eventCode ~= nil then _Gain = _Gain + money end - InventoryManager:ProcessSingleItem(false, data) + IM:ProcessSingleItem(false, data) end local function filter_for_sale(fence, data) if data.stolen ~= fence then return false end - if InventoryManager.FCOISL:IsProtectedAction( - InventoryManager.ACTION_SELL, + if IM.FCOISL:IsProtectedAction( + IM.ACTION_SELL, data.bagId, data.slotId, fence) then return false end @@ -27,14 +30,14 @@ local function filter_for_sale(fence, data) end local function filter_for_launder(data) - if InventoryManager.FCOISL:IsProtectedAction( - InventoryManager.ACTION_LAUNDER, + if IM.FCOISL:IsProtectedAction( + IM.ACTION_LAUNDER, data.bagId, data.slotId) then return false end return true end -function InventoryManager:SellItems(stolen) +function IM:SellItems(stolen) local list = { } local end_fn = function(abort, eventCode, itemName, itemQuantity, money) if eventCode ~= nil then @@ -47,39 +50,39 @@ function InventoryManager:SellItems(stolen) if eventCode ~= nil then _Gain = _Gain + money end - InventoryManager.currentRuleset:ResetCounters() - InventoryManager:EventProcessBag(BAG_BACKPACK, InventoryManager.ACTION_LAUNDER, + IM.currentRuleset:ResetCounters() + IM:EventProcessBag(BAG_BACKPACK, IM.ACTION_LAUNDER, filter_for_launder, - function(data) InventoryManager:ProcessSingleItem(false, data) end, + function(data) IM:ProcessSingleItem(false, data) end, function(abort) end_fn(abort) end, EVENT_ITEM_LAUNDER_RESULT, EVENT_CLOSE_STORE, - InventoryManager.settings.bankMoveDelay) + IM.settings.bankMoveDelay) end _Gain = 0 - InventoryManager.currentRuleset:ResetCounters() - self:EventProcessBag(BAG_BACKPACK, InventoryManager.ACTION_SELL, + IM.currentRuleset:ResetCounters() + self:EventProcessBag(BAG_BACKPACK, IM.ACTION_SELL, function(data) return filter_for_sale(stolen, data) end, do_sell, ((stolen and launder_run) or end_fn), EVENT_SELL_RECEIPT, EVENT_CLOSE_STORE, - InventoryManager.settings.bankMoveDelay) + IM.settings.bankMoveDelay) end local function OnOpenStore(eventCode) - if InventoryManager.settings.autosell then - InventoryManager:SellItems(false) + if IM.settings.autosell then + IM:SellItems(false) end end local function OnOpenFence(eventCode) - if InventoryManager.settings.autosell then - InventoryManager:SellItems(true) + if IM.settings.autosell then + IM:SellItems(true) end end -EVENT_MANAGER:RegisterForEvent(InventoryManager.name, EVENT_OPEN_STORE, OnOpenStore) -EVENT_MANAGER:RegisterForEvent(InventoryManager.name, EVENT_OPEN_FENCE, OnOpenFence) +EVENT_MANAGER:RegisterForEvent(IM.name, EVENT_OPEN_STORE, OnOpenStore) +EVENT_MANAGER:RegisterForEvent(IM.name, EVENT_OPEN_FENCE, OnOpenFence) diff --git a/Rulesets.lua b/Rulesets.lua index e8b4e41..431a822 100644 --- a/Rulesets.lua +++ b/Rulesets.lua @@ -7,30 +7,38 @@ local function _tr(str) end -local IM_Rule = {} -local IM_Ruleset = InventoryManager.IM_Ruleset +if not InventoryManager then InventoryManager = {} end +local IM = InventoryManager -IM_Rule.action = InventoryManager.ACTION_KEEP -IM_Rule.minQuality = ITEM_QUALITY_TRASH -IM_Rule.maxQuality = ITEM_QUALITY_LEGENDARY +if not IM.IM_Rule then IM.IM_Rule = ZO_Object:Subclass() end +local IMR = IM.IM_Rule -IM_Rule.filterType = "IM_FILTER_ANY" -IM_Rule.filterSubType = "IM_FILTERSPEC_ANY" +if not IM.IM_Ruleset then IM.IM_Ruleset = ZO_Object:Subclass() end +local IMRS = IM.IM_Ruleset -function IM_Rule:New() - local _new = { } - - for k,v in pairs(self) do - _new[k] = v - end +IMR.text = "" + +function IMR:New() + local rule = ZO_Object.New(self) + rule.action = IM.ACTION_KEEP + rule.minQuality = ITEM_QUALITY_TRASH + rule.maxQuality = ITEM_QUALITY_LEGENDARY + + rule.filterType = "IM_FILTER_ANY" + rule.filterSubType = "IM_FILTERSPEC_ANY" + + return rule +end - return _new +function IMR:Clone() + local rule = IMR:New() + for k,v in pairs(self) do + rule[k] = v + end + return rule end -function IM_Rule:ToString() - local stolenText = "" - local traitText = "" - local worthlessText = "" +function IMR:ToString() local qualityRangeText = "" local isSetText = "" local actionText = GetString("IM_ACTIONTXT", self.action) @@ -47,8 +55,8 @@ 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) + if self.traitType == IMRS.ITEM_TRAIT_TYPE_NOTRAIT then which = 2 end + local str = (self.traitType == IMRS.ITEM_TRAIT_TYPE_ANY and "") or GetString("IM_META_TRAIT_TYPE", -self.traitType) itemDescription = zo_strformat( GetString("IM_META_TRAIT_TYPE_FORMAT", which), itemDescription, @@ -70,15 +78,15 @@ function IM_Rule:ToString() itemDescription = GetString(IM_RULETXT_JUNKED) .. " " .. itemDescription end - if (InventoryManager.FCOISL:hasAddon() or InventoryManager.ISL:hasAddon()) and self.FCOISMark then - if InventoryManager.FCOISL:IsNoMark(self.FCOISMark) then + if (IM.FCOISL:hasAddon() or IM.ISL:hasAddon()) and self.FCOISMark then + if IM.FCOISL:IsNoMark(self.FCOISMark) then itemDescription = GetString(IM_FCOIS_UNMARKED) .. " " .. itemDescription - elseif InventoryManager.FCOISL:IsAnyMark(self.FCOISMark) then + elseif IM.FCOISL:IsAnyMark(self.FCOISMark) then itemDescription = itemDescription .. " " .. GetString(IM_FCOIS_WITHANYMARK) else itemDescription = itemDescription .. " " .. zo_strformat( GetString(IM_FCOIS_MARKEDASX), - InventoryManager.FCOISL:GetIndexedMark(self.FCOISMark)) + IM.FCOISL:GetIndexedMark(self.FCOISMark)) end end @@ -90,16 +98,18 @@ function IM_Rule:ToString() isSetText = " " .. GetString(IM_RULETXT_ISSET) end - colorMin = GetItemQualityColor(self.minQuality) - colorMax = GetItemQualityColor(self.maxQuality) - + itemDescription = zo_strlower(itemDescription) + if self.text ~= "" then + itemDescription = itemDescription .. " " .. zo_strformat(GetString(IM_RULETXT_TXT), self.text) + end + if self.minQuality == self.maxQuality then qualityRangeText = " " .. zo_strformat(GetString("IM_RULETXT_QUALITY", 1), - InventoryManager:getIQString(self.minQuality)) + IM:getIQString(self.minQuality)) elseif self.minQuality ~= ITEM_QUALITY_TRASH or self.maxQuality ~= ITEM_QUALITY_LEGENDARY then qualityRangeText = " " .. zo_strformat(GetString("IM_RULETXT_QUALITY", 2), - InventoryManager:getIQString(self.minQuality), - InventoryManager:getIQString(self.maxQuality)) + IM:getIQString(self.minQuality), + IM:getIQString(self.maxQuality)) end return zo_strformat(GetString(IM_RULETXTFORMAT), @@ -109,9 +119,9 @@ function IM_Rule:ToString() actionText) end -function IM_Rule:Filter(data) +function IMR:Filter(data) - local filterList = InventoryManager.filtertypes[self.filterType][self.filterSubType] + local filterList = IM.filtertypes[self.filterType][self.filterSubType] if #filterList > 0 then local attrName = filterList[1] @@ -148,13 +158,13 @@ function IM_Rule:Filter(data) -- Ornate, Intricate, ect. if self.traitType then - if self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_ANY then + if self.traitType == IMRS.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 + elseif self.traitType == IMRS.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 + elseif self.traitType == IMRS.ITEM_TRAIT_TYPE_ANYUNKOTHERS then if not data.unknownothers then return false end - elseif self.traitType == IM_Ruleset.ITEM_TRAIT_TYPE_ANYUNKNOWN then + elseif self.traitType == IMRS.ITEM_TRAIT_TYPE_ANYUNKNOWN then if not data.unknownself then return false end elseif self.traitType ~= traitType then return false @@ -163,8 +173,8 @@ function IM_Rule:Filter(data) -- FCO ItemSaver marker? -- Call with parameters suitable for both API's and let FCOISL sort it out. - if (not InventoryManager.FCOISL:FitMark(data.itemInstanceId, self.FCOISMark, data.bagId, data.slotId)) or - (not InventoryManager.ISL:FitMark(data.itemInstanceId, self.FCOISMark, data.bagId, data.slotId)) then return false end + if (not IM.FCOISL:FitMark(data.itemInstanceId, self.FCOISMark, data.bagId, data.slotId)) or + (not IM.ISL:FitMark(data.itemInstanceId, self.FCOISMark, data.bagId, data.slotId)) then return false end -- Junked? if self.junk and not data.junk then return false end @@ -184,33 +194,39 @@ function IM_Rule:Filter(data) -- outside wanted quality range? if data.quality < self.minQuality or data.quality > self.maxQuality then return false end + -- text matching + if self.text ~= "" and not string.match(data.name, self.text) then return false end + return true end -function IM_Ruleset:New() - local _new = { } - - for k,v in pairs(self) do - _new[k] = v - end +IMRS.version = 1 - _new["rules"] = { } - if self.rules then - for k,v in pairs(self.rules) do - _new["rules"][k] = v:New() - end - end - - return _new +function IMRS:New() + local ruleset = ZO_Object.New(self) + ruleset.rules = { } + return ruleset +end + +function IMRS:Clone() + local ruleset = IMRS:New() + for k,v in pairs(self) do + ruleset[k] = v + end + ruleset["rules"] = { } + for k,v in pairs(self["rules"]) do + ruleset["rules"][k] = IMR.Clone(v) + end + return ruleset end local ExecCounters = nil -function IM_Ruleset:ResetCounters() +function IMRS:ResetCounters() ExecCounters = nil end -function IM_Ruleset:Match(data, action) +function IMRS:Match(data, action) if not ExecCounters then ExecCounters = { } end for k, v in pairs(self.rules) do @@ -221,12 +237,12 @@ function IM_Ruleset:Match(data, action) -- If it's stolen, we can't put it in the bank. if res then if data.locked then res = false - elseif data.stolen and v.action == InventoryManager.ACTION_STASH then res = false + elseif data.stolen and v.action == IM.ACTION_STASH then res = false end end -- If we want a specific action, skip if it's not the one. - if action and (action ~= v.action and v.action ~= InventoryManager.ACTION_KEEP) then res = false end + if action and (action ~= v.action and v.action ~= IM.ACTION_KEEP) then res = false end -- If we reached the max execution count for that particular rule, skip it. if res and v.maxCount and ExecCounters[k] and ExecCounters[k] >= v.maxCount then @@ -241,36 +257,20 @@ function IM_Ruleset:Match(data, action) end end - return InventoryManager.ACTION_KEEP, nil, nil + return IM.ACTION_KEEP, nil, nil end -function IM_Ruleset:NewRule() - return IM_Rule:New() +function IMRS:List() + CHAT_SYSTEM:AddMessage(GetString(IM_LIST_NUM_RULES) .. #self.rules) + + for i = 1, #self.rules, 1 do + if not self.rules[i] then + break + end + CHAT_SYSTEM:AddMessage(GetString(IM_LIST_RULE) .. i .. ":" .. self.rules[i]:ToString()) + end end -InventoryManager.IM_Ruleset = IM_Ruleset - --- DEBUG CODE --- Ruleset = IM_Ruleset:New() - --- local Rule1 = IM_Ruleset:NewRule() --- Rule1.filterType = "IM_FILTER_MISC" --- Rule1.filterSubType = "IM_FILTERSPEC_TRASH" --- Rule1.action = InventoryManager.ACTION_JUNK - --- local Rule2 = IM_Ruleset:NewRule() --- Rule2.filterType = "IM_FILTER_WEAPON" --- Rule2.filterSubType = "IM_FILTERSPEC_2H" --- Rule2.minQuality = ITEM_QUALITY_MAGIC --- Rule2.action = InventoryManager.ACTION_RETRIEVE - --- local Rule3 = IM_Ruleset:NewRule() --- Rule3.filterType = "IM_FILTER_APPAREL" --- Rule3.filterSubType = "IM_FILTERSPEC_MEDIUM" --- Rule3.stolen = true --- Rule3.action = InventoryManager.ACTION_DESTROY - --- Ruleset.rules = { Rule1, Rule2, Rule3 } --- -- Ruleset.rules = { } - --- InventoryManager.currentRuleset = Ruleset +function IMRS:GetRuleList(action) + return self.rules +end diff --git a/RulesetsV2.lua b/RulesetsV2.lua new file mode 100644 index 0000000..33abe0e --- /dev/null +++ b/RulesetsV2.lua @@ -0,0 +1,275 @@ +local DEBUG = +function() end +-- d + +local function _tr(str) + return str +end + + +if not InventoryManager then InventoryManager = {} end +local IM = InventoryManager + +local VisitedLists = { } + +IM.IM_RuleV2 = IM.IM_Rule:Subclass() +local IMR2 = IM.IM_RuleV2 + +IM.IM_RulesetV2 = IM.IM_Ruleset:Subclass() +local IMRS2 = IM.IM_RulesetV2 + +IMR2.version = 2 + +function IMR2:New() + local rule = IM.IM_Rule.New(self) + rule.action = nil + return rule +end + +function IMR2:Clone() + local rule = IMR2:New() + for k,v in pairs(self) do + rule[k] = v + end + + local action = rule.action + rule.action = nil + + return rule, action +end + +function IMR2:ToString() + local qualityRangeText = "" + local isSetText = "" + local formatindex = 1 + + local exeCountText = "" + if self.maxCount then + exeCountText = " " .. zo_strformat(GetString(IM_RULETXT_EXECOUNT), self.maxCount) + end + + if self.negate then formatindex = 0 end + + if self.xref and self.xref ~= IM.ACTION_KEEP then + formatindex = formatindex + 2 + local tgtlist = GetString("IM_R2_HEADING", self.xref) + return zo_strformat(GetString("IM_R2_FORMAT", formatindex), tgtlist, exeCountText) + end + + local itemDescription = zo_strformat( + GetString(self.filterSubType), + " " .. GetString(self.filterType)) + + + + if self.traitType then + local which = (self.filterType == "IM_FILTER_CONSUMABLE" and 1) or 0 + if self.traitType < 0 then + if self.traitType == IMRS2.ITEM_TRAIT_TYPE_NOTRAIT then which = 2 end + local str = (self.traitType == IMRS2.ITEM_TRAIT_TYPE_ANY and "") or GetString("IM_META_TRAIT_TYPE", -self.traitType) + itemDescription = zo_strformat( + GetString("IM_META_TRAIT_TYPE_FORMAT", which), + itemDescription, + str) + else + itemDescription = GetString("SI_ITEMTRAITTYPE", self.traitType) .. " " .. itemDescription + end + end + + if self.crafted then + itemDescription = GetString(IM_RULETXT_CRAFTED) .. " " .. itemDescription + end + + if self.worthless then + itemDescription = GetString(IM_RULETXT_WORTHLESS) .. " " .. itemDescription + end + + if self.junk then + itemDescription = GetString(IM_RULETXT_JUNKED) .. " " .. itemDescription + end + + if (IM.FCOISL:hasAddon() or IM.ISL:hasAddon()) and self.FCOISMark then + if IM.FCOISL:IsNoMark(self.FCOISMark) then + itemDescription = GetString(IM_FCOIS_UNMARKED) .. " " .. itemDescription + elseif IM.FCOISL:IsAnyMark(self.FCOISMark) then + itemDescription = itemDescription .. " " .. GetString(IM_FCOIS_WITHANYMARK) + else + itemDescription = itemDescription .. " " .. zo_strformat( + GetString(IM_FCOIS_MARKEDASX), + IM.FCOISL:GetIndexedMark(self.FCOISMark)) + end + end + + if self.stolen then + itemDescription = GetString(IM_RULETXT_STOLEN) .. " " .. itemDescription + end + + if self.isSet then + isSetText = " " .. GetString(IM_RULETXT_ISSET) + end + + itemDescription = zo_strlower(itemDescription) + if self.text ~= "" then + itemDescription = itemDescription .. " " .. zo_strformat(GetString(IM_RULETXT_TXT), self.text) + end + + if self.minQuality == self.maxQuality then + qualityRangeText = " " .. zo_strformat(GetString("IM_RULETXT_QUALITY", 1), + IM:getIQString(self.minQuality)) + elseif self.minQuality ~= ITEM_QUALITY_TRASH or self.maxQuality ~= ITEM_QUALITY_LEGENDARY then + qualityRangeText = " " .. zo_strformat(GetString("IM_RULETXT_QUALITY", 2), + IM:getIQString(self.minQuality), + IM:getIQString(self.maxQuality)) + end + + return zo_strformat(GetString("IM_R2_FORMAT", formatindex), + itemDescription, + qualityRangeText, + isSetText, + exeCountText) +end + +function IMR2:Filter(data) + if self.xref and self.xref ~= IM.ACTION_KEEP then + + -- Avoid cycles - break if we were already here. + if VisitedLists[self.xref] then return false end + + VisitedLists[self.xref] = true + local action, index, text = IM.currentRuleset:Match(data, self.xref) + VisitedLists[self.xref] = nil + + -- If we found a positive match on the referenced list, this cross reference matches + if action ~= IM.ACTION_KEEP then return true end + end + + return IM.IM_Rule.Filter(self, data) +end + +IMRS2.version = 2 + +function IMRS2:New() + local ruleset = IM.IM_Ruleset.New(self) + ruleset.rules = nil + ruleset.rulelists = { } + + for k,_ in pairs(IM.actionfunctions) do + ruleset.rulelists[k] = { } + end + ruleset.rulelists[IM.ACTION_KEEP] = nil + + return ruleset +end + +function IMRS2:Clone() + if not self.rulelists then return IMRS2.Upgrade(self) end + + local ruleset = IMRS2:New() + for k,v in pairs(self) do + ruleset[k] = v + end + + ruleset.rulelists = { } + for k,v in pairs(self.rulelists) do + ruleset.rulelists[k] = { } + for k2,v2 in pairs(v) do + ruleset.rulelists[k][k2] = IMR2.Clone(v2) + end + end + + return ruleset +end + +function IMRS2:Upgrade() + local ruleset = IMRS2:New() + for _,v in pairs(self.rules) do + local rule, action = IMR2.Clone(v) + if action == IM.ACTION_KEEP then + rule.negate = true + for _, list in pairs(ruleset.rulelists) do + list[#list + 1] = rule:Clone() + end + else + local list = ruleset.rulelists[action] + list[#list + 1] = rule + end + end + return ruleset +end + +local ExecCounters = { } + +function IMRS2:ResetCounters() + ExecCounters = { } + VisitedLists = { } +end + +function IMRS2:Match(data, action) + + -- Locked: Do nothing in any case + if data.locked then + return IM.ACTION_KEEP, nil, nil + end + + -- If action is not given, try any action that matches + if not action then + local raction = IM.ACTION_KEEP + local rindex, rtext + for k, _ in pairs(self.rulelists) do + local action, index, text = self:Match(data, k) + + -- If we find an explicit 'do nothing' here, try to find a better match. + -- Maybe it's because of a negative cross reference. + if index and (not raction or action ~= IM.ACTION_KEEP) then + raction = action + rindex = index + rtext = text + end + end + return raction, rindex, rtext + end + + if not ExecCounters[action] then ExecCounters[action] = { } end + + -- Stolen: No storing in bank or guild bank + if data.stolen and (action == IM.ACTION_STASH or action == IM.ACTION_GB_STASH) then + return IM.ACTION_KEEP, nil, nil + end + local rulelist = self.rulelists[action] + for k = 1, #rulelist, 1 do + local v = rulelist[k] + local res = v:Filter(data) + + -- If we reached the max execution count for that particular rule, skip it. + if res and v.maxCount and ExecCounters[action][k] and ExecCounters[action][k] >= v.maxCount then + res = false + end + + if res then + ExecCounters[action][k] = (ExecCounters[action][k] or 0) + 1 + data.action = (v.negate and IM.ACTION_KEEP) or action + data.guildbank = v.guildbank + return data.action, action .. ":" .. k, v:ToString() + end + end + + return IM.ACTION_KEEP, nil, nil +end + +function IMRS2:List() + for action, rulelist in pairs(self.rulelists) do + if #rulelist > 0 then + local str = GetString("IM_R2_HEADING", action) .. GetString(IM_R2_COUNT_TAG) + CHAT_SYSTEM:AddMessage(zo_strformat(str, #rulelist)) + + for i = 1, #rulelist, 1 do + CHAT_SYSTEM:AddMessage(" " .. GetString(IM_LIST_RULE) .. i .. ":" .. rulelist[i]:ToString()) + end + CHAT_SYSTEM:AddMessage("----") + end + end +end + +function IMRS2:GetRuleList(action) + return self.rulelists[action] +end diff --git a/UI/ProfileEdit.lua b/UI/ProfileEdit.lua index 4a806f7..6c3684b 100644 --- a/UI/ProfileEdit.lua +++ b/UI/ProfileEdit.lua @@ -6,7 +6,9 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager + local PE = IM.UI.ProfileEdit PE.profileList = { } @@ -102,8 +104,9 @@ function PE:BtnLoadClicked() selProfile = IM.presetProfiles[-PE.selectedProfile] end - IM.currentRuleset.rules = selProfile["rules"] - IM.currentRuleset = IM.currentRuleset:New() + IM.currentRuleset = selProfile:Clone() + IM.currentRuleset.name = nil + IM.currentRuleset.settings = nil IM.settings = { } for k,v in pairs(IM.charDefaults["settings"]) do @@ -127,11 +130,10 @@ function PE:BtnSaveClicked() PE.selectedProfile = #profiles + 1 end - profiles[PE.selectedProfile] = { - ["name"] = PE.selectedName, - ["rules"] = IM.currentRuleset:New()["rules"], - ["settings"] = IM.settings, - } + local selProfile = IM.currentRuleset:Clone(); + selProfile.name = PE.selectedName + selProfile.settings = IM.settings + profiles[PE.selectedProfile] = selProfile PE:UpdateProfileList(PE.selectedProfile) IM:Save() diff --git a/UI/RuleEdit.lua b/UI/RuleEdit.lua index dd55992..2de6925 100644 --- a/UI/RuleEdit.lua +++ b/UI/RuleEdit.lua @@ -6,7 +6,9 @@ local function _tr(str) return str end +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager + local RE = IM.UI.RuleEdit @@ -15,7 +17,7 @@ local function getChoiceboxLists(structure, fun) local _reverse = { } local _order = { } for i = 1, #structure, 1 do - n = structure[i][1] + local n = structure[i][1] _new[n] = fun(n, i) _order[i] = _new[n] _reverse[_new[n]] = n @@ -61,7 +63,6 @@ local function getSpecificFilterTypes(whichFilter) end local function getSpecificTraitTypes(whichFilter, whichSubFilter) - local rs = IM.IM_Ruleset local ttlist = IM.traitsorder[whichSubFilter] or IM.traitsorder[whichFilter] or { } local _new = { } @@ -90,7 +91,8 @@ end function RE:GetControls() RE.filterTypesList = getChoiceboxLists(IM.filterorder, function(n) return GetString(n) end) - RE.actionList = getChoiceboxLists(IM.actionorder, function(n) return GetString("IM_ACTIONTXT", n) end) + RE.actionList = getChoiceboxLists(IM.actionorder, function(n) return GetString("IM_R2_HEADING", n) end) + RE.xrefList = getChoiceboxLists(IM.xreforder, function(n) return GetString("IM_R2_HEADING", n) end) RE.qualityList = getChoiceboxListsAssoc(IM.qualityorder) local guilds = { } @@ -102,12 +104,31 @@ function RE:GetControls() end RE.guildList = getChoiceboxListsAssoc(guilds) - RE.editingRule = IM.IM_Ruleset:NewRule() + RE.editingRule = IM.IM_RuleV2:New() + RE.selectedAction = IM.ACTION_JUNK + local rule = RE.editingRule RE:UpdateFilterSpecList(rule.filterType, rule.filterSubType) RE:UpdateTraitList(rule.filterType, rule.filterSubType) return { + { + type = "dropdown", + width = "half", + name = GetString(IM_SET_RULELIST), + tooltip = GetString(IM_SET_RULELIST_TT), + choices = RE.actionList["order"], + getFunc = function() return RE.actionList["forward"][RE.selectedAction] end, + setFunc = function(value) + RE.selectedAction = RE.actionList["reverse"][value] + RE:UpdateRuleList() + end, + }, + { + type = "description", + text = "", + width = "half", + }, { type = "dropdown", name = GetString(IM_RE_CURRENTRULES), @@ -168,22 +189,21 @@ function RE:GetControls() text = GetString(IM_RE_DESC), }, { - type = "dropdown", - name = GetString(IM_RE_ACTION), + type = "checkbox", + name = GetString(IM_SET_NEGATE), + tooltip = GetString(IM_SET_NEGATE_TT), width = "half", - choices = RE.actionList["order"], - getFunc = function() return RE.actionList["forward"][RE.editingRule.action] end, - setFunc = function(value) RE.editingRule.action = RE.actionList["reverse"][value] end, + getFunc = function() return RE.editingRule.negate end, + setFunc = function(value) RE.editingRule.negate = value end, }, { type = "dropdown", - name = GetString(IM_RE_GUILDBANK), - tooltip = GetString(IM_RE_GUILDBANK_TT), + name = GetString(IM_SET_XREF), + tooltip = GetString(IM_SET_XREF_TT), width = "half", - choices = RE.guildList["order"], - getFunc = function() return RE.editingRule.guildbank or RE.guildList["seltext"] end, - setFunc = function(value) RE.editingRule.guildbank = value end, - disabled = function() return RE:GetChoGBDisabled() end, + choices = RE.xrefList["order"], + getFunc = function() return RE.xrefList["forward"][RE.editingRule.xref or IM.ACTION_KEEP] end, + setFunc = function(value) RE.editingRule.xref = RE.xrefList["reverse"][value] end, }, { type = "slider", @@ -198,9 +218,14 @@ function RE:GetControls() width = "half", --or "half" (optional) }, { - type = "description", - text = "", + type = "dropdown", + name = GetString(IM_RE_GUILDBANK), + tooltip = GetString(IM_RE_GUILDBANK_TT), width = "half", + choices = RE.guildList["order"], + getFunc = function() return RE.editingRule.guildbank or RE.guildList["seltext"] end, + setFunc = function(value) RE.editingRule.guildbank = value end, + disabled = function() return RE:GetChoGBDisabled() end, }, { type = "dropdown", @@ -229,12 +254,13 @@ function RE:GetControls() reference = "IWONTSAY_IM_CHO_TRAIT", }, { - type = "checkbox", - name = GetString(IM_RE_PARTOFSET), + type = "dropdown", + name = GetString(IM_FCOIS_CHOICE), width = "half", - disabled = function() return RE:GetIsSetCheckDisabled() end, - getFunc = function() return RE.editingRule.isSet end, - setFunc = function(value) RE.editingRule.isSet = value end, + choices = IM.FCOISL:GetIconChoices(), + getFunc = function() return IM.FCOISL:GetIndexedMark(RE.editingRule.FCOISMark) end, + setFunc = function(value) RE.editingRule.FCOISMark = IM.FCOISL:GetMarkIndex(value) end, + disabled = function() return not IM.FCOISL:hasAddon() and not IM.ISL:hasAddon() end }, { type = "dropdown", @@ -253,13 +279,12 @@ function RE:GetControls() setFunc = function(value) RE.editingRule.maxQuality = RE.qualityList["reverse"][value] end, }, { - type = "dropdown", - name = GetString(IM_FCOIS_CHOICE), + type = "checkbox", + name = GetString(IM_RE_PARTOFSET), width = "half", - choices = IM.FCOISL:GetIconChoices(), - getFunc = function() return IM.FCOISL:GetIndexedMark(RE.editingRule.FCOISMark) end, - setFunc = function(value) RE.editingRule.FCOISMark = IM.FCOISL:GetMarkIndex(value) end, - disabled = function() return not IM.FCOISL:hasAddon() and not IM.ISL:hasAddon() end + disabled = function() return RE:GetIsSetCheckDisabled() end, + getFunc = function() return RE.editingRule.isSet end, + setFunc = function(value) RE.editingRule.isSet = value end, }, { type = "checkbox", @@ -290,8 +315,12 @@ function RE:GetControls() setFunc = function(value) RE.editingRule.crafted = value end, }, { - type = "description", - text = "", + type = "editbox", + name = GetString(IM_SET_TXTMATCH), + tooltip = GetString(IM_SET_TXTMATCH_TT), + getFunc = function() return RE.editingRule.text end, + setFunc = function(text) RE.editingRule.text = text end, + isMultiline = false, width = "half", }, } @@ -303,7 +332,7 @@ end function RE:BtnAddBeforeClicked() DEBUG("--- OnBtnAddBefore") - local rs = IM.currentRuleset.rules + local rs = IM.currentRuleset:GetRuleList(RE.selectedAction) RE.selectedRule = RE.selectedRule or 1 table.insert(rs, RE.selectedRule, RE.editingRule) RE:UpdateRuleList(RE.selectedRule) @@ -312,7 +341,7 @@ end function RE:BtnAddAfterClicked() DEBUG("--- OnBtnAddAfter") - local rs = IM.currentRuleset.rules + local rs = IM.currentRuleset:GetRuleList(RE.selectedAction) RE.selectedRule = RE.selectedRule or 0 RE.selectedRule = RE.selectedRule + 1 table.insert(rs, RE.selectedRule, RE.editingRule) @@ -322,7 +351,7 @@ end function RE:BtnDeleteClicked() DEBUG("--- OnBtnDelete") - local rs = IM.currentRuleset.rules + local rs = IM.currentRuleset:GetRuleList(RE.selectedAction) table.remove(rs, RE.selectedRule) if RE.selectedRule > #rs then RE.selectedRule = #rs @@ -333,7 +362,7 @@ end function RE:BtnReplaceClicked() DEBUG("--- OnBtnAddAfter") - local rs = IM.currentRuleset.rules + local rs = IM.currentRuleset:GetRuleList(RE.selectedAction) RE.selectedRule = RE.selectedRule or 1 rs[RE.selectedRule] = RE.editingRule RE:UpdateRuleList(RE.selectedRule) @@ -341,7 +370,7 @@ function RE:BtnReplaceClicked() end local function moveRule(direction) - local rs = IM.currentRuleset.rules + local rs = IM.currentRuleset:GetRuleList(RE.selectedAction) local tmp = rs[RE.selectedRule] rs[RE.selectedRule] = rs[RE.selectedRule+direction] rs[RE.selectedRule+direction] = tmp @@ -376,7 +405,7 @@ function RE:GetBtnMoveDownDisabled() end function RE:GetChoGBDisabled() - return RE.editingRule.action ~= IM.ACTION_GB_STASH and RE.editingRule.action ~= IM.ACTION_GB_RETRIEVE + return RE.selectedAction ~= IM.ACTION_GB_STASH and RE.selectedAction ~= IM.ACTION_GB_RETRIEVE end function RE:UpdateTraitList(filterType, filterSubType) @@ -385,9 +414,6 @@ function RE:UpdateTraitList(filterType, filterSubType) local traitTxt = (RE.editingRule.traitType and RE.traitList["forward"][RE.editingRule.traitType]) or RE.traitList["seltext"] - -- Explicitely set here. If traitTxt is nil, because no traits are listed, it wouldn't be set elsewhere - RE.editingRule.traitType = RE.traitList["reverse"][value] - if not IWONTSAY_IM_CHO_TRAIT then return end IWONTSAY_IM_CHO_TRAIT:UpdateChoices(RE.traitList["order"]); @@ -412,7 +438,7 @@ end function RE:UpdateRuleList(preselection) DEBUG("--- UpdateRuleList()", preselection) - local rules = IM.currentRuleset.rules + local rules = IM.currentRuleset:GetRuleList(RE.selectedAction) RE.ruleList = { } RE.reverseRuleList = { } if #rules then @@ -452,8 +478,8 @@ end function RE:SetSelectedRule(whichRuleText) DEBUG("--- SetSelectedRule", whichRuleText) RE.selectedRule = RE.reverseRuleList[whichRuleText] - local rule = IM.currentRuleset.rules[RE.selectedRule] - RE.editingRule = (rule and rule:New()) or RE.editingRule + local rule = IM.currentRuleset:GetRuleList(RE.selectedAction)[RE.selectedRule] + RE.editingRule = (rule and rule:Clone()) or RE.editingRule rule = RE.editingRule RE:UpdateFilterSpecList(rule.filterType, rule.filterSubType) diff --git a/UI/Settings.lua b/UI/Settings.lua index 473ceab..d6e5bd3 100644 --- a/UI/Settings.lua +++ b/UI/Settings.lua @@ -5,7 +5,10 @@ d local function _tr(str) return str end + +if not InventoryManager then InventoryManager = {} end local IM = InventoryManager + local SE = IM.UI.Settings function SE:GetControls() diff --git a/lang/de.lua b/lang/de.lua index 1537f82..7eee38d 100644 --- a/lang/de.lua +++ b/lang/de.lua @@ -4,7 +4,7 @@ local lang = { -- parameters are itemDescription, qualityRangeText, isSetText, actionText -- e.g. "put in trash any stolen worthless light armor with quality Trash to Normal" - IM_RULETXTFORMAT = "<<4>>: jeder <<z:1>><<z:2>><<z:3>>", + IM_RULETXTFORMAT = "<<4>>: jeder <<1>><<z:2>><<z:3>>", IM_RULETXT_ISSET = "(Teil eines Sets)", IM_RULETXT_STOLEN = "gestohlene(s)", IM_RULETXT_WORTHLESS = "wertlos(es)", @@ -13,6 +13,7 @@ local lang = { IM_RULETXT_QUALITY1 = "mit Qualität <<1>>", IM_RULETXT_QUALITY2 = "mit Qualität von <<1>> bis <<2>>", IM_RULETXT_EXECOUNT = "(max. <<1>>-mal)", + IM_RULETXT_TXT = "passend auf '<<1>>'", IM_ACTIONTXT0 = "Behalten", IM_ACTIONTXT1 = "Zum Müll stecken", @@ -154,6 +155,14 @@ local lang = { IM_SET_INV_TT = "Setzt die Verzögerung zwischen Änderungen im Inventar wie Sperren/Entsperren usw.", IM_SET_EXECOUNT = "Maximale Anzahl Ausführungen", IM_SET_EXECOUNT_TT = "Wie oft diese Regel maximal in einem Lauf ausgeführt werden darf. 0 bedeutet 'unbegrenzt'", + IM_SET_RULELIST = "Regelliste", + IM_SET_RULELIST_TT = "Gibt die Gelegenheit an, bei der die nachfolgende Liste angewendet wird", + IM_SET_NEGATE = "Negieren", + IM_SET_NEGATE_TT = "Wenn gesetzt, wird diese Aktion NICHT auf die Gegenstände angewendet, die passen", + IM_SET_XREF = "Kreuzreferenz", + IM_SET_XREF_TT = "Wenn gesetzt, verweist es auf eine andere Regelliste, die zu Rate gezogen wird", + IM_SET_TXTMATCH = "Filtertext", + IM_SET_TXTMATCH_TT = "Wenn nicht leer, bezeichnet es den Namen oder einen Namensteil von dem passenden Objekt. Reguläre Ausdrücke sind zulässig.", IM_PM_PROFILENAME_TOOLTIP = "Namen vom Profil hier eingeben", IM_RM_PRESETRULES = "--- Voreingestellte Profile ---", @@ -182,7 +191,8 @@ local lang = { IM_INIT_DETECTED_CS_OLD = "IM: Altes CraftStore 3.00+ AddOn erkannt. Es ist überholt, bitte aktualisieren Sie auf 'CraftStore Fixed And Improved'", IM_INIT_DETECTED_CS_NEW = "IM: CraftStore Fixed And Improved AddOn erkannt", - IM_INIT_UPDATE_V2_NOTE = "Aktualisiere Charakterdaten nach Version 2: Regel 'Verkaufe alle Gegenstände im Müll' hinzugefügt, um altes Verhalten beizubehalten.", + IM_INIT_UPDATE_V2_NOTE = "Aktualisiere Charakterdaten nach Version 2: Regel 'Verkaufe alle Gegenstände im Müll' hinzugefügt, um altes Verhalten beizubehalten.", + IM_INIT_UPDATE_V3_NOTE = "Aktualisiere Charakterdaten nach Version 3: Regeln neu organisiert", IM_FCO_STATIC_TXT1 = "zur Sperrung", IM_FCO_STATIC_TXT2 = "Ausrüstungssatz 1", @@ -195,7 +205,24 @@ local lang = { IM_FCO_STATIC_TXT9 = "zur Zerlegung", IM_FCO_STATIC_TXT10 = "zur Verbesserung", IM_FCO_STATIC_TXT11 = "zum Verkauf im Gildenladen", - IM_FCO_STATIC_TXT12 = "intrikat", + IM_FCO_STATIC_TXT12 = "aufwändig", + + IM_R2_HEADING0 = "(Keine Kreuzreferenz)", + IM_R2_HEADING1 = "Beim Aufheben eines Gegenstands, in den Müll, wenn ...", + IM_R2_HEADING2 = "Beim vollen Inventar, vernichte ...", + IM_R2_HEADING3 = "Verkaufe beim Geschäft oder Hehler ...", + IM_R2_HEADING4 = "Wasche beim Hehler ...", + IM_R2_HEADING5 = "Am Arbeitstisch, zerlege ...", + IM_R2_HEADING10 = "Lege in die eigene Bank ...", + IM_R2_HEADING20 = "Hole aus der eigenen Bank ...", + IM_R2_HEADING11 = "Lege die in der Regel angegebenen Gildenbank ...", + IM_R2_HEADING21 = "Hole aus die in der Regel angegebenen Gildenbank ...", + IM_R2_COUNT_TAG = " (Regeln: <<1>>)", + + IM_R2_FORMAT0 = "Kein <<1>><<z:2>><<z:3>> <<4>>", -- Rule V2 text, negative + IM_R2_FORMAT1 = "Jeder <<1>><<z:2>><<z:3>> <<4>>", -- Rule V2 text, positive + IM_R2_FORMAT2 = "Nichts von der Liste '<<z:1>>' <<2>>", -- Rule V2 text, cross reference, negative + IM_R2_FORMAT3 = "Alles von der Liste '<<z:1>>' <<2>>" -- Rule V2 text, cross reference, positive } diff --git a/lang/en.lua b/lang/en.lua index 6a93ad8..d685e78 100644 --- a/lang/en.lua +++ b/lang/en.lua @@ -4,7 +4,7 @@ local lang = { -- parameters are itemDescription, qualityRangeText, isSetText, actionText -- e.g. "put in trash any stolen worthless light armor with quality Trash to Normal" - IM_RULETXTFORMAT = "<<z:4>> any <<z:1>><<z:2>><<z:3>>", + IM_RULETXTFORMAT = "<<z:4>> any <<1>><<z:2>><<z:3>>", IM_RULETXT_ISSET = "which is part of a set", IM_RULETXT_STOLEN = "stolen", IM_RULETXT_WORTHLESS = "worthless", @@ -13,6 +13,7 @@ local lang = { IM_RULETXT_QUALITY1 = "with quality <<1>>", IM_RULETXT_QUALITY2 = "with quality from <<1>> to <<2>>", IM_RULETXT_EXECOUNT = "(max. <<1>> times)", + IM_RULETXT_TXT = "matching '<<1>>'", IM_ACTIONTXT0 = "Keep", IM_ACTIONTXT1 = "Put to junk", @@ -155,7 +156,15 @@ local lang = { IM_SET_INV_TT = "Sets the delay between inventory status changes like junk/unjunk lock/unlock and so on.", IM_SET_EXECOUNT = "Maximum execution count", IM_SET_EXECOUNT_TT = "How often this rule may be executed in a single run. 0 means 'unlimited'", - + IM_SET_RULELIST = "Rule list", + IM_SET_RULELIST_TT = "Select the occasion the list of rules apply to", + IM_SET_NEGATE = "Negate", + IM_SET_NEGATE_TT = "When set, matching items will NOT have this action performed on.", + IM_SET_XREF = "Cross Reference", + IM_SET_XREF_TT = "When set, refer to another rule list to determine the course of action", + IM_SET_TXTMATCH = "Filter text", + IM_SET_TXTMATCH_TT = "When not empty, it states a name or the part of the name of the item to match. Note: Regular expressions do work here.", + IM_PM_PROFILENAME_TOOLTIP = "Enter the name of the new profile here", IM_RM_PRESETRULES = "--- Preset profiles ---", IM_RM_CUSTOMRULES = "--- Custom profiles ---", @@ -184,6 +193,7 @@ local lang = { IM_INIT_DETECTED_CS_OLD = "IM: Old CraftStore 3.00+ detected. It's outdated, please update to 'CraftStore Fixed And Improved'", IM_INIT_DETECTED_CS_NEW = "IM: CraftStore Fixed And Improved detected", IM_INIT_UPDATE_V2_NOTE = "Upgraded character data to version 2: Added sell rule up front to maintain backwards compatibility.", + IM_INIT_UPDATE_V3_NOTE = "Upgraded character data to version 3: Reorganized rules", IM_FCO_STATIC_TXT1 = "for locking", IM_FCO_STATIC_TXT2 = "gear set 1", @@ -197,6 +207,24 @@ local lang = { IM_FCO_STATIC_TXT10 = "for improvement", IM_FCO_STATIC_TXT11 = "for sale at guildstore", IM_FCO_STATIC_TXT12 = "intricate", + + IM_R2_HEADING0 = "(No cross reference)", + IM_R2_HEADING1 = "On picking up an item, junk it if ...", + IM_R2_HEADING2 = "When inventory filled up, destroy ...", + IM_R2_HEADING3 = "Sell at shop or fence ...", + IM_R2_HEADING4 = "Launder at fence ...", + IM_R2_HEADING5 = "Deconstruct at crafting station ...", + IM_R2_HEADING10 = "Store in own bank ...", + IM_R2_HEADING20 = "Retrieve from own bank ...", + IM_R2_HEADING11 = "Store in named guild bank ...", + IM_R2_HEADING21 = "Retrieve from named guild bank ...", + IM_R2_COUNT_TAG = " (rules: <<1>>)", + + IM_R2_FORMAT0 = "No <<1>><<z:2>><<z:3>> <<4>>", -- Rule V2 text, negative + IM_R2_FORMAT1 = "Any <<1>><<z:2>><<z:3>> <<4>>", -- Rule V2 text, positive + IM_R2_FORMAT2 = "Nothing from the list '<<z:1>>' <<2>>", -- Rule V2 text, cross reference, negative + IM_R2_FORMAT3 = "Everything from the list '<<z:1>>' <<2>>" -- Rule V2 text, cross reference, positive + } for stringId, stringValue in pairs(lang) do