diff --git a/.gitignore b/.gitignore index 3fa3560..04cf002 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ IIfA/.idea/dictionaries/P.xml IIfA/.idea/misc.xml IIfA/.idea/modules.xml IIfA/.idea/workspace.xml +assets/ \ No newline at end of file diff --git a/IIfA/IIfABackpack.lua b/IIfA/IIfABackpack.lua index 2f4a9c7..c9472b1 100644 --- a/IIfA/IIfABackpack.lua +++ b/IIfA/IIfABackpack.lua @@ -757,6 +757,8 @@ p("OnChestSelect '<<1>>' - <<2>>", choiceText, choice) if cName == self.EMPTY_STRING then cName = GetCollectibleName(cId) end + --remove gender specific characters from house bank chest name + cName = zo_strformat("<<C:1>>", cName) if cName == choiceText then IIfA:SetInventoryListFilter("Housing Storage", ctr) break @@ -788,6 +790,8 @@ p("OnChestSelect '<<1>>' - <<2>>", choiceText, choice) if cName == self.EMPTY_STRING then cName = GetCollectibleName(cId) end + --remove gender specific characters from house bank chest name + cName = zo_strformat("<<C:1>>", cName) entry = comboBox:CreateItemEntry(cName, OnChestSelect) comboBox:AddItem(entry) end diff --git a/IIfA/IIfADataCollection.lua b/IIfA/IIfADataCollection.lua index 84d0d48..2f4f935 100644 --- a/IIfA/IIfADataCollection.lua +++ b/IIfA/IIfADataCollection.lua @@ -80,8 +80,7 @@ function IIfA:CollectGuildBank(curGuild) end end - SelectGuildBank(CurGB) - local count = 0 + SelectGuildBank(curGB) if(IIfA.data.guildBanks[curGuild] == nil) then IIfA.data.guildBanks[curGuild] = {} @@ -95,7 +94,7 @@ function IIfA:CollectGuildBank(curGuild) IIfA.BagSlotInfo = IIfA.BagSlotInfo or {} p("Collect guild bank - <<1>>", curGuild) local guildData = IIfA.data.guildBanks[curGuild] - local itemCount, i, slotIndex + local itemCount, slotIndex itemCount = 0 slotIndex = ZO_GetNextBagSlotIndex(BAG_GUILDBANK, nil) while slotIndex do @@ -105,7 +104,6 @@ function IIfA:CollectGuildBank(curGuild) p("GuildBank Item Count = " .. itemCount) --- guildData.items = #ZO_GuildBankBackpack.data guildData.lastCollected = GetDate() .. "@" .. GetFormattedTime(); IIfA:ClearLocationData(curGuild) @@ -122,12 +120,10 @@ function IIfA:CollectGuildBank(curGuild) IIfA.BagSlotInfo[curGuild][slotIndex] = itemKey slotIndex = ZO_GetNextBagSlotIndex(BAG_GUILDBANK, slotIndex) end + p("IIfA - Guild Bank Collected - " .. curGuild .. ", itemCount=" .. itemCount) end) - p("IIfA - Guild Bank Collected - " .. curGuild .. ", itemCount=" .. itemCount) end - - function IIfA:ScanCurrentCharacter() local playerName = GetUnitName('player') @@ -308,12 +304,15 @@ function IIfA:GuildBankAddRemove(eventID, slotId) end) end - +function IIfA:IgnoreHouse(houseCollectibleId) + houseCollectibleId = houseCollectibleId or GetCollectibleIdForHouse(GetCurrentZoneHouseId()) +end function IIfA:RescanHouse(houseCollectibleId) houseCollectibleId = houseCollectibleId or GetCollectibleIdForHouse(GetCurrentZoneHouseId()) if not houseCollectibleId or not IIfA.trackedBags[houseCollectibleId] then return end - + + -- if GetHouseCategoryType(GetCurrentZoneHouseId()) == HOUSE_CATEGORY_TYPE_NOTABLE then return end IIfA.data.collectHouseData[houseCollectibleId] = IIfA.data.collectHouseData[houseCollectibleId] or IIfA:GetHouseTracking() if not IIfA.data.collectHouseData[houseCollectibleId] then @@ -324,33 +323,42 @@ function IIfA:RescanHouse(houseCollectibleId) IIfA.trackedBags[houseCollectibleId] = true end + -- TODO: Debug this --- stuff them all into an array local function getAllPlacedFurniture() local ret = {} + local counter = 1 + local furnitureId = nil while(true) do - local furnitureId = GetNextPlacedHousingFurnitureId(furnitureId) - if(not furnitureId) then return ret end + furnitureId = GetNextPlacedHousingFurnitureId(furnitureId) + if (not furnitureId or counter > 10000 ) then return ret end local itemLink = GetPlacedFurnitureLink(furnitureId, LINK_STYLE_BRACKETS) - if not ret[itemLink] then - ret[itemLink] = 1 - else - ret[itemLink] = ret[itemLink] + 1 - end + -- if not ret[itemLink] then + -- ret[itemLink] = 1 + -- else + ret[itemLink] = ( ret[itemLink] or 1 ) + 1 + -- end + counter = counter + 1 end + return ret end + + IIfA.getAllPlacedFurniture = getAllPlacedFurniture -- call with libAsync to avoid lag task:Call(function() -- clear and re-create, faster than conditionally updating IIfA:ClearLocationData(houseCollectibleId) --- end):Then(function() - for itemLink, itemCount in pairs(getAllPlacedFurniture()) do + + + end):Then(function() -- TODO - can this go again? Having it in here at least prevented the crash + local placedFurniture = getAllPlacedFurniture() + for itemLink, itemCount in pairs(placedFurniture) do -- (bagId, slotId, fromXfer, itemCount, itemLink, itemName, locationID) p("furniture item <<1>> x<<2>>", itemLink, itemCount) IIfA:EvalBagItem(houseCollectibleId, tonumber(IIfA_GetItemID(itemLink)), false, itemCount, itemLink, GetItemLinkName(itemLink), houseCollectibleId) end end) - end -- try to read item name from bag/slot - if that's empty, we read it from item link @@ -452,6 +460,7 @@ function IIfA:EvalBagItem(bagId, slotId, fromXfer, qty, itemLink, itemName, loca -- item count is either passed or we have to get it from bag/slot ID or item link local bAddQty = false if qty ~= nil then bAddQty = true end + local itemCount = qty or getItemCount(bagId, slotId, itemLink) --p("trying to save <<1>> x<<2>>", itemLink, itemCount) @@ -697,12 +706,9 @@ function IIfA:ClearLocationData(location, bagID) -- if loc is characterid, bagI local itemLocation = nil local LocationCount = 0 local itemName, itemData - local bChar - if bagID == nil then - bChar = nil - else - bChar = location == IIfA.currentCharacterId - end + + local bChar = (bagID == nil and nil) or location == IIfA.currentCharacterId + if(DBv3)then p(zo_strformat("IIfA:ClearLocationData(<<1>>, <<2>>)", location, bagID)) diff --git a/IIfA/IIfAEvents.lua b/IIfA/IIfAEvents.lua index d0f29a6..b190a01 100644 --- a/IIfA/IIfAEvents.lua +++ b/IIfA/IIfAEvents.lua @@ -154,7 +154,7 @@ local function fgb4(...) IIfA_EventDump(...) end local function fgb5(...) - d("gb items ready") + d("inventory fragment state change") IIfA_EventDump(...) end @@ -206,6 +206,7 @@ function IIfA:RegisterForEvents() -- ZO_QuickSlot:RegisterForEvent(EVENT_ABILITY_COOLDOWN_UPDATED, IIfA_EventDump) ZO_PreHook('ZO_InventorySlot_ShowContextMenu', function(rowControl) IIfA:ProcessRightClick(rowControl) end) + end diff --git a/IIfA/IIfASceneFuncs.lua b/IIfA/IIfASceneFuncs.lua index e58fbe8..8999738 100644 --- a/IIfA/IIfASceneFuncs.lua +++ b/IIfA/IIfASceneFuncs.lua @@ -37,22 +37,34 @@ function IIfA:RegisterForSceneChanges() end end end + + INVENTORY_FRAGMENT:RegisterCallback("StateChange", function(...) + IIfA:ProcessInventoryTabChange("", ...) + end) + CRAFT_BAG_FRAGMENT:RegisterCallback("StateChange", function(...) + IIfA:ProcessInventoryTabChange("", ...) + end) + WALLET_FRAGMENT:RegisterCallback("StateChange", function(...) + IIfA:ProcessInventoryTabChange("", ...) + end) + QUICKSLOT_FRAGMENT:RegisterCallback("StateChange", function(...) + IIfA:ProcessInventoryTabChange("_quickSlots", ...) + end) end function IIfA:GetSceneSettings(sceneName) sceneName = sceneName or IIfA:GetCurrentSceneName() - - local settings = IIfA:GetSettings().frameSettings - if not settings[sceneName] then -- if we have to create a new set of scene info, register it in the scene change too, it'll be set again during next opening local scene = SCENE_MANAGER:GetScene(sceneName) - scene:RegisterCallback("StateChange", function(...) - IIfA:ProcessSceneChange(sceneName, ...) - end) + if scene then + scene:RegisterCallback("StateChange", function(...) + IIfA:ProcessSceneChange(sceneName, ...) + end) + end -- save the settings in the settings table, base it on HUD settings[sceneName] = ZO_DeepTableCopy(settings["hud"]) settings[sceneName].hidden = true @@ -68,6 +80,23 @@ function IIfA:ProcessSceneChange(sceneName, oldState, newState) -- IIfA:DebugOut(zo_strformat("ProcessSceneChange <<1>>: <<2>> -> <<3>>", sceneName, oldState, newState)) if SCENE_SHOWN == newState then sceneName = IIfA:GetCurrentSceneName() + if sceneName == "inventory" then + if not QUICKSLOT_FRAGMENT:IsHidden() then + sceneName = sceneName .. "_quickslots" + end + end + local settings = IIfA:GetSceneSettings(sceneName) + self:RePositionFrame(settings) + elseif SCENE_HIDDEN == newState then + IIFA_GUI:SetHidden(true) + end +end + + +function IIfA:ProcessInventoryTabChange(tabName, oldState, newState) + -- IIfA:DebugOut(zo_strformat("ProcessSceneChange <<1>>: <<2>> -> <<3>>", oldState, newState)) + if newState == SCENE_SHOWN then + sceneName = "inventory" .. tabName local settings = IIfA:GetSceneSettings(sceneName) self:RePositionFrame(settings) @@ -81,6 +110,10 @@ function IIfA:SaveFrameInfo(calledFrom) if (calledFrom == "onHide") then return end local sceneName = IIfA:GetCurrentSceneName() + if not QUICKSLOT_FRAGMENT:IsHidden() then + sceneName = sceneName .. "_quickslots" + end + local settings = IIfA:GetSceneSettings(sceneName) settings.hidden = IIFA_GUI:IsControlHidden() @@ -95,7 +128,7 @@ function IIfA:SaveFrameInfo(calledFrom) end end --- called only from bindings.xml on keypress +-- called from bindings.xml on keypress, and on /iifa toggle chat cmd function IIfA:ToggleInventoryFrame() IIFA_GUI:SetHidden(not IIFA_GUI:IsControlHidden()) if not IIFA_GUI:IsControlHidden() then diff --git a/IIfA/IIfASettingsAdapter.lua b/IIfA/IIfASettingsAdapter.lua index 1bb55f6..7143a8b 100644 --- a/IIfA/IIfASettingsAdapter.lua +++ b/IIfA/IIfASettingsAdapter.lua @@ -137,7 +137,10 @@ end function IIfA:GetTrackingWithHouseNames() local ret = {} for collectibleId, trackIt in pairs(IIfA.data.collectHouseData) do - ret[GetCollectibleName(collectibleId)] = true + local collectibleName = GetCollectibleName(collectibleId) + --remove gender specific characters from house name + collectibleName = zo_strformat("<<C:1>>", collectibleName) + ret[collectibleName] = true end return ret end @@ -147,6 +150,8 @@ function IIfA:RebuildHouseMenuDropdowns() local ignored = {} for collectibleId, trackIt in pairs(IIfA.data.collectHouseData) do local collectibleName = GetCollectibleName(collectibleId) + --remove gender specific characters from house name + collectibleName = zo_strformat("<<C:1>>", collectibleName) -- cache house name for lookup IIfA.houseNameToIdTbl[collectibleName] = collectibleId local targetTable = (trackIt and tracked) or ignored @@ -155,12 +160,14 @@ function IIfA:RebuildHouseMenuDropdowns() IIfA.houseNamesIgnored = ignored IIfA.houseNamesTracked = tracked end + function IIfA:GetIgnoredHouseNames() if nil == IIfA.houseNamesIgnored then IIfA:RebuildHouseMenuDropdowns() end return IIfA.houseNamesIgnored end + function IIfA:GetTrackedHouseNames() if nil == IIfA.houseNamesIgnored then IIfA:RebuildHouseMenuDropdowns() @@ -175,6 +182,7 @@ function IIfA:GetAllHouseIds() end return ret end + function IIfA:SetTrackingForHouse(houseCollectibleId, trackIt) houseCollectibleId = houseCollectibleId or GetCollectibleIdForHouse(GetCurrentZoneHouseId()) if tonumber(houseCollectibleId) ~= houseCollectibleId then diff --git a/IIfA/IIfA_xml_adapter.lua b/IIfA/IIfA_xml_adapter.lua index 51f7818..c04e0c7 100644 --- a/IIfA/IIfA_xml_adapter.lua +++ b/IIfA/IIfA_xml_adapter.lua @@ -508,7 +508,7 @@ function IIfA:RePositionFrame(settings) if bMinimize then IIFA_GUI:SetResizeHandleSize(0) -- have to change the constraints, it even constrains resizing by code, not just resize by sizing handles - IIFA_GUI:SetDimensionConstraints(IIfA.minWidth, 33, -1, 1400) + IIFA_GUI:SetDimensionConstraints(IIfA.minWidth, 44, -1, 1400) IIFA_GUI:SetHeight(33) IIFA_GUI:SetWidth(settings.width) diff --git a/IIfA/libs/LibAsync/LibAsync.lua b/IIfA/libs/LibAsync/LibAsync.lua index 77100f0..8127aec 100644 --- a/IIfA/libs/LibAsync/LibAsync.lua +++ b/IIfA/libs/LibAsync/LibAsync.lua @@ -1,4 +1,4 @@ -local MAJOR, MINOR = "LibAsync", 1.4 +local MAJOR, MINOR = "LibAsync", 1.7 local async, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not async then return end -- the same or newer version of this lib is already loaded into memory @@ -48,7 +48,7 @@ local function DoJob(job) if call then DoCallback(job, index) else - assert(index == 0, "No call on non-empty stack?!") + -- assert(index == 0, "No call on non-empty stack?!") jobs[job.name] = nil call = job.finally if call then pcall(safeCall) end @@ -57,27 +57,33 @@ local function DoJob(job) end -- time we can spend until the next frame must be shown -local frameTimeTarget = 13 +local frameTimeTarget = GetCVar("VSYNC") == "1" and 14 or(tonumber(GetCVar("MinFrameTime.2")) * 1000) + -- we allow a function to use 25% of the frame time before it gets critical local spendTimeDef = frameTimeTarget * 0.75 -local spendTimeDefNoHUD = spendTimeDef * 1.54 +local spendTimeDefNoHUD = 15 local spendTime = spendTimeDef local debug = false +local running local GetFrameTimeMilliseconds, GetGameTimeMilliseconds = GetFrameTimeMilliseconds, GetGameTimeMilliseconds -local identifier = "ASYNCTASKS_JOBS" local function GetThreshold() return(HUD_SCENE:IsShowing() or HUD_UI_SCENE:IsShowing()) and spendTimeDef or spendTimeDefNoHUD end local job = nil +local cpuLoad = 0 +local name local function Scheduler() + if not running then return end + + job = nil local start = GetFrameTimeMilliseconds() - local runTime = start - if (GetGameTimeMilliseconds() - start) > spendTime then - spendTime = 750 / GetFramerate() + local runTime, cpuLoad = start, GetGameTimeMilliseconds() - start + if cpuLoad > spendTime then + spendTime = math.min(30, spendTime + spendTime * 0.02) if debug then df("initial gap: %ims. skip. new threshold: %ims", GetGameTimeMilliseconds() - start, spendTime) end @@ -86,26 +92,27 @@ local function Scheduler() if debug then df("initial gap: %ims", GetGameTimeMilliseconds() - start) end - local name while (GetGameTimeMilliseconds() - start) <= spendTime do - name, job = next(jobs) + name, job = next(jobs, name) + if not job then name, job = next(jobs) end if job then runTime = GetGameTimeMilliseconds() DoJob(job) + spendTime = spendTime - 0.001 else -- Finished - em:UnregisterForUpdate(identifier) + running = false spendTime = GetThreshold() - return + return end end - spendTime = GetThreshold() + -- spendTime = GetThreshold() if debug and job then local now = GetGameTimeMilliseconds() local freezeTime = now - start if freezeTime >= 16 then runTime = now - runTime - df("%s freeze. used %ims, resulting frametime %ims.", job.name, runTime, freezeTime) + df("%s freeze. allowed: %ims, used %ims, resulting fps %i.", job.name, spendTime, runTime, 1000 / freezeTime) end end end @@ -118,6 +125,10 @@ function async:SetDebug(enabled) debug = enabled end +function async:GetCpuLoad() + return cpuLoad / frameTimeTarget +end + -- Class task local task = async.task or ZO_Object:Subclass() @@ -139,8 +150,8 @@ end -- Resume the execution context. function task:Resume() + running = true jobs[self.name] = self - em:RegisterForUpdate(identifier, 0, Scheduler) return self end @@ -174,7 +185,7 @@ do local insert = table.insert -- Continue your task context execution with the given FuncOfTask after the previous as finished. function task:Then(funcOfTask) - assert(self.lastCallIndex > 0 and self.lastCallIndex <= #self.callstack, "cap!") + -- assert(self.lastCallIndex > 0 and self.lastCallIndex <= #self.callstack, "cap!") insert(self.callstack, self.lastCallIndex, funcOfTask) return self end @@ -338,3 +349,22 @@ end -- async.BREAK is the new 'break' for breaking loops. As Lua would not allowed the keyword 'break' in that context. -- To break a for-loop, return async.BREAK async.BREAK = true + +local function stateChange(oldState, newState) + if newState == SCENE_SHOWN or newState == SCENE_HIDING then + spendTime = GetThreshold() + end +end + +local identifier = "ASYNCTASKS_JOBS" + +HUD_SCENE:RegisterCallback("StateChange", stateChange) +HUD_UI_SCENE:RegisterCallback("StateChange", stateChange) + +function async:Unload() + HUD_SCENE:UnregisterCallback("StateChange", stateChange) + HUD_UI_SCENE:UnregisterCallback("StateChange", stateChange) +end + +em:UnregisterForUpdate(identifier) +em:RegisterForUpdate(identifier, 0, Scheduler)