diff --git a/CraftStoreLink.lua b/CraftStoreLink.lua
index eda8eeb..ff48880 100644
--- a/CraftStoreLink.lua
+++ b/CraftStoreLink.lua
@@ -11,129 +11,81 @@ local IM = InventoryManager
local CSL = {}
-local Used_CS
-local Used_CSA
-
local hasCS = nil
IM.CSL = CSL
-local function SplitLink(link,nr)
- local split = {SplitString(':', link)}
- if split[nr] then return tonumber(split[nr]) else return false end
-end
-
function CSL:hasCSAddon()
if hasCS ~= nil then
- -- This variable is late initialized, update if needed
- if hasCS == "new" then
- Used_CSA = Used_CS.Account
- end
-
- return hasCS ~= false and true
+ return hasCS
end
if CS then
- Used_CS = CS
- Used_CSA = Used_CS.Account
- CHAT_SYSTEM:AddMessage(GetString(IM_INIT_DETECTED_CS_NEW))
- hasCS = "new"
- elseif CraftStoreFixedAndImprovedLongClassName then
- -- In case someone is lazy updating past 1.74
- Used_CS = CraftStoreFixedAndImprovedLongClassName
- Used_CSA = Used_CS.Account
CHAT_SYSTEM:AddMessage(GetString(IM_INIT_DETECTED_CS_NEW))
- hasCS = "new"
+ hasCS = true
else
hasCS = false
end
return hasCS
end
-function CSL:IsTraitNeeded(itemLink)
- local need = { }
- local craft, row, trait = Used_CS.GetTrait(itemLink)
- -- Loop all chars known by CS
- for char, data in pairs(Used_CSA.crafting.studies) do
- --if a char study this item
- if data[craft] and data[craft][row] and (data[craft][row]) then
- -- If this char didn't yet researched this item
- local csr = Used_CSA.crafting.research
- if csr[char][craft] and csr[char][craft][row] and csr[char][craft][row][trait] == false then
- need[char] = true
- need[#need + 1] = char
- end
- end
+local CURRENT_PLAYER = GetUnitName("player")
+
+-- It would help me LOTS if Is*Needed would return the raw names list rather than formatted strings.
+-- Now I have to take them apart again and make graceful assumptions on their format. :(
+function CSL:parseNeeded(needStr)
+
+ -- Can happen with items which cannot be deconstructed (or researched)
+ if not needStr then
+ return false, false
end
- return need
-end
-local CURRENT_PLAYER = GetUnitName("player")
+ local nameHeader = "|cFF1010" -- output modifier: red coloring
+ local formattedName = nameHeader .. CURRENT_PLAYER .. "|r" -- including tail to reset the output modifier
+ local headerpos = needStr:find(nameHeader)
-function CSL:IsStyleNeeded(link)
- local id, need = SplitLink(link,3), { }
- if id then
- for _, char in pairs(Used_CS.GetCharacters()) do
- if Used_CSA.style.tracking[char] and not Used_CS.Data.style.knowledge[char][id] then
- need[char] = true
- need[#need + 1] = char
- end
- end
+ -- If we don't find a red coloured name at all, no one seems to need it.
+ if not headerpos then
+ return false, false
end
- return need
-end
-function CSL:IsCookRecipeNeeded(link)
- local id, need = SplitLink(link,3), { }
- if id then
- for char,data in pairs(Used_CS.Data.cook.knowledge) do
- if data[id] ~= nil and not data[id] and Used_CSA.cook.tracking[char] then
- need[char] = true
- need[#need + 1] = char
- end
- end
+ -- true of we found our own name on the list
+ local needSelf = (needStr:find(formattedName) or -1) > -1
+
+ -- string length, minus header (everything in front of the first name), and
+ -- eventually the own name. If there's something left, other characters need it, too.
+ local lenOthers = needStr:len() - headerpos + 1
+ if needSelf then
+ lenOthers = lenOthers - formattedName:len()
end
- return need
+
+ local needOthers = lenOthers > 0
+
+ return needSelf, needOthers
end
-function CSL:IsBlueprintNeeded(link)
- local id, need = SplitLink(link,3), { }
+function CSL:IsItemNeeded(itemLink, uID)
+ local craft, row, trait = CS.GetTrait(itemLink)
+ return self:parseNeeded(CS.IsItemNeeded(craft, row, trait, uID, itemLink))
+end
- if not Used_CSA.furnisher then
- return need
- end
- if id then
- for char,data in pairs(Used_CS.Data.furnisher.knowledge) do
- if data[id] ~= nil and not data[id] and Used_CSA.furnisher.tracking[char] then
- need[char] = true
- need[#need + 1] = char
- end
- end
- end
- return need
+function CSL:IsStyleNeeded(link)
+ return self:parseNeeded(CS.IsStyleNeeded(itemLink))
end
function CSL:IsRecipeNeeded(link)
- local collate1 = self:IsCookRecipeNeeded(link)
- local collate2 = self:IsBlueprintNeeded(link)
- local all = { }
- for k, v in pairs(collate1) do
- if type(k) == "string" then all[k] = true end
- end
- for k, v in pairs(collate2) do
- if type(k) == "string" then all[k] = true end
- end
- for k, v in pairs(all) do
- all[#all+1] = k
- end
- return all
+ return self:parseNeeded(CS.IsRecipeNeeded(itemLink))
+end
+
+function CSL:IsBlueprintNeeded(link)
+ return self:parseNeeded(CS.IsBlueprintNeeded(itemLink))
end
-function CSL:isUnknown(itemLink)
- local chars
- local itemType
+function CSL:isUnknown(itemLink, uID)
+ local oneself, others
+ local itemType, specItemType
if not CSL:hasCSAddon() then
return false, false
@@ -148,25 +100,16 @@ function CSL:isUnknown(itemLink)
specItemType == SPECIALIZED_ITEMTYPE_RECIPE_PROVISIONING_DESIGN_FURNISHING or
specItemType == SPECIALIZED_ITEMTYPE_RECIPE_WOODWORKING_BLUEPRINT_FURNISHING or
specItemType == SPECIALIZED_ITEMTYPE_RECIPE_JEWELRYCRAFTING_SKETCH_FURNISHING then
- DEBUG("Blueprint:", CS.IsBlueprintNeeded(itemLink))
- chars = CSL:IsBlueprintNeeded(itemLink)
+ oneself, others = CSL:IsBlueprintNeeded(itemLink)
else
- DEBUG("Cooking Recipe:", CS.IsRecipeNeeded(itemLink))
- chars = CSL:IsCookRecipeNeeded(itemLink)
+ oneself, others = CSL:IsRecipeNeeded(itemLink)
end
elseif itemType == ITEMTYPE_RACIAL_STYLE_MOTIF then
- chars = CSL:IsStyleNeeded(itemLink)
+ oneself, others = CSL:IsStyleNeeded(itemLink)
elseif itemType == ITEMTYPE_WEAPON or itemType == ITEMTYPE_ARMOR then
- chars = CSL:IsTraitNeeded(itemLink)
+ oneself, others = CSL:IsItemNeeded(itemLink, uID)
end
- if not chars then
- return false, false
- end
-
- local oneself = (chars[CURRENT_PLAYER] or false)
- local numothers = #chars - ((oneself and 1) or 0)
- local others = numothers > 0
-
+ -- allow (nil, nil) for items which don't fit in any category
return oneself, others
end
diff --git a/InventoryManager.lua b/InventoryManager.lua
index 75a1510..4945bf6 100644
--- a/InventoryManager.lua
+++ b/InventoryManager.lua
@@ -23,7 +23,7 @@ IM.opssuspended = false
-- The current ruleset we're working with
IM.currentRuleset = { }
-local ADDON_VERSION = "2.4.4"
+local ADDON_VERSION = "2.5.0"
local ADDON_WEBSITE = "https://www.esoui.com/downloads/info1642-InventoryManager.html"
function IM:ProcessSingleItem(dryrun, data)
@@ -90,6 +90,7 @@ function IM:GetItemData(slotId, _inv)
end
local itemLink = GetItemLink(self.currentBagType, slotId)
+ local uID = Id64ToString(GetItemUniqueId(self.currentBagType, slotId))
data.bagId = self.currentBagType
data.slotId = slotId
@@ -122,7 +123,7 @@ function IM:GetItemData(slotId, _inv)
data.crafted = IsItemLinkCrafted(itemLink)
data.unique = IsItemLinkUnique(itemLink)
- data.unknownself, data.unknownothers = self.CSL:isUnknown(itemLink)
+ data.unknownself, data.unknownothers = self.CSL:isUnknown(itemLink, uID)
return data
end
diff --git a/InventoryManager.txt b/InventoryManager.txt
index ecb3d10..fd4fac3 100644
--- a/InventoryManager.txt
+++ b/InventoryManager.txt
@@ -2,7 +2,7 @@
## APIVersion: 100030
## DependsOn: LibAddonMenu-2.0
## SavedVariables: IMSavedVars
-## Version: 2.4.4
+## Version: 2.5.0
## Author: iwontsay & iFedix
## Description: Automatically stash, retrieve and dispose your items with custom rules!
diff --git a/Modules/Extractor.lua b/Modules/Extractor.lua
index 1dd5752..512c660 100644
--- a/Modules/Extractor.lua
+++ b/Modules/Extractor.lua
@@ -1,6 +1,6 @@
local DEBUG =
--- function() end
-d
+function() end
+-- d
local function _tr(str)
return str
@@ -33,37 +33,46 @@ local wt2tradeskill = {
[WEAPONTYPE_TWO_HANDED_SWORD] = CRAFTING_TYPE_BLACKSMITHING,
}
+local jt2tradeskill = {
+ [EQUIP_TYPE_RING] = CRAFTING_TYPE_JEWELRYCRAFTING,
+ [EQUIP_TYPE_NECK] = CRAFTING_TYPE_JEWELRYCRAFTING,
+}
+
local it2tradeskill = {
[ITEMTYPE_GLYPH_ARMOR] = CRAFTING_TYPE_ENCHANTING,
[ITEMTYPE_GLYPH_WEAPON] = CRAFTING_TYPE_ENCHANTING,
[ITEMTYPE_GLYPH_JEWELRY] = CRAFTING_TYPE_ENCHANTING,
- [ITEMTYPE_ARMOR] = { "armorType", at2tradeskill },
- [ITEMTYPE_WEAPON] = { "weaponType", wt2tradeskill },
+ [ITEMTYPE_ARMOR] = { ["equipType"] = jt2tradeskill, ["armorType"] = at2tradeskill },
+ [ITEMTYPE_WEAPON] = { ["weaponType"] = wt2tradeskill },
}
-local dt2tradeskill = { "itemType", it2tradeskill }
+local dt2tradeskill = { ["itemType"] = it2tradeskill }
-- Recurse through the decision tree to get the correct tradeskill for the item
local function GetItemTradeSkill(data, _used_table)
if not _used_table then _used_table = dt2tradeskill end
- local _key = _used_table[1]
- local _tab = _used_table[2]
-
- local entry = _tab[data[_key]]
-
- if not entry then return nil end
+ for _key, _tab in pairs(_used_table) do
+ local entry = _tab[data[_key]]
- if type(entry) ~= "table" then return entry end
+ -- Recurse if we see a table with more decision criteria
+ if entry and type(entry) == "table" then return GetItemTradeSkill(data, entry) end
- return GetItemTradeSkill(data, entry)
+ -- Return if we find a plain value at a leaf
+ if entry then
+ DEBUG("Found!", entry)
+ return entry
+ end
+ end
+
+ return nil
end
local function GetTradeskillUsed()
if not ZO_EnchantingTopLevelExtractionSlotContainer:IsHidden() then
return CRAFTING_TYPE_ENCHANTING
elseif not ZO_SmithingTopLevelDeconstructionPanelSlotContainer:IsHidden() then
- return CRAFTING_TYPE_BLACKSMITHING
+ return CRAFTING_TYPE_BLACKSMITHING -- Includes everything else that is not Enchanting
end
return nil
@@ -74,7 +83,7 @@ local function filter_for_deconstruction(tradeskill, data)
if ts ~= tradeskill then return false end
- if not CanItemBeSmithingExtractedOrRefined(data.bagId, data.slotId, ts) then return false end
+ if not CanItemBeDeconstructed(data.bagId, data.slotId, ts) then return false end
if IM.FCOISL:IsProtectedAction(data.action, data.bagId, data.slotId, ts == CRAFTING_TYPE_ENCHANTING) then return false end
diff --git a/lang/de.lua b/lang/de.lua
index e69b54e..94b6434 100644
--- a/lang/de.lua
+++ b/lang/de.lua
@@ -201,12 +201,12 @@ local lang = {
IM_FCOIS_UNMARKED = "unmarkiert(es)",
IM_FCOIS_WITHANYMARK = "mit einer Markierung",
IM_FCOIS_MARKEDASX = "markiert als <<z:1>>",
- IM_FCOIS_NOCAREMARK = "Nicht relevant",
+ IM_FCOIS_NOCAREMARK = "(irrelevant)",
IM_FCOIS_NOMARK = "Keine Markierung",
IM_FCOIS_ANYMARK = "Irgendeine Markierung",
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_DETECTED_CS_NEW = "IM: CraftStore 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_V3_NOTE = "Aktualisiere Charakterdaten nach Version 3: Regeln neu organisiert",
diff --git a/lang/en.lua b/lang/en.lua
index c56cfde..a2ce1be 100644
--- a/lang/en.lua
+++ b/lang/en.lua
@@ -201,12 +201,12 @@ local lang = {
IM_FCOIS_UNMARKED = "unmarked",
IM_FCOIS_WITHANYMARK = "with any mark",
IM_FCOIS_MARKEDASX = "marked as <<z:1>>",
- IM_FCOIS_NOCAREMARK = "Don't care",
+ IM_FCOIS_NOCAREMARK = "(irrelevant)",
IM_FCOIS_NOMARK = "No mark",
IM_FCOIS_ANYMARK = "Any mark",
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_DETECTED_CS_NEW = "IM: CraftStore 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",
@@ -218,7 +218,7 @@ local lang = {
IM_FCO_STATIC_TXT6 = "gear set 3",
IM_FCO_STATIC_TXT7 = "gear set 4",
IM_FCO_STATIC_TXT8 = "gear set 5",
- IM_FCO_STATIC_TXT9 = "deconstruction",
+ IM_FCO_STATIC_TXT9 = "for deconstruction",
IM_FCO_STATIC_TXT10 = "for improvement",
IM_FCO_STATIC_TXT11 = "for sale at guildstore",
IM_FCO_STATIC_TXT12 = "intricate",