refactor and switch to using nampower events
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
if not Cursive.superwow then
|
||||
if not Cursive.nampower then
|
||||
return
|
||||
end
|
||||
|
||||
@@ -24,10 +24,6 @@ Cursive.core.add = function(unit)
|
||||
end
|
||||
|
||||
Cursive.core.addGuid = function(guid)
|
||||
-- check if first two characters are 0x
|
||||
if string.sub(guid, 1, 2) ~= "0x" then
|
||||
return
|
||||
end
|
||||
if UnitExists(guid) and not UnitIsDead(guid) then
|
||||
Cursive.core.guids[guid] = GetTime()
|
||||
end
|
||||
@@ -41,8 +37,8 @@ Cursive.core.enable = function()
|
||||
-- unitstr
|
||||
Cursive.core:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
-- arg1
|
||||
Cursive.core:RegisterEvent("UNIT_COMBAT") -- this can get called with player/target/raid1 etc
|
||||
Cursive.core:RegisterEvent("UNIT_MODEL_CHANGED")
|
||||
Cursive.core:RegisterEvent("UNIT_COMBAT_GUID") -- this can get called with player/target/raid1 etc
|
||||
Cursive.core:RegisterEvent("UNIT_MODEL_CHANGED_GUID")
|
||||
end
|
||||
|
||||
Cursive.core.disable = function()
|
||||
|
||||
+103
-143
@@ -1,4 +1,4 @@
|
||||
if not Cursive.superwow then
|
||||
if not Cursive.nampower then
|
||||
return
|
||||
end
|
||||
local L = AceLibrary("AceLocale-2.2"):new("Cursive")
|
||||
@@ -20,6 +20,7 @@ local curses = {
|
||||
[52551] = true,
|
||||
[52552] = true,
|
||||
},
|
||||
travelTimeSpellIds = {},
|
||||
darkHarvestData = {},
|
||||
guids = {},
|
||||
isChanneling = false,
|
||||
@@ -76,14 +77,6 @@ local curses = {
|
||||
|
||||
-- combat events for curses
|
||||
local fades_test = L["(.+) fades from (.+)"]
|
||||
local resist_test = L["Your (.+) was resisted by (.+)"]
|
||||
local missed_test = L["Your (.+) missed (.+)"]
|
||||
local parry_test = L["Your (.+) is parried by (.+)"]
|
||||
local immune_test = L["Your (.+) fail.+\. (.+) is immune"]
|
||||
local block_test = L["Your (.+) was blocked by (.+)"]
|
||||
local dodge_test = L["Your (.+) was dodged by (.+)"]
|
||||
|
||||
local molten_blast_test = L["Your Molten Blast(.+)for .+ Fire damage"]
|
||||
|
||||
local lastGuid = nil
|
||||
|
||||
@@ -131,9 +124,39 @@ function curses:LoadCurses()
|
||||
curses.trackedCurseIds = getWarriorSpells()
|
||||
end
|
||||
|
||||
-- build travelTimeSpellIds from spell data
|
||||
curses.travelTimeSpellIds = {}
|
||||
for id, data in pairs(curses.trackedCurseIds) do
|
||||
if data.travelTime then
|
||||
curses.travelTimeSpellIds[id] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- register travel time spell tracking
|
||||
if next(curses.travelTimeSpellIds) and not Cursive:IsEventRegistered("SPELL_DAMAGE_EVENT_SELF") then
|
||||
Cursive:RegisterEvent("SPELL_DAMAGE_EVENT_SELF", function(targetGuid, casterGuid, spellID, amount, mitigationStr, hitInfo, spellSchool, effectAuraStr)
|
||||
if curses.travelTimeSpellIds[spellID] and curses.trackedCurseIds[spellID] then
|
||||
lastGuid = targetGuid
|
||||
local duration = curses:GetCurseDuration(spellID)
|
||||
curses:ApplyCurse(spellID, targetGuid, GetTime(), duration)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- load shared debuffs
|
||||
curses.sharedDebuffs = getSharedDebuffs()
|
||||
|
||||
-- register faerie fire tracking from other players
|
||||
if Cursive.db.profile.shareddebuffs.faeriefire then
|
||||
if not Cursive:IsEventRegistered("SPELL_GO_OTHER") then
|
||||
Cursive:RegisterEvent("SPELL_GO_OTHER", function(itemId, spellID, casterGuid, targetGuid, castFlags, numTargetsHit, numTargetsMissed)
|
||||
if curses.sharedDebuffs.faeriefire[spellID] then
|
||||
curses.sharedDebuffGuids.faeriefire[targetGuid] = GetTime()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- go through spell slots and
|
||||
local i = 1
|
||||
while true do
|
||||
@@ -152,7 +175,7 @@ function curses:LoadCurses()
|
||||
|
||||
for id, data in pairs(curses.trackedCurseIds) do
|
||||
-- get the texture
|
||||
local name, rank, texture = SpellInfo(id)
|
||||
local texture = GetSpellIconTexture(GetSpellRecField(id, "spellIconID"))
|
||||
-- update trackedCurseNamesToTextures
|
||||
curses.trackedCurseNamesToTextures[data.name] = texture
|
||||
-- update trackedCurseIds
|
||||
@@ -274,155 +297,92 @@ end);
|
||||
Cursive:RegisterEvent("SPELLCAST_CHANNEL_STOP", StopChanneling);
|
||||
Cursive:RegisterEvent("SPELLCAST_INTERRUPTED", StopChanneling);
|
||||
|
||||
Cursive:RegisterEvent("UNIT_CASTEVENT", function(casterGuid, targetGuid, event, spellID, castDuration)
|
||||
-- immolate will fire both start and cast
|
||||
if event == "CAST" then
|
||||
local _, guid = UnitExists("player")
|
||||
if casterGuid ~= guid then
|
||||
-- check for faeriefire
|
||||
if Cursive.db.profile.shareddebuffs.faeriefire and curses.sharedDebuffs.faeriefire[spellID] then
|
||||
curses.sharedDebuffGuids.faeriefire[targetGuid] = GetTime()
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- store pending cast
|
||||
-- player spell completions
|
||||
Cursive:RegisterEvent("SPELL_GO_SELF", function(itemId, spellID, casterGuid, targetGuid, castFlags, numTargetsHit, numTargetsMissed)
|
||||
if numTargetsMissed > 0 then
|
||||
curses.pendingCast = {}
|
||||
elseif numTargetsHit > 0 or curses.travelTimeSpellIds[spellID] then
|
||||
curses.pendingCast = {
|
||||
spellID = spellID,
|
||||
targetGuid = targetGuid,
|
||||
castDuration = castDuration
|
||||
}
|
||||
end
|
||||
|
||||
if curses.isDruid then
|
||||
-- track ferocious bite cast time and target
|
||||
if spellID == 22557 or
|
||||
spellID == 22568 or
|
||||
spellID == 22827 or
|
||||
spellID == 22828 or
|
||||
spellID == 22829 or
|
||||
spellID == 31018 then
|
||||
curses.lastFerociousBiteTime = GetTime()
|
||||
curses.lastFerociousBiteTargetGuid = targetGuid
|
||||
end
|
||||
end
|
||||
if curses.isDruid then
|
||||
-- track ferocious bite cast time and target
|
||||
if spellID == 22557 or
|
||||
spellID == 22568 or
|
||||
spellID == 22827 or
|
||||
spellID == 22828 or
|
||||
spellID == 22829 or
|
||||
spellID == 31018 then
|
||||
curses.lastFerociousBiteTime = GetTime()
|
||||
curses.lastFerociousBiteTargetGuid = targetGuid
|
||||
end
|
||||
end
|
||||
|
||||
if curses.isShaman then
|
||||
if spellID >= 36916 and spellID <= 36921 then
|
||||
curses.lastMoltenBlastTargetGuid = targetGuid
|
||||
end
|
||||
end
|
||||
if curses.isShaman then
|
||||
if spellID >= 36916 and spellID <= 36921 then
|
||||
curses.lastMoltenBlastTargetGuid = targetGuid
|
||||
if numTargetsHit > 0 then
|
||||
local flame_shock = L["flame shock"]
|
||||
if curses:HasCurse(flame_shock, targetGuid, 0) then
|
||||
curses.guids[targetGuid][flame_shock]["start"] = GetTime()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- delay to check for resists/failures
|
||||
local delay = 0.2
|
||||
|
||||
local _, _, nping = GetNetStats()
|
||||
-- ignore extreme pings
|
||||
if nping and nping > 0 and nping < 500 then
|
||||
delay = 0.05 + (nping / 1000.0) -- convert to seconds
|
||||
end
|
||||
|
||||
if curses.trackedCurseIds[spellID] then
|
||||
if numTargetsHit > 0 then
|
||||
if curses.trackedCurseIds[spellID] and not curses.travelTimeSpellIds[spellID] then
|
||||
lastGuid = targetGuid
|
||||
local duration = curses:GetCurseDuration(spellID) - delay
|
||||
Cursive:ScheduleEvent("addCurse" .. targetGuid .. curses.trackedCurseIds[spellID].name, curses.ApplyCurse, delay, self, spellID, targetGuid, GetTime(), duration)
|
||||
local duration = curses:GetCurseDuration(spellID)
|
||||
curses:ApplyCurse(spellID, targetGuid, GetTime(), duration)
|
||||
elseif curses.conflagrateSpellIds[spellID] then
|
||||
Cursive:ScheduleEvent("updateCurse" .. targetGuid .. L["conflagrate"], curses.UpdateCurse, delay, self, spellID, targetGuid, GetTime())
|
||||
curses:UpdateCurse(spellID, targetGuid, GetTime())
|
||||
end
|
||||
elseif event == "START" then
|
||||
if curses.trackedCurseIds[spellID] then
|
||||
local _, guid = UnitExists("player")
|
||||
if casterGuid ~= guid then
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- store pending cast
|
||||
curses.pendingCast = {
|
||||
spellID = spellID,
|
||||
targetGuid = targetGuid,
|
||||
castDuration = castDuration
|
||||
}
|
||||
end
|
||||
elseif event == "FAIL" then
|
||||
if curses.trackedCurseIds[spellID] then
|
||||
local _, guid = UnitExists("player")
|
||||
if casterGuid ~= guid then
|
||||
return
|
||||
end
|
||||
-- clear pending cast
|
||||
curses.pendingCast = {}
|
||||
end
|
||||
elseif event == "CHANNEL" then
|
||||
-- dark harvest
|
||||
if curses.darkHarvestSpellIds[spellID] then
|
||||
local _, guid = UnitExists("player")
|
||||
if casterGuid ~= guid then
|
||||
return
|
||||
end
|
||||
-- player spell start (cast time spells)
|
||||
Cursive:RegisterEvent("SPELL_START_SELF", function(itemId, spellID, casterGuid, targetGuid, castFlags, castTime)
|
||||
if curses.trackedCurseIds[spellID] then
|
||||
curses.pendingCast = {
|
||||
spellID = spellID,
|
||||
targetGuid = targetGuid,
|
||||
castDuration = castTime / 1000
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
curses.darkHarvestData = {
|
||||
spellID = spellID,
|
||||
targetGuid = targetGuid,
|
||||
castDuration = curses:ScanTooltipForDuration(spellID),
|
||||
start = GetTime()
|
||||
}
|
||||
end
|
||||
-- player spell failure
|
||||
Cursive:RegisterEvent("SPELL_FAILED_SELF", function(spellID, spellResult, failedByServer)
|
||||
if curses.trackedCurseIds[spellID] then
|
||||
curses.pendingCast = {}
|
||||
end
|
||||
end)
|
||||
|
||||
-- player channel start (dark harvest)
|
||||
Cursive:RegisterEvent("SPELL_CHANNEL_START", function(spellID, targetGuid, durationMs)
|
||||
if curses.darkHarvestSpellIds[spellID] then
|
||||
curses.darkHarvestData = {
|
||||
spellID = spellID,
|
||||
targetGuid = targetGuid,
|
||||
castDuration = curses:ScanTooltipForDuration(spellID),
|
||||
start = GetTime()
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
Cursive:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE",
|
||||
function(message)
|
||||
local spell_failed_tests = {
|
||||
resist_test,
|
||||
immune_test
|
||||
}
|
||||
-- only some classes have melee spells that need to check for dodge, parry, miss, block
|
||||
if playerClassName == "DRUID" or playerClassName == "HUNTER" or playerClassName == "ROGUE" then
|
||||
spell_failed_tests = {
|
||||
resist_test,
|
||||
immune_test,
|
||||
missed_test,
|
||||
parry_test,
|
||||
block_test,
|
||||
dodge_test
|
||||
}
|
||||
end
|
||||
Cursive:RegisterEvent("SPELL_MISS_SELF", function(casterGuid, targetGuid, spellID, missInfo)
|
||||
curses.pendingCast = {}
|
||||
|
||||
local spellName, failedTarget
|
||||
for _, test in pairs(spell_failed_tests) do
|
||||
local _, _, foundSpell, foundTarget = string.find(message, test)
|
||||
if foundSpell and foundTarget then
|
||||
spellName = foundSpell
|
||||
failedTarget = foundTarget
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if spellName and failedTarget then
|
||||
spellName = curses:GetLowercaseSpellName(spellName)
|
||||
|
||||
curses.pendingCast = {}
|
||||
|
||||
if curses.trackedCurseNamesToTextures[spellName] and lastGuid then
|
||||
Cursive:CancelScheduledEvent("addCurse" .. lastGuid .. spellName)
|
||||
-- check if sound should be played
|
||||
if curses:ShouldPlayResistSound(lastGuid) then
|
||||
PlaySoundFile("Interface\\AddOns\\Cursive\\Sounds\\resist.mp3")
|
||||
end
|
||||
elseif spellName == L["conflagrate"] and lastGuid then
|
||||
Cursive:CancelScheduledEvent("updateCurse" .. lastGuid .. spellName)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if curses.isShaman and string.find(message, molten_blast_test) then
|
||||
local flame_shock = L["flame shock"]
|
||||
if curses:HasCurse(flame_shock, curses.lastMoltenBlastTargetGuid, 0) then
|
||||
curses.guids[curses.lastMoltenBlastTargetGuid][flame_shock]["start"] = GetTime() -- reset start time to current time
|
||||
end
|
||||
end
|
||||
end
|
||||
) -- resists
|
||||
if curses.trackedCurseIds[spellID] and lastGuid then
|
||||
if curses:ShouldPlayResistSound(lastGuid) then
|
||||
PlaySoundFile("Interface\\AddOns\\Cursive\\Sounds\\resist.mp3")
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
Cursive:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_OTHER", function(message)
|
||||
-- check if spell that faded is relevant
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
if not Cursive.superwow then
|
||||
if not Cursive.nampower then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
+23
-9
@@ -1,22 +1,36 @@
|
||||
local L = AceLibrary("AceLocale-2.2"):new("Cursive")
|
||||
Cursive = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceDebug-2.0", "AceModuleCore-2.0", "AceConsole-2.0", "AceDB-2.0", "AceHook-2.1")
|
||||
Cursive.superwow = true
|
||||
local function HasMinimumNampowerVersion(major, minor, patch)
|
||||
if GetNampowerVersion then
|
||||
local installedMajor, installedMinor, installedPatch = GetNampowerVersion()
|
||||
|
||||
if not GetPlayerBuffID or not CombatLogAdd or not SpellInfo then
|
||||
local notify = CreateFrame("Frame", "CursiveNoSuperwow", UIParent)
|
||||
notify:SetScript("OnUpdate", function()
|
||||
DEFAULT_CHAT_FRAME:AddMessage(L["|cffffcc00Cursive:|cffffaaaa Couldn't detect SuperWoW."])
|
||||
this:Hide()
|
||||
end)
|
||||
if installedMajor > major then
|
||||
return true
|
||||
elseif installedMajor == major and installedMinor > minor then
|
||||
return true
|
||||
elseif installedMajor == major and installedMinor == minor and installedPatch >= patch then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
Cursive.superwow = false
|
||||
return false
|
||||
end
|
||||
|
||||
Cursive.nampower = HasMinimumNampowerVersion(2, 37, 0)
|
||||
|
||||
if not Cursive.nampower then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff6060Cursive:|r could not detect nampower >= v2.37.0")
|
||||
return
|
||||
end
|
||||
|
||||
function Cursive:OnEnable()
|
||||
if not Cursive.superwow then
|
||||
if not Cursive.nampower then
|
||||
return
|
||||
end
|
||||
|
||||
SetCVar("NP_EnableSpellStartEvents", 1)
|
||||
SetCVar("NP_EnableSpellGoEvents", 1)
|
||||
|
||||
DEFAULT_CHAT_FRAME:AddMessage(L["|cffffcc00Cursive:|cffffaaaa Loaded. /cursive for commands and minimap icon for options."])
|
||||
|
||||
Cursive.curses:LoadCurses()
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
if not Cursive.superwow then
|
||||
if not Cursive.nampower then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
+20
-20
@@ -1,34 +1,34 @@
|
||||
local L = AceLibrary("AceLocale-2.2"):new("Cursive")
|
||||
function getHunterSpells()
|
||||
return {
|
||||
[3043] = { name = L["scorpid sting"], rank = 1, duration = 20 },
|
||||
[14275] = { name = L["scorpid sting"], rank = 2, duration = 20 },
|
||||
[14276] = { name = L["scorpid sting"], rank = 3, duration = 20 },
|
||||
[14277] = { name = L["scorpid sting"], rank = 4, duration = 20 },
|
||||
[3043] = { name = L["scorpid sting"], rank = 1, duration = 20, travelTime = true },
|
||||
[14275] = { name = L["scorpid sting"], rank = 2, duration = 20, travelTime = true },
|
||||
[14276] = { name = L["scorpid sting"], rank = 3, duration = 20, travelTime = true },
|
||||
[14277] = { name = L["scorpid sting"], rank = 4, duration = 20, travelTime = true },
|
||||
|
||||
[1978] = { name = L["serpent sting"], rank = 1, duration = 15 },
|
||||
[13549] = { name = L["serpent sting"], rank = 2, duration = 15 },
|
||||
[13550] = { name = L["serpent sting"], rank = 3, duration = 15 },
|
||||
[13551] = { name = L["serpent sting"], rank = 4, duration = 15 },
|
||||
[13552] = { name = L["serpent sting"], rank = 5, duration = 15 },
|
||||
[13553] = { name = L["serpent sting"], rank = 6, duration = 15 },
|
||||
[13554] = { name = L["serpent sting"], rank = 7, duration = 15 },
|
||||
[13555] = { name = L["serpent sting"], rank = 8, duration = 15 },
|
||||
[25295] = { name = L["serpent sting"], rank = 9, duration = 15 },
|
||||
[1978] = { name = L["serpent sting"], rank = 1, duration = 15, travelTime = true },
|
||||
[13549] = { name = L["serpent sting"], rank = 2, duration = 15, travelTime = true },
|
||||
[13550] = { name = L["serpent sting"], rank = 3, duration = 15, travelTime = true },
|
||||
[13551] = { name = L["serpent sting"], rank = 4, duration = 15, travelTime = true },
|
||||
[13552] = { name = L["serpent sting"], rank = 5, duration = 15, travelTime = true },
|
||||
[13553] = { name = L["serpent sting"], rank = 6, duration = 15, travelTime = true },
|
||||
[13554] = { name = L["serpent sting"], rank = 7, duration = 15, travelTime = true },
|
||||
[13555] = { name = L["serpent sting"], rank = 8, duration = 15, travelTime = true },
|
||||
[25295] = { name = L["serpent sting"], rank = 9, duration = 15, travelTime = true },
|
||||
|
||||
[3034] = { name = L["viper sting"], rank = 1, duration = 8 },
|
||||
[14279] = { name = L["viper sting"], rank = 2, duration = 8 },
|
||||
[14280] = { name = L["viper sting"], rank = 3, duration = 8 },
|
||||
[3034] = { name = L["viper sting"], rank = 1, duration = 8, travelTime = true },
|
||||
[14279] = { name = L["viper sting"], rank = 2, duration = 8, travelTime = true },
|
||||
[14280] = { name = L["viper sting"], rank = 3, duration = 8, travelTime = true },
|
||||
|
||||
[2974] = { name = L["wing clip"], rank = 1, duration = 10 },
|
||||
[14267] = { name = L["wing clip"], rank = 2, duration = 10 },
|
||||
[14268] = { name = L["wing clip"], rank = 3, duration = 10 },
|
||||
|
||||
[5116] = { name = L["concussive shot"], rank = 1, duration = 4 },
|
||||
[5116] = { name = L["concussive shot"], rank = 1, duration = 4, travelTime = true },
|
||||
|
||||
[19386] = { name = L["wyvern sting"], rank = 1, duration = 12 },
|
||||
[24132] = { name = L["wyvern sting"], rank = 2, duration = 12 },
|
||||
[24133] = { name = L["wyvern sting"], rank = 3, duration = 12 },
|
||||
[19386] = { name = L["wyvern sting"], rank = 1, duration = 12, travelTime = true },
|
||||
[24132] = { name = L["wyvern sting"], rank = 2, duration = 12, travelTime = true },
|
||||
[24133] = { name = L["wyvern sting"], rank = 3, duration = 12, travelTime = true },
|
||||
|
||||
[19306] = { name = L["counterattack"], rank = 1, duration = 5 },
|
||||
[20909] = { name = L["counterattack"], rank = 2, duration = 5 },
|
||||
|
||||
+3
-3
@@ -60,9 +60,9 @@ function getWarlockSpells()
|
||||
[11668] = { name = L["immolate"], rank = 7, duration = 15 },
|
||||
[25309] = { name = L["immolate"], rank = 8, duration = 15 },
|
||||
|
||||
[6789] = { name = L["death coil"], rank = 1, duration = 3 },
|
||||
[17925] = { name = L["death coil"], rank = 2, duration = 3 },
|
||||
[17926] = { name = L["death coil"], rank = 3, duration = 3 },
|
||||
[6789] = { name = L["death coil"], rank = 1, duration = 3, travelTime = true },
|
||||
[17925] = { name = L["death coil"], rank = 2, duration = 3, travelTime = true },
|
||||
[17926] = { name = L["death coil"], rank = 3, duration = 3, travelTime = true },
|
||||
|
||||
[710] = { name = L["banish"], rank = 1, duration = 20 },
|
||||
[18647] = { name = L["banish"], rank = 2, duration = 30 },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
if not Cursive.superwow then
|
||||
if not Cursive.nampower then
|
||||
return
|
||||
end
|
||||
|
||||
@@ -184,6 +184,7 @@ ui.BarEnter = function()
|
||||
end
|
||||
this.parent.hover = true
|
||||
|
||||
SetMouseoverUnit(this.parent.guid)
|
||||
GameTooltip_SetDefaultAnchor(GameTooltip, this)
|
||||
GameTooltip:SetUnit(this.parent.guid)
|
||||
GameTooltip:Show()
|
||||
@@ -191,6 +192,7 @@ end
|
||||
|
||||
ui.BarLeave = function()
|
||||
this.parent.hover = false
|
||||
SetMouseoverUnit()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user