diff --git a/Libs/LibOpenRaid/Functions.lua b/Libs/LibOpenRaid/Functions.lua index c8db2b63..6e083f23 100644 --- a/Libs/LibOpenRaid/Functions.lua +++ b/Libs/LibOpenRaid/Functions.lua @@ -52,6 +52,26 @@ function openRaidLib.PackTable(table) return newString end +function openRaidLib.PackTableAndSubTables(table) + local totalSize = 0 + local subTablesAmount = #table + for i = 1, subTablesAmount do + totalSize = totalSize + #table[i] + end + + local newString = "" .. totalSize .. "," + + for i = 1, subTablesAmount do + local subTable = table[i] + for subIndex = 1, #subTable do + newString = newString .. subTable[subIndex] .. "," + end + end + + newString = newString:gsub(",$", "") + return newString +end + --return is a number is almost equal to another within a tolerance range function openRaidLib.isNearlyEqual(value1, value2, tolerance) tolerance = tolerance or CONST_FRACTION_OF_A_SECOND @@ -64,10 +84,10 @@ function openRaidLib.IsCommAllowed() end --stract some indexes of a table -local selectIndexes = function(table, startIndex, amountIndexes) +local selectIndexes = function(table, startIndex, amountIndexes, zeroIfNil) local values = {} for i = startIndex, startIndex+amountIndexes do - values[#values+1] = tonumber(table[i]) or 0 + values[#values+1] = tonumber(table[i]) or (zeroIfNil and 0) or table[i] end return values end @@ -92,7 +112,7 @@ function openRaidLib.UnpackTable(table, index, isPair, valueIsTable, amountOfVal for i = indexStart, indexEnd, amountOfValues do if (valueIsTable) then local key = tonumber(table[i]) - local values = selectIndexes(table, i+1, max(amountOfValues-2, 1)) + local values = selectIndexes(table, i+1, max(amountOfValues-2, 1), true) result[key] = values else local key = tonumber(table[i]) @@ -101,12 +121,19 @@ function openRaidLib.UnpackTable(table, index, isPair, valueIsTable, amountOfVal end end else - for i = indexStart, indexEnd do - local value = tonumber(table[i]) - result[#result+1] = value + if (valueIsTable) then + for i = indexStart, indexEnd, amountOfValues do + local values = selectIndexes(table, i, amountOfValues - 1) + tinsert(result, values) + end + else + for i = indexStart, indexEnd do + local value = tonumber(table[i]) + result[#result+1] = value + end end end - + return result end @@ -400,4 +427,78 @@ function openRaidLib.GetFoodTierFromAura(auraInfo) end end return nil +end + +function openRaidLib.GearManager.BuildEquipmentItemLinks(equippedGearList) + equippedGearList = equippedGearList or {} --nil table for older versions + + for i = 1, #equippedGearList do + local equipmentTable = equippedGearList[i] + + --equippedGearList is a indexed table with 4 indexes: + local slotId = equipmentTable[1] + local numGemSlots = equipmentTable[2] + local itemLevel = equipmentTable[3] + local partialItemLink = equipmentTable[4] + + --get the itemId from the partial link to query the itemName with GetItemInfo + local itemId = partialItemLink:match("^%:(%d+)%:") + itemId = tonumber(itemId) + local itemName, _, itemQuality = GetItemInfo(itemId) + + --build the full item link + local itemLink = "|cFFEEEEEE|Hitem" .. partialItemLink .. "|h[" .. itemName .. "]|r" + + --use GetItemInfo again with the now completed itemLink to query the item color + local _, _, itemQuality = GetItemInfo(itemLink) + local qualityColor = ITEM_QUALITY_COLORS[itemQuality] + + --replace the item color + --local r, g, b, hex = GetItemQualityColor(qualityColor) + itemLink = itemLink:gsub("FFEEEEEE", qualityColor.color:GenerateHexColor()) + + wipe(equipmentTable) + + equipmentTable.slotId = slotId + equipmentTable.gemSlots = numGemSlots + equipmentTable.itemLevel = itemLevel + equipmentTable.itemLink = itemLink + equipmentTable.itemQuality = itemQuality + equipmentTable.itemId = itemId + equipmentTable.itemName = itemName + + local _, _, enchantId, gemId1, gemId2, gemId3, gemId4, suffixId, uniqueId, levelOfTheItem, specId, upgradeInfo, instanceDifficultyId, numBonusIds, restLink = strsplit(":", itemLink) + + local enchantAttribute = LIB_OPEN_RAID_ENCHANT_SLOTS[slotId] + local nEnchantId = 0 + if (enchantAttribute) then --this slot can receive an enchat + if (enchantId and enchantId ~= "") then + enchantId = tonumber(enchantId) + nEnchantId = enchantId + end + + --6400 and above is dragonflight enchantId number space + if (nEnchantId < 6300 and not LIB_OPEN_RAID_DEATHKNIGHT_RUNEFORGING_ENCHANT_IDS[nEnchantId]) then + nEnchantId = 0 + end + end + equipmentTable.enchantId = nEnchantId + + local nGemId = 0 + local gemsIds = {gemId1, gemId2, gemId3, gemId4} + + --check if the item has a socket + if (numGemSlots) then + --check if the socket is empty + for gemSlotId = 1, numGemSlots do + local gemId = tonumber(gemsIds[gemSlotId]) + if (gemId and gemId >= 180000) then + nGemId = gemId + break + end + end + end + + equipmentTable.gemId = nGemId + end end \ No newline at end of file diff --git a/Libs/LibOpenRaid/GetPlayerInformation.lua b/Libs/LibOpenRaid/GetPlayerInformation.lua index a6c6ac12..d09a74ad 100644 --- a/Libs/LibOpenRaid/GetPlayerInformation.lua +++ b/Libs/LibOpenRaid/GetPlayerInformation.lua @@ -340,7 +340,7 @@ function openRaidLib.GearManager.GetPlayerGemsAndEnchantInfo() local enchantAttribute = LIB_OPEN_RAID_ENCHANT_SLOTS[equipmentSlotId] local nEnchantId = 0 - if (enchantAttribute) then --this slot can receive an enchat + if (enchantAttribute) then --this slot can receive an enchant if (enchantId and enchantId ~= "") then local number = tonumber(enchantId) nEnchantId = number @@ -380,6 +380,54 @@ function openRaidLib.GearManager.GetPlayerGemsAndEnchantInfo() return slotsWithoutGems, slotsWithoutEnchant end +function openRaidLib.GearManager.BuildPlayerEquipmentList() + local equipmentList = {} + local debug + for equipmentSlotId = 1, 17 do + local itemLink = GetInventoryItemLink("player", equipmentSlotId) + if (itemLink) then + local itemStatsTable = {} + local itemID, enchantID, gemID1, gemID2, gemID3, gemID4, suffixID, uniqueID, linkLevel, specializationID, modifiersMask, itemContext = select(2, strsplit(":", itemLink)) + itemID = tonumber(itemID) + + GetItemStats(itemLink, itemStatsTable) + local gemSlotsAvailable = itemStatsTable and itemStatsTable.EMPTY_SOCKET_PRISMATIC or 0 + local _, _, _, itemLevel = GetItemInfo(itemLink) + + local noPrefixItemLink = itemLink : gsub("^|c%x%x%x%x%x%x%x%x|Hitem", "") + local linkTable = {strsplit(":", noPrefixItemLink)} + local numModifiers = linkTable[14] + numModifiers = numModifiers and tonumber(numModifiers) or 0 + + for i = #linkTable, 14 + numModifiers + 1, -1 do + tremove(linkTable, i) + end + + local newItemLink = table.concat(linkTable, ":") + newItemLink = newItemLink + equipmentList[#equipmentList+1] = {equipmentSlotId, gemSlotsAvailable, itemLevel, newItemLink} + + if (equipmentSlotId == 2) then + debug = {itemLink:gsub("|H", ""), newItemLink} + end + end + end + + --[[ debug + local str = "" + for i = 1, #equipmentList do + local t = equipmentList[i] + local s = t[1] .. "," .. t[2] .. "," .. t[3] .. "," .. t[4] + str = str .. s + end + + table.insert(debug, str) + dumpt(debug) + --]] + + return equipmentList +end + local playerHasPetOfNpcId = function(npcId) if (UnitExists("pet") and UnitHealth("pet") >= 1) then local guid = UnitGUID("pet") diff --git a/Libs/LibOpenRaid/LibOpenRaid.lua b/Libs/LibOpenRaid/LibOpenRaid.lua index e8541f42..9a7e1b4e 100644 --- a/Libs/LibOpenRaid/LibOpenRaid.lua +++ b/Libs/LibOpenRaid/LibOpenRaid.lua @@ -64,7 +64,7 @@ if (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE and not isExpansion_Dragonflight()) t end local major = "LibOpenRaid-1.0" -local CONST_LIB_VERSION = 84 +local CONST_LIB_VERSION = 85 if (not LIB_OPEN_RAID_MAX_VERSION) then LIB_OPEN_RAID_MAX_VERSION = CONST_LIB_VERSION @@ -1584,6 +1584,9 @@ openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.UnitI --enchants and gems local slotsWithoutGems, slotsWithoutEnchant = openRaidLib.GearManager.GetPlayerGemsAndEnchantInfo() + --full gear list {{slotId, gemAmount, itemLevel, itemLink}, {slotId, gemAmount, itemLevel, itemLink}, } + local equippedGearList = openRaidLib.GearManager.BuildPlayerEquipmentList() + --build the table with the gear information local playerGearInfo = {} playerGearInfo[#playerGearInfo+1] = itemLevel --[1] - one index @@ -1591,12 +1594,13 @@ openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.UnitI playerGearInfo[#playerGearInfo+1] = weaponEnchant --[3] - one index playerGearInfo[#playerGearInfo+1] = slotsWithoutEnchant --[4] - undefined playerGearInfo[#playerGearInfo+1] = slotsWithoutGems --[5] - undefined + playerGearInfo[#playerGearInfo+1] = equippedGearList --[6] - undefined return playerGearInfo end --when received the gear update from another player, store it and trigger a callback - function openRaidLib.GearManager.AddUnitGearList(unitName, itemLevel, durability, weaponEnchant, noEnchantTable, noGemsTable) + function openRaidLib.GearManager.AddUnitGearList(unitName, itemLevel, durability, weaponEnchant, noEnchantTable, noGemsTable, equippedGearList) local unitGearInfo = openRaidLib.GearManager.GetUnitGear(unitName, true) unitGearInfo.ilevel = itemLevel @@ -1605,6 +1609,11 @@ openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.UnitI unitGearInfo.noGems = noGemsTable unitGearInfo.noEnchants = noEnchantTable + --parse and replace the 'equippedGearList' + openRaidLib.GearManager.BuildEquipmentItemLinks(equippedGearList) + + unitGearInfo.equippedGear = equippedGearList + openRaidLib.publicCallback.TriggerCallback("GearUpdate", openRaidLib.GetUnitID(unitName), unitGearInfo, openRaidLib.GearManager.GetAllUnitsGear()) end @@ -1612,30 +1621,39 @@ openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.UnitI --@data: table received from comm --@unitName: player name function openRaidLib.GearManager.OnReceiveGearFullInfo(data, unitName) - local itemLevel = tonumber(data[1]) - local durability = tonumber(data[2]) - local weaponEnchant = tonumber(data[3]) + local itemLevel = tonumber(data[1]) --1 index + local durability = tonumber(data[2]) --1 index + local weaponEnchant = tonumber(data[3]) --1 index + local noEnchantTableSize = tonumber(data[4]) - local noGemsTableIndex = tonumber(noEnchantTableSize + 5) + local noGemsTableIndex = tonumber(noEnchantTableSize + 5) --5 is the three first indexes, the enchant table size and +1 to jump to next index local noGemsTableSize = data[noGemsTableIndex] + local equippedGearListIndex = tonumber(noEnchantTableSize + noGemsTableSize + 6) --6 is the same has the 5 but +1 index for the gems table size + --local equippedGearListSize = data[noGemsTableIndex] + --unpack the enchant data as a ipairs table local noEnchantTableUnpacked = openRaidLib.UnpackTable(data, 4, false, false, noEnchantTableSize) --unpack the enchant data as a ipairs table local noGemsTableUnpacked = openRaidLib.UnpackTable(data, noGemsTableIndex, false, false, noGemsTableSize) + --unpack the full gear + local equippedGearListUnpacked = equippedGearListIndex and openRaidLib.UnpackTable(data, equippedGearListIndex, false, true, 4) or {} --add to the list of gear information - openRaidLib.GearManager.AddUnitGearList(unitName, itemLevel, durability, weaponEnchant, noEnchantTableUnpacked, noGemsTableUnpacked) + openRaidLib.GearManager.AddUnitGearList(unitName, itemLevel, durability, weaponEnchant, noEnchantTableUnpacked, noGemsTableUnpacked, equippedGearListUnpacked) end openRaidLib.commHandler.RegisterComm(CONST_COMM_GEARINFO_FULL_PREFIX, openRaidLib.GearManager.OnReceiveGearFullInfo) + --todo: on changing an item in the inventory, send an update only for the slot that got changed + function openRaidLib.GearManager.SendAllGearInfo() - --get gear information, gear info has 5 indexes: + --get gear information, gear info has 6 indexes: --[1] int item level --[2] int durability --[3] int weapon enchant --[4] table with integers of equipSlot without enchant --[5] table with integers of equipSlot which has a gem slot but the slot is empty + --[6] table with all gear from the player local dataToSend = "" .. CONST_COMM_GEARINFO_FULL_PREFIX .. "," local playerGearInfo = openRaidLib.GearManager.GetPlayerFullGearInfo() @@ -1647,7 +1665,8 @@ openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.UnitI dataToSend = dataToSend .. playerGearInfo[2] .. "," --durability dataToSend = dataToSend .. playerGearInfo[3] .. "," --weapon enchant dataToSend = dataToSend .. openRaidLib.PackTable(playerGearInfo[4]) .. "," --slots without enchant - dataToSend = dataToSend .. openRaidLib.PackTable(playerGearInfo[5]) -- slots with empty gem sockets + dataToSend = dataToSend .. openRaidLib.PackTable(playerGearInfo[5]) .. "," -- slots with empty gem sockets + dataToSend = dataToSend .. openRaidLib.PackTableAndSubTables(playerGearInfo[6]) --full equipped equipment --send the data openRaidLib.commHandler.SendCommData(dataToSend) @@ -2286,216 +2305,12 @@ end function openRaidLib.CooldownManager.OnReceiveUnitCooldowns(data, unitName) --unpack the table as a pairs table local unpackedTable = openRaidLib.UnpackTable(data, 1, true, true, CONST_COOLDOWN_INFO_SIZE) - --local unpackedTable = openRaidLib.UnpackTable(data, 1, true, true, 5) - --dumpt(unpackedTable) --add the list of cooldowns openRaidLib.CooldownManager.AddUnitCooldownsList(unitName, unpackedTable) end openRaidLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNFULLLIST_PREFIX, openRaidLib.CooldownManager.OnReceiveUnitCooldowns) ---debug data clean up on next version - ---[=[]] received data -["1"] = "72", --72 indexes -["2"] = "7744", -["3"] = "0", -["4"] = "1", -["5"] = "0", -["6"] = "0", -["7"] = "0", -["8"] = "586", -["9"] = "0", -["10"] = "1", -["11"] = "0", -["12"] = "0", -["13"] = "0", -["14"] = "10060", -["15"] = "0", -["16"] = "1", -["17"] = "0", -["18"] = "0", -["19"] = "0", -["20"] = "8122", -["21"] = "0", -["22"] = "1", -["23"] = "0", -["24"] = "0", -["25"] = "0", -["26"] = "15286", -["27"] = "0", -["28"] = "1", -["29"] = "0", -["30"] = "0", -["31"] = "0", -["32"] = "64901", -["33"] = "0", -["34"] = "1", -["35"] = "0", -["36"] = "0", -["37"] = "0", -["38"] = "19236", -["39"] = "0", -["40"] = "1", -["41"] = "0", -["42"] = "0", -["43"] = "0", -["44"] = "32375", -["45"] = "0", -["46"] = "1", -["47"] = "0", -["48"] = "0", -["49"] = "0", -["50"] = "34433", -["51"] = "0", -["52"] = "1", -["53"] = "0", -["54"] = "0", -["55"] = "0", -["56"] = "64843", -["57"] = "0", -["58"] = "1", -["59"] = "0", -["60"] = "0", -["61"] = "0", -["62"] = "265202", -["63"] = "0", -["64"] = "1", -["65"] = "0", -["66"] = "0", -["67"] = "0", -["68"] = "47788", -["69"] = "0", -["70"] = "1", -["71"] = "0", -["72"] = "0", -["73"] = "0", ---]=] - ---[=[ -unpack data with 5 indexes: -[1] = { --1 spellID - word of recall - ["1"] = 0, - ["2"] = 0, - ["3"] = 0, - ["4"] = 64843, --divine hymm spellID -}, -[7744] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, -}, -[265202] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, -}, -[64901] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, -}, -[0] = { --0 spellID - ["1"] = 0, - ["2"] = 0, - ["3"] = 0, - ["4"] = 0, -}, ---]=] - ---[=[ unpacked data with 6 indexes, matches -[7744] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[586] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[10060] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[32375] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[15286] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[64901] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[19236] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[47788] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[265202] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[64843] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[34433] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, -[8122] = { - ["1"] = 0, - ["2"] = 1, - ["3"] = 0, - ["4"] = 0, - ["5"] = 0, -}, - ---]=] - - - --send a comm requesting other units in the raid to send an update on the requested spell --any unit in the raid that has this cooldown should send a CONST_COMM_COOLDOWNUPDATE_PREFIX --@spellId: spellId to query @@ -2775,27 +2590,6 @@ openRaidLib.commHandler.RegisterComm(CONST_COMM_COOLDOWNREQUEST_PREFIX, openRaid openRaidLib.internalCallback.RegisterCallback("onEnterGroup", openRaidLib.KeystoneInfoManager.OnPlayerEnterGroup) openRaidLib.internalCallback.RegisterCallback("mythicDungeonEnd", openRaidLib.KeystoneInfoManager.OnMythicDungeonFinished) - ---DEBUG TEST ---[=[ -local ff = {} -function ff.OnKSUpdate(unitId, keystoneInfo, allKeystonesInfo) - print(unitId, keystoneInfo, allKeystonesInfo) - print(keystoneInfo.level, keystoneInfo.mapID, keystoneInfo.challengeMapID) -end -openRaidLib.RegisterCallback(ff, "KeystoneUpdate", "OnKSUpdate") - -C_Timer.After(7, function() - openRaidLib.GetAllKeystonesInfo() - print("> ", openRaidLib.GetKeystoneInfo("player")) - - openRaidLib.RequestKeystoneDataFromGuild() - openRaidLib.RequestKeystoneDataFromParty() - openRaidLib.RequestKeystoneDataFromRaid() -end) ---]=] - - -------------------------------------------------------------------------------------------------------------------------------- --data