Merge pull request #66 from pepopo978/nampower
Switch to using nampower events/functions
This commit is contained in:
+4
-4
@@ -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
|
||||
|
||||
@@ -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."] = "选择多重诅咒目标时忽略当前目标。不影响‘诅咒’命令。",
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
+3
-1
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user