From cb4b08d0d52ed13d0278fa5d93e5817c0ed09442 Mon Sep 17 00:00:00 2001 From: Dave Date: Fri, 15 Mar 2024 17:18:21 +0100 Subject: [PATCH] Fix issues with target acquisition and improve some display options --- FreshShit/RaiderlosSA/init.lua | 204 ++++++++++++++++++++++++++++----- 1 file changed, 174 insertions(+), 30 deletions(-) diff --git a/FreshShit/RaiderlosSA/init.lua b/FreshShit/RaiderlosSA/init.lua index 4b48cd1..444024c 100644 --- a/FreshShit/RaiderlosSA/init.lua +++ b/FreshShit/RaiderlosSA/init.lua @@ -1037,24 +1037,152 @@ CLEUParser = { } GUIDUnitMap = {} +PlayerName = UnitName("player") +-- Indices are class ids +---@alias ClassColor {className: string, color: {rgbInt: table, rgbHex: table}, rgbString: string} +---@type table +ClassColors = { + { + className = "Warrior", + color = { + rgbInt = { 198, 155, 109 }, + rgbHex = { 0.78, 0.61, 0.43 }, + }, + rgbString = "C69B6D", + }, + { + className = "Paladin", + color = { + rgbInt = { 244, 140, 186 }, + rgbHex = { 0.96, 0.55, 0.73 }, + }, + rgbString = "F48CBA", + }, + { + className = "Hunter", + color = { + rgbInt = { 170, 211, 114 }, + rgbHex = { 0.67, 0.83, 0.45 }, + }, + rgbString = "AAD372", + }, + { + className = "Rogue", + color = { + rgbInt = { 255, 244, 104 }, + rgbHex = { 1.00, 0.96, 0.41 }, + }, + rgbString = "FFF468", + }, + { + className = "Priest", + color = { + rgbInt = { 255, 255, 255 }, + rgbHex = { 1.00, 1.00, 1.00 }, + }, + rgbString = "FFFFFF", + }, + { + className = "Death Knight", + color = { + rgbInt = { 196, 30, 58 }, + rgbHex = { 0.77, 0.12, 0.23 }, + }, + rgbString = "C41E3A", + }, + { + className = "Shaman", + color = { + rgbInt = { 0, 112, 221 }, + rgbHex = { 0.00, 0.44, 0.87 }, + }, + rgbString = "0070DD", + }, + { + className = "Mage", + color = { + rgbInt = { 63, 199, 235 }, + rgbHex = { 0.25, 0.78, 0.92 }, + }, + rgbString = "3FC7EB", + }, + { + className = "Warlock", + color = { + rgbInt = { 135, 136, 238 }, + rgbHex = { 0.53, 0.53, 0.93 }, + }, + rgbString = "8788EE", + }, + { + className = "Monk", + color = { + rgbInt = { 0, 255, 152 }, + rgbHex = { 0.00, 1.00, 0.60 }, + }, + rgbString = "00FF98", + }, + { + className = "Druid", + color = { + rgbInt = { 255, 124, 10 }, + rgbHex = { 1.00, 0.49, 0.04 }, + }, + rgbString = "FF7C0A", + }, + { + className = "Demon Hunter", + color = { + rgbInt = { 163, 48, 201 }, + rgbHex = { 0.64, 0.19, 0.79 }, + }, + rgbString = "A330C9", + }, +} local SoundFileRoot = "Interface\\Sounds\\spellAlert\\" -local PlayerName = UnitName("player") ---@param guid string ---@return string, nil|string local function GetUnitFromGuid(guid) local unit = GUIDUnitMap[guid] - if unit == nil then return "", "Unit not found" end + if unit == nil then return "none", "Unit not found" end return unit, nil end ---@param guid string ----@return {name: string, target: string, startms: number, endms: number, spellid: number}, nil|string -local function GetCastInfoForGuid(guid) +---@return {name: string, target: string, targetClassId: number, prettyTarget: string}, nil|string +local function GetTargetInfoForGuid(guid) local retval = { name = "", target = "", + targetClassId = 1, + prettyTarget = "", + } + + local unit, err = GetUnitFromGuid(guid) + if err then return retval, err end + + local targetUnit = string.format("%starget", unit) + retval.target = UnitName(targetUnit) + retval.prettyTarget = retval.target + + local targetClassId = select(3, UnitClass(targetUnit)) + retval.targetClassId = targetClassId + ---@type ClassColor + local classColorInfo = ClassColors[targetClassId] + if classColorInfo then + retval.prettyTarget = string.format("|cFF%s%s|r", classColorInfo.rgbString, retval.target) + end + + return retval, nil +end + +---@param guid string +---@return {name: string, startms: number, endms: number, spellid: number}, nil|string +local function GetCastInfoForGuid(guid) + local retval = { + name = "", startms = 0, endms = 0, spellid = 0 @@ -1062,13 +1190,13 @@ local function GetCastInfoForGuid(guid) local unit, err = GetUnitFromGuid(guid) if err then return retval, err end - local name, _, _, startTimeMS, endTimeMS, _, _, _, spellId = UnitCastingInfo(unit) - if name == nil then return retval, "Unit is not casting" end + local name, _, _, _, startTimeMS, endTimeMS, _, _, _, spellId = UnitCastingInfo(unit) + if name == nil then return retval, "Unit not casting" end + retval.name = name retval.startms = startTimeMS retval.endms = endTimeMS retval.spellid = spellId - retval.target = UnitName(string.format("%starget", unit)) return retval, nil end @@ -1112,41 +1240,57 @@ Alert = { -- We trust that the event is valid local spellname, err = CLEUParser.GetSpellName(...) if err then return end - -- SPELL_CAST_START does NOT have the destination info - -- What we'll have to do is keep a map of unit guids to units - -- In other words - 10 times per second scan all the nameplates and create a map - -- On SPELL_CAST_START get the srcGUID, index the map, get the unit, run UnitCastingInfo(unit), get the target - -- It's fried af but it will probably work - -- With only 40 nameplates it shouldn't be a big deal - local target, err = CLEUParser.GetDestGUID(...) - if target == "" then - local src, err = CLEUParser.GetSourceGUID(...) - if err == nil then - local castInfo, err = GetCastInfoForGuid(src) - if err then print(err) end - if err == nil then - target = castInfo.target - end - end + + -- The idea is: + -- If the spell is being cast (SPELL_CAST_START) target will be nil (because server is cooked) + -- So what we want to do is get the source GUID and try to find it in nameplates + -- If it exists in nameplates we have a unitid and we can try to get casting info + -- From the casting info we can get the cast start and end as well as get the target from unit+target + -- However if the spell is already cast (SPELL_CAST_SUCCESS) the call to castInfo will return no info for cast + -- But it will return info about the target + -- Now the target itself is the actual target of the unit NOT the target of the spell + -- We just have to assume that the target of the spell is the same as the target of the unit + -- We then clamp the cast time to at least 1 second (meaning instant spells appear for 1s) + -- And get the target "manually" from the instant cast using the same principle as with the cast start + local src, err = CLEUParser.GetSourceGUID(...) + if err then return end + local castInfo, err = GetCastInfoForGuid(src) + local targetInfo, err = GetTargetInfoForGuid(src) + + -- If the event DOES have destName then use that ACTUAL target + -- Unless it's the same target we already got + -- The reason we don't overwrite the same target we already got is because we can not (easily) infer + -- The target class from the destName because we don't know where to look for the unit + local target, err = CLEUParser.GetDestName(...) + if err ~= nil and target ~= targetInfo.target then + targetInfo.target = target + targetInfo.prettyTarget = target + targetInfo.targetClassId = 1 end local displayText = self.instruction - if err == nil and target == PlayerName then + if err == nil and targetInfo.target == PlayerName then displayText = self.afflictedInstruction end + local castEnd = math.max(GetTime() + 1, castInfo.endms / 1000) + local castDuration = math.max(1, (castInfo.endms - castInfo.startms) / 1000) + DevTools_Dump(castInfo) + ---@type state local state = { show = true, changed = true, progressType = "timed", - expireTime = GetTime() + 3, - duration = 3, + expireTime = castEnd, + duration = castDuration, autoHide = true, - name = displayText, - target = target, + name = spellname, + instruction = displayText, + target = targetInfo.target, + prettyTarget = targetInfo.prettyTarget, + targetClassId = targetInfo.targetClassId, } - DevTools_Dump(state) allstates[string.format("%d-%d", self.id, self.iterator)] = state self.iterator = self.iterator + 1 @@ -1155,7 +1299,7 @@ Alert = { local alerts = { -- Debug - Alert.new(5176, "Solar Wrath", { "SPELL_CAST_START" }, "Solar Wrath", "Solar Wrath on you!"), + Alert.new(774, "Rejuvenation", { "SPELL_CAST_SUCCESS" }, "REJUV", "REEEEEEEEJUUUUUUUUUUUVVVVVVVVV"), -- Garothi Alert.new(244410, "Decimation", { "SPELL_CAST_SUCCESS" }, "", "Move"), Alert.new(246220, "Fel Bombardment", { "SPELL_CAST_SUCCESS" }, "", "Move"),