local DEBUG = function() end -- d local function _tr(str) return str end if not InventoryManager then InventoryManager = {} end local IM = InventoryManager if not IM.IM_Rule then IM.IM_Rule = ZO_Object:Subclass() end local IMR = IM.IM_Rule if not IM.IM_Ruleset then IM.IM_Ruleset = ZO_Object:Subclass() end local IMRS = IM.IM_Ruleset 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 function IMR:Clone() local rule = IMR:New() for k,v in pairs(self) do rule[k] = v end return rule end function IMR:ToString() local qualityRangeText = "" local isSetText = "" local actionText = GetString("IM_ACTIONTXT", self.action) local itemDescription = zo_strformat( GetString(self.filterSubType), " " .. GetString(self.filterType)) if self.maxCount then actionText = actionText .. " " .. zo_strformat(GetString(IM_RULETXT_EXECOUNT), self.maxCount) end if self.traitType then local which = (self.filterType == "IM_FILTER_CONSUMABLE" and 1) or 0 if self.traitType < 0 then 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, 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_RULETXTFORMAT), itemDescription, qualityRangeText, isSetText, actionText) end function IMR:Filter(data) local filterList = IM.filtertypes[self.filterType][self.filterSubType] if #filterList > 0 then local attrName = filterList[1] local found = false for i = 2, #filterList, 1 do if data[attrName] == filterList[i] then found = true break end end if not found then return false end end -- For sake of simplicity, translate 'intricate' and 'ornate' to a single value local traitType = data.traitType if traitType == ITEM_TRAIT_TYPE_ARMOR_NIRNHONED then traitType = ITEM_TRAIT_TYPE_WEAPON_NIRNHONED end if traitType == ITEM_TRAIT_TYPE_ARMOR_INTRICATE then traitType = ITEM_TRAIT_TYPE_WEAPON_INTRICATE end if traitType == ITEM_TRAIT_TYPE_ARMOR_ORNATE then traitType = ITEM_TRAIT_TYPE_WEAPON_ORNATE end if traitType == ITEM_TRAIT_TYPE_JEWELRY_INTRICATE then traitType = ITEM_TRAIT_TYPE_WEAPON_INTRICATE end if traitType == ITEM_TRAIT_TYPE_JEWELRY_ORNATE then traitType = ITEM_TRAIT_TYPE_WEAPON_ORNATE end -- Ornate, Intricate, ect. if self.traitType then if self.traitType == IMRS.ITEM_TRAIT_TYPE_ANY then if traitType == ITEM_TRAIT_TYPE_NONE then return false end elseif self.traitType == IMRS.ITEM_TRAIT_TYPE_NOTRAIT then if traitType ~= ITEM_TRAIT_TYPE_NONE then return false end elseif self.traitType == IMRS.ITEM_TRAIT_TYPE_ANYUNKOTHERS then if not data.unknownothers then return false end elseif self.traitType == IMRS.ITEM_TRAIT_TYPE_ANYUNKNOWN then if not data.unknownself then return false end elseif self.traitType ~= traitType then return false end end -- FCO ItemSaver marker? -- Call with parameters suitable for both API's and let FCOISL sort it out. 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 -- Part of a set? if self.isSet and not data.isSet then return false end -- stolen only? if self.stolen and not data.stolen then return false end -- worthless? if self.worthless and data.value ~= 0 then return false end -- crafted? if self.crafted and not data.crafted then return false end -- 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 IMRS.version = 1 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 IMRS:ResetCounters() ExecCounters = nil end function IMRS:Match(data, action) if not ExecCounters then ExecCounters = { } end for k, v in pairs(self.rules) do local res = v:Filter(data) -- Safeguards -- If it's locked, don't touch. -- 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 == 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 ~= 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 res = false end if res then ExecCounters[k] = (ExecCounters[k] or 0) + 1 data.action = v.action data.guildbank = v.guildbank return v.action, k, v:ToString() end end return IM.ACTION_KEEP, nil, nil end 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 function IMRS:GetRuleList(action) return self.rules end