local function copy(obj, seen) if type(obj) ~= 'table' then return obj end if seen and seen[obj] then return seen[obj] end local s = seen or {} local res = setmetatable({}, getmetatable(obj)) s[obj] = res for k, v in pairs(obj) do res[copy(k, s)] = copy(v, s) end return res end function LeoTrainer.maxStyle(piece) local maxStyleId = -1 local maxQty = 0 for _,i in ipairs(LeoTrainer.const.racialStyles) do if IsSmithingStyleKnown(i, piece) == true then local qty = GetCurrentSmithingStyleItemCount(i) if qty > maxQty then maxStyleId = i maxQty = qty end end end return maxStyleId end function LeoTrainer.GetCharKnowsTrait(craft, line, trait) local known = {} local unknown = {} local myself = false local all = {} for i, char in ipairs(LeoAltholic.GetCharacters()) do all[char.bio.name] = char.research[craft][line][trait] ~= false if char.research[craft][line][trait] ~= false then if char.bio.name == GetUnitName("player") then myself = true end table.insert(known, char.bio.name) else table.insert(unknown, char.bio.name) end end return myself, known, unknown, all end function LeoTrainer.IKnowTrait(craft, line, trait) local myself = LeoAltholic.GetMyself() return myself.research[craft][line][trait] == true end function LeoTrainer.GetPatternIndexes(craft) LeoTrainer.namesToPatternIndexes[craft] = { ["names"] = {}, ["lines"] = {} } for patternIndex = 1, GetNumSmithingPatterns() do local _, name = GetSmithingPatternInfo(patternIndex) LeoTrainer.namesToPatternIndexes[craft]["names"][name] = patternIndex end for line = 1, GetNumSmithingResearchLines(craft) do local lineName, lineIcon, numTraits = GetSmithingResearchLineInfo(craft, line) LeoTrainer.namesToPatternIndexes[craft]["lines"][line] = LeoTrainer.namesToPatternIndexes[craft]["names"][lineName] end end function LeoTrainer.OnCraftFailed(event, station) --GetString("SI_TRADESKILLRESULT", result) --d("FAILED " .. event) end function LeoTrainer.OnCraftComplete(event, station) --local numItemsGained = GetNumLastCraftingResultItemsAndPenalty() --local craftFailed = numItemsGained == 0 --d(craftFailed) if LeoTrainer.isCrafting == 0 then return end LeoTrainer.RemoveFromQueue(LeoTrainer.isCrafting) LeoTrainer.isCrafting = 0 -- Player still at station and pressed Craft All if GetCraftingInteractionType() ~= CRAFTING_TYPE_INVALID and LeoTrainer.continueCrating == true then zo_callLater(function() LeoTrainer.CraftNext() end, 200) end end function LeoTrainer.CraftItem(queueIndex, data) LeoTrainer.log("Crafting " .. data.itemLink .. " ("..data.researchName..") ...") if IsPerformingCraftProcess() == true then LeoTrainer.log("Still crafting ...") return false end data.patternIndex = LeoTrainer.namesToPatternIndexes[data.craft]["lines"][data.line] local matName, _, matReq = GetSmithingPatternMaterialItemInfo(data.patternIndex, data.materialIndex) data.materialQuantity = matReq local curMats = GetCurrentSmithingMaterialItemCount(data.patternIndex, data.materialIndex) if curMats < data.materialQuantity then local diff = data.materialQuantity - curMats LeoTrainer.log("Not enough " .. matName .. ". Need " .. diff .. " more.") LeoTrainer.continueCrating = false return false end data.itemStyleId = LeoTrainer.maxStyle(data.line) if data.itemStyleId == -1 then LeoTrainer.log("Not enough known style material.") LeoTrainer.continueCrating = false return false end local request = { data.patternIndex, data.materialIndex, data.materialQuantity, data.itemStyleId, data.traitIndex + 1, data.useUniversalStyleItem } LeoTrainer.isCrafting = queueIndex CraftSmithingItem(unpack(request)) return true end function LeoTrainer.CraftNext() local list = LeoTrainer.GetQueue() for index, data in ipairs(list) do if data.craft == LeoTrainer.inStation and LeoTrainer.IKnowTrait(data.craft, data.line, data.trait) == true then LeoTrainer.CraftItem(index, data) return end end LeoTrainer.log("Nothing more to craft at this station.") LeoTrainer.isCrafting = 0 LeoTrainer.continueCrating = false end function LeoTrainer.stationEnter(eventcode, station) if station ~= CRAFTING_TYPE_BLACKSMITHING and station ~= CRAFTING_TYPE_WOODWORKING and station ~= CRAFTING_TYPE_CLOTHIER and station ~= CRAFTING_TYPE_JEWELRYCRAFTING then return end LeoTrainer.inStation = station LeoTrainer.queueScroll:RefreshData() LeoTrainerWindowQueuePanelQueueScrollCraftNext:SetState(BSTATE_NORMAL) LeoTrainerWindowQueuePanelQueueScrollCraftAll:SetState(BSTATE_NORMAL) LeoTrainer.GetPatternIndexes(station) local namesToPatternIndexes = {} for patternIndex = 1, GetNumSmithingPatterns() do local _, name = GetSmithingPatternInfo(patternIndex) namesToPatternIndexes[name] = patternIndex end --[[for line = 1, GetNumSmithingResearchLines(station) do local lineName, lineIcon, numTraits = GetSmithingResearchLineInfo(station, line) local patternIndex = namesToPatternIndexes[lineName] local _, _, matReq = GetSmithingPatternMaterialItemInfo(patternIndex, 1) d(line.." "..lineName.." "..patternIndex.." "..matReq) for trait = 1, numTraits do local traitType = GetSmithingResearchLineTraitInfo(station, line, trait) local traitName = GetString('SI_ITEMTRAITTYPE', traitType) --local styleId = maxStyle(lineId) --local requestResult = { -- patternIndex, -- 1, -- matReq, -- styleId, -- traitType + 1, -- LINK_STYLE_BRACKETS --} --d(GetSmithingPatternResultLink(unpack(requestResult)) .. "{line="..line..", patternIndex="..patternIndex..", materialIndex=1, materialQuantity="..matReq..", itemStyleId="..styleId..", trait="..trait..", traitType="..traitType.."} -- " .. lineName .. " " .. traitName) end end]] end function LeoTrainer.stationExit(eventcode, station) if station ~= CRAFTING_TYPE_BLACKSMITHING and station ~= CRAFTING_TYPE_WOODWORKING and station ~= CRAFTING_TYPE_CLOTHIER and station ~= CRAFTING_TYPE_JEWELRYCRAFTING then return end LeoTrainerWindowQueuePanelQueueScrollCraftNext:SetState(BSTATE_DISABLED) LeoTrainerWindowQueuePanelQueueScrollCraftAll:SetState(BSTATE_DISABLED) LeoTrainer.inStation = 0 LeoTrainer.queueScroll:RefreshData() LeoTrainer.HideUI() end function LeoTrainer.isTrackingSkill(charName, craftId) return LeoTrainer.savedVariables.trackedTraits[charName][craftId] end function LeoTrainer.setTrackingSkill(charName, craftId, tracking) LeoTrainer.savedVariables.trackedTraits[charName][craftId] = tracking end function LeoTrainer.canFillSlotWithSkill(charName, craftId) return LeoTrainer.savedVariables.fillSlot[charName][craftId] end function LeoTrainer.setFillSlotWithSkill(charName, craftId, tracking) LeoTrainer.savedVariables.fillSlot[charName][craftId] = tracking end function LeoTrainer.Initialize() LeoTrainer.savedVariables = ZO_SavedVars:NewAccountWide("LeoTrainerSavedVariables", 1, nil, nil, GetWorldName()) if LeoTrainer.savedVariables.trackedTraits == nil then LeoTrainer.savedVariables.trackedTraits = {} end if not LeoTrainer.savedVariables.queue then LeoTrainer.savedVariables.queue = {} end if not LeoTrainer.savedVariables.fillSlot then LeoTrainer.savedVariables.fillSlot = {} end for i, char in ipairs(LeoAltholic.GetCharacters()) do if LeoTrainer.savedVariables.trackedTraits[char.bio.name] == nil then LeoTrainer.savedVariables.trackedTraits[char.bio.name] = {} end if not LeoTrainer.savedVariables.fillSlot[char.bio.name] then LeoTrainer.savedVariables.fillSlot[char.bio.name] = {} end for _, craftId in pairs(LeoAltholic.craftResearch) do LeoTrainer.savedVariables.trackedTraits[char.bio.name][craftId] = LeoTrainer.savedVariables.trackedTraits[char.bio.name][craftId] or false LeoTrainer.savedVariables.fillSlot[char.bio.name][craftId] = LeoTrainer.savedVariables.fillSlot[char.bio.name][craftId] or false end end local LibFeedback = LibStub:GetLibrary("LibFeedback") local showButton, feedbackWindow = LibFeedback:initializeFeedbackWindow(LeoTrainer, LeoTrainer.name,LeoTrainerWindow, "@LeandroSilva", {TOPRIGHT, LeoTrainerWindow, TOPRIGHT,-50,3}, {0,1000,10000,"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Y9KM4PZU2UZ6A"}, "If you found a bug, have a request or a suggestion, or simply wish to donate, send a mail.") LeoTrainer.feedback = feedbackWindow LeoTrainerWindowTitle:SetText(LeoTrainer.displayName .. " v" .. LeoTrainer.version) SLASH_COMMANDS["/leotrainer"] = function(cmd) LeoTrainer:ShowUI() end if GetDisplayName() == "@LeandroSilva" then SLASH_COMMANDS["/rr"] = function(cmd) ReloadUI() end end LeoTrainer.settings = LeoTrainer_Settings:New() LeoTrainer.settings:CreatePanel() LeoTrainer.launcher = LeoTrainer_Launcher:New() LeoTrainer.launcher:SetHidden(false) LeoTrainer.CreateUI() end function LeoTrainer.log(message) d(LeoTrainer.chatPrefix .. message) end local function OnSettingsControlsCreated(panel) LeoTrainer_Settings:OnSettingsControlsCreated(panel) end function LeoTrainer.OnAddOnLoaded(event, addonName) if addonName == LeoTrainer.name then EVENT_MANAGER:UnregisterForEvent(LeoTrainer.name, EVENT_ADD_ON_LOADED) SCENE_MANAGER:RegisterTopLevel(LeoTrainerWindow, false) LeoTrainer.Initialize() EVENT_MANAGER:RegisterForEvent(LeoTrainer.name, EVENT_CRAFTING_STATION_INTERACT, LeoTrainer.stationEnter) EVENT_MANAGER:RegisterForEvent(LeoTrainer.name, EVENT_END_CRAFTING_STATION_INTERACT, LeoTrainer.stationExit) EVENT_MANAGER:RegisterForEvent(LeoTrainer.name, EVENT_CRAFT_COMPLETED, LeoTrainer.OnCraftComplete) EVENT_MANAGER:RegisterForEvent(LeoTrainer.name, EVENT_CRAFT_FAILED, LeoTrainer.OnCraftFailed) CALLBACK_MANAGER:RegisterCallback("LAM-PanelControlsCreated", OnSettingsControlsCreated) LeoTrainer.log("started.") end end EVENT_MANAGER:RegisterForEvent(LeoTrainer.name, EVENT_ADD_ON_LOADED, LeoTrainer.OnAddOnLoaded)