Merge pull request #66 from pepopo978/nampower

Switch to using nampower events/functions
This commit is contained in:
pepopo978
2026-03-17 09:08:42 -07:00
committed by GitHub
13 changed files with 204 additions and 264 deletions
+4 -4
View File
@@ -1,9 +1,9 @@
## Interface: 11200
## Title: [|CFF33AAFFSUPERWOW|R] Cursive 2.6.6
## Title-zhCN: [|CFF33AAFFSUPERWOW|R] Cursive 2.6.6
## Title: Cursive 3.0.0
## Title-zhCN: Cursive 3.0.0
## Author: Pepopo
## Notes: Uses SuperWoW GUIDs to show units in combat and track curses
## Notes-zhCN: 使用SuperWoW的GUID功能来显示战斗中的单位并监视诅咒等
## Notes: Uses GUIDs to show units in combat and track curses
## Notes-zhCN: 使用的GUID功能来显示战斗中的单位并监视诅咒等
## Version: 1.4.0
## SavedVariablesPerCharacter: CursiveDB
## X-Embeds: Ace2, FuBarPlugin-2.0, CompostLib, DewDropLib, TabletLib
+2
View File
@@ -13,6 +13,7 @@ L:RegisterTranslations("enUS", function()
["Filter targets by name. Can be a partial match. If no match is found, the command will do nothing."] = true,
["Ignore targets with the specified spell id already on them. Useful for ignoring targets that already have a shared debuff."] = true,
["Ignore targets with the specified spell texture already on them. Useful for ignoring targets that already have a shared debuff."] = true,
["For Warlocks with the Malediction talent: when checking if Curse of Recklessness, Curse of the Elements, or Curse of Shadow is already on a target, check for Curse of Agony instead. Default is 1 (enabled). Set malediction=0 to disable and check for the original curse."] = true,
["Time threshold at which to allow refreshing a curse. Default is 0 seconds."] = true,
["Always prioritize current target when choosing target for multicurse. Does not affect 'curse' command."] = true,
["Ignore the current target when choosing target for multicurse. Does not affect 'curse' command."] = true,
@@ -221,6 +222,7 @@ L:RegisterTranslations("zhCN", function()
["Filter targets by name. Can be a partial match. If no match is found, the command will do nothing."] = "通过名称过滤目标。可以是部分匹配。如果没有找到匹配项,命令将不执行.",
["Ignore targets with the specified spell id already on them. Useful for ignoring targets that already have a shared debuff."] = "忽略已经在目标身上的指定法术ID。对于忽略已经有共享debuff的目标很有用.",
["Ignore targets with the specified spell texture already on them. Useful for ignoring targets that already have a shared debuff."] = "忽略已经在目标身上的指定法术纹理。对于忽略已经有共享debuff的目标很有用.",
["For Warlocks with the Malediction talent: when checking if Curse of Recklessness, Curse of the Elements, or Curse of Shadow is already on a target, check for Curse of Agony instead. Default is 1 (enabled). Set malediction=0 to disable and check for the original curse."] = "对于拥有诅咒天赋的术士:检查鲁莽诅咒、元素诅咒或暗影诅咒是否已在目标身上时,改为检查痛苦诅咒。默认为1(启用)。设置malediction=0可禁用并检查原始诅咒。",
["Time threshold at which to allow refreshing a curse. Default is 0 seconds."] = "允许刷新诅咒的时间阈值。默认是0秒.例如:refreshtime=2",
["Always prioritize current target when choosing target for multicurse. Does not affect 'curse' command."] = "选择多重诅咒目标时总是优先当前目标。不影响‘诅咒’命令。",
["Ignore the current target when choosing target for multicurse. Does not affect 'curse' command."] = "选择多重诅咒目标时忽略当前目标。不影响‘诅咒’命令。",
+5 -2
View File
@@ -100,8 +100,11 @@ All commands can take the following options separated by commas:
- `name=<str>` : "Filter targets by name. Can be a partial match. If no match is found, the command will do nothing.",
- `ignorespellid=<number>` : "Ignore targets with the specified spell id already on them. Useful for ignoring targets
that already have a shared debuff.",
- `ignorespelltexture=<number>` : "Ignore targets with the specified spell texture already on them. Useful for ignoring
- `ignorespelltexture=<str>` : "Ignore targets with the specified spell texture already on them. Useful for ignoring
targets that already have a shared debuff.",
- `malediction=<0|1>` : "For Warlocks with the Malediction talent: when checking if Curse of Recklessness, Curse of
the Elements, or Curse of Shadow is already on a target, check for Curse of Agony instead. Default is 1 (enabled).
Set `malediction=0` to disable and check for the original curse.",
EXAMPLE: `/cursive multicurse Corruption|HIGHEST_HP|warnings,resistsound,expiringsound,minhp=10000,refreshtime=2`
@@ -187,7 +190,7 @@ All commands will ignore targets with the following CCs on them:
Multicurse will only ever target enemies that are already in combat (except if you target a mob directly first) to
prevent pulling things you didn't intend like marked patrols.
For Warlocks with the Malediction talent, when checking if Curse of Recklessness, Curse of the Elements, or Curse of Shadow is already on a target, the addon will instead check for Curse of Agony to allow you to refresh agony using them. Don't use the refreshtime option with this as the server won't refresh Curse of Agony if it is still on the mob.
For Warlocks with the Malediction talent, when checking if Curse of Recklessness, Curse of the Elements, or Curse of Shadow is already on a target, the addon will instead check for Curse of Agony to allow you to refresh agony using them. This is enabled by default and can be disabled per-command with `malediction=0`. Don't use the `refreshtime` option with this as the server won't refresh Curse of Agony if it is still on the mob.
Mobs with raid marks will be displayed first.
+14 -42
View File
@@ -16,6 +16,7 @@ local commandOptions = {
name = L["Filter targets by name. Can be a partial match. If no match is found, the command will do nothing."],
ignorespellid = L["Ignore targets with the specified spell id already on them. Useful for ignoring targets that already have a shared debuff."],
ignorespelltexture = L["Ignore targets with the specified spell texture already on them. Useful for ignoring targets that already have a shared debuff."],
malediction = L["For Warlocks with the Malediction talent: when checking if Curse of Recklessness, Curse of the Elements, or Curse of Shadow is already on a target, check for Curse of Agony instead. Default is 1 (enabled). Set malediction=0 to disable and check for the original curse."],
}
local commands = {
@@ -77,6 +78,11 @@ local function parseOptions(optionsStr)
if texture then
options["ignorespelltexture"] = texture
end
elseif option == "malediction" then
local _, _, maledictionVal = string.find(optionsStr, "malediction=(%d)")
if maledictionVal then
options["malediction"] = tonumber(maledictionVal)
end
elseif string.find(optionsStr, option) then
options[option] = true
end
@@ -241,32 +247,12 @@ local crowdControlledSpellIds = {
}
local function isMobCrowdControlled(guid)
-- check if mob is CC'ed
-- check debuffs
for i = 1, 16 do
local _, _, _, spellId = UnitDebuff(guid, i)
if spellId then
if crowdControlledSpellIds[spellId] then
return true
end
else
break
local auras = GetUnitField(guid, "aura")
for i, spellId in pairs(auras) do
if crowdControlledSpellIds[spellId] then
return true
end
end
-- check buffs
for i = 1, 32 do
local _, _, spellId = UnitBuff(guid, i)
if spellId then
if crowdControlledSpellIds[spellId] then
return true
end
else
break
end
end
return false
end
@@ -283,26 +269,12 @@ local function GetSquarePrioRaidTargetIndex(guid)
end
local function hasSpellId(guid, ignoreSpellId)
for i = 1, 16 do
local texture, stacks, spellSchool, spellId = UnitDebuff(guid, i);
if not spellId then
break
end
local auras = GetUnitField(guid, "aura")
for i, spellId in pairs(auras) do
if spellId == ignoreSpellId then
return true
end
end
for i = 1, 32 do
local texture, stacks, spellId = UnitBuff(guid, i);
if not spellId then
break
end
if spellId == ignoreSpellId then
return true
end
end
return false
end
@@ -401,7 +373,7 @@ local function pickTarget(selectedPriority, lowercaseSpellNameNoRank, checkRange
end
if passedRangeCheck then
-- check if the target has the curse
if not Cursive.curses:HasCurse(lowercaseSpellNameNoRank, guid, refreshTime) and not isMobCrowdControlled(guid) then
if not Cursive.curses:HasCurse(lowercaseSpellNameNoRank, guid, refreshTime, options["malediction"]) and not isMobCrowdControlled(guid) then
local mobHp = UnitHealth(guid)
if not minHp or mobHp >= minHp then
local primaryValue = -1
@@ -512,7 +484,7 @@ function Cursive:Curse(spellName, targetedGuid, options)
-- remove (Rank x) from spellName if it exists
local lowercaseSpellNameNoRank = Cursive.utils.GetLowercaseSpellNameNoRank(spellName)
if targetedGuid and not Cursive.curses:HasCurse(lowercaseSpellNameNoRank, targetedGuid, options["refreshtime"]) and not isMobCrowdControlled(targetedGuid) then
if targetedGuid and not Cursive.curses:HasCurse(lowercaseSpellNameNoRank, targetedGuid, options["refreshtime"], options["malediction"]) and not isMobCrowdControlled(targetedGuid) then
castSpellWithOptions(string.lower(spellName), lowercaseSpellNameNoRank, targetedGuid, options)
return true
elseif options["warnings"] then
+3 -7
View File
@@ -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()
+119 -156
View File
@@ -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,40 @@ function curses:LoadCurses()
curses.trackedCurseIds = getWarriorSpells()
end
-- build travelTimeSpellIds from spell data
-- travelTime spells must have a damage component otherwise it won't work
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 +176,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 +298,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
@@ -574,29 +535,31 @@ function curses:GetCurseData(spellName, guid)
return nil
end
function curses:HasCurse(lowercaseSpellNameNoRank, targetGuid, minRemaining)
function curses:HasCurse(lowercaseSpellNameNoRank, targetGuid, minRemaining, malediction)
if not minRemaining then
minRemaining = 0 -- default to 0
end
if malediction == nil then
malediction = 1 -- default to enabled
end
-- handle faerie fire special case
if curses.isDruid and string.find(lowercaseSpellNameNoRank, L["faerie fire"]) then
-- remove (feral) or (bear) from spell name
lowercaseSpellNameNoRank = L["faerie fire"]
end
-- handle malediction for warlocks
if curses.isWarlock and
lowercaseSpellNameNoRank == L["curse of recklessness"] or
lowercaseSpellNameNoRank == L["curse of the elements"] or
lowercaseSpellNameNoRank == L["curse of shadow"] then
-- check if they have malediction
local _, _, _, _, malediction = GetTalentInfo(1, 17)
if malediction > 0 then
lowercaseSpellNameNoRank = L["curse of agony"] -- check for curse of agony instead
end
end
-- handle malediction for warlocks
if curses.isWarlock and malediction ~= 0 and (
lowercaseSpellNameNoRank == L["curse of recklessness"] or
lowercaseSpellNameNoRank == L["curse of the elements"] or
lowercaseSpellNameNoRank == L["curse of shadow"]) then
local _, _, _, _, hasMalediction = GetTalentInfo(1, 17)
if hasMalediction > 0 then
lowercaseSpellNameNoRank = L["curse of agony"]
end
end
if curses.guids[targetGuid] and curses.guids[targetGuid][lowercaseSpellNameNoRank] then
local remaining = Cursive.curses:TimeRemaining(curses.guids[targetGuid][lowercaseSpellNameNoRank])
+1 -1
View File
@@ -1,4 +1,4 @@
if not Cursive.superwow then
if not Cursive.nampower then
return
end
+23 -9
View File
@@ -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()
+3 -1
View File
@@ -1,4 +1,4 @@
if not Cursive.superwow then
if not Cursive.nampower then
return
end
@@ -20,6 +20,8 @@ Cursive:RegisterDefaults("profile", {
showhealthbar = true,
showunitname = true,
malediction = true,
shareddebuffs = {
faeriefire = false,
},
+21 -21
View File
@@ -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 = 21 }, -- 1 sec added to estimate travel time. Can't use travelTime due to the spell having no direct damage component
[14275] = { name = L["scorpid sting"], rank = 2, duration = 21 },
[14276] = { name = L["scorpid sting"], rank = 3, duration = 21 },
[14277] = { name = L["scorpid sting"], rank = 4, duration = 21 },
[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 = 16 }, -- 1 sec added to estimate travel time. Can't use travelTime due to the spell having no direct damage component
[13549] = { name = L["serpent sting"], rank = 2, duration = 16 },
[13550] = { name = L["serpent sting"], rank = 3, duration = 16 },
[13551] = { name = L["serpent sting"], rank = 4, duration = 16 },
[13552] = { name = L["serpent sting"], rank = 5, duration = 16 },
[13553] = { name = L["serpent sting"], rank = 6, duration = 16 },
[13554] = { name = L["serpent sting"], rank = 7, duration = 16 },
[13555] = { name = L["serpent sting"], rank = 8, duration = 16 },
[25295] = { name = L["serpent sting"], rank = 9, duration = 16 },
[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 = 9 }, -- 1 sec added to estimate travel time. Can't use travelTime due to the spell having no direct damage component
[14279] = { name = L["viper sting"], rank = 2, duration = 9 },
[14280] = { name = L["viper sting"], rank = 3, duration = 9 },
[19386] = { name = L["wyvern sting"], rank = 1, duration = 13 }, -- 1 sec added to estimate travel time. Can't use travelTime due to the spell having no direct damage component
[24132] = { name = L["wyvern sting"], rank = 2, duration = 13 },
[24133] = { name = L["wyvern sting"], rank = 3, duration = 13 },
[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 },
[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 },
[5116] = { name = L["concussive shot"], rank = 1, duration = 5 }, -- 1 sec added to estimate travel time. Can't use travelTime due to the spell having no direct damage component
[19306] = { name = L["counterattack"], rank = 1, duration = 5 },
[20909] = { name = L["counterattack"], rank = 2, duration = 5 },
+3 -3
View File
@@ -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 },
+5 -17
View File
@@ -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
@@ -507,26 +509,12 @@ local function GetBarCords(row, col)
end
local function hasAnySpellId(guid, spellIds)
for i = 1, 16 do
local texture, stacks, spellSchool, spellId = UnitDebuff(guid, i);
if not spellId then
break
end
local auras = GetUnitField(guid, "aura")
for i, spellId in pairs(auras) do
if spellIds[spellId] then
return spellId
end
end
for i = 1, 32 do
local texture, stacks, spellId = UnitBuff(guid, i);
if not spellId then
break
end
if spellIds[spellId] then
return spellId
end
end
return nil
end
+1 -1
View File
@@ -1,4 +1,4 @@
if not Cursive.superwow then
if not Cursive.nampower then
return
end