Dark harvest (#25)

* dark harvest handling

* check for current player on dh cast

* merge changes

* fix more case stuff

* missing translation
This commit is contained in:
pepopo978
2025-01-08 09:19:17 -08:00
committed by GitHub
parent 4d273b151c
commit e75b821a09
7 changed files with 165 additions and 72 deletions
+4 -2
View File
@@ -130,7 +130,7 @@ L:RegisterTranslations("enUS", function()
["holy fire"] = true,
-- Paladin
["Turn Undead"] = true,
["turn undead"] = true,
-- rogue
["blind"] = true,
@@ -158,6 +158,7 @@ L:RegisterTranslations("enUS", function()
["curse of tongues"] = true,
["curse of weakness"] = true,
["curse of exhaustion"] = true,
["dark harvest"] = true,
["immolate"] = true,
["death coil"] = true,
["banish"] = true,
@@ -294,7 +295,7 @@ L:RegisterTranslations("zhCN", function()
["holy fire"] = "神圣之火",
-- Paladin
["Turn Undead"] = "超度亡灵",
["turn undead"] = "超度亡灵",
-- rogue
["blind"] = "致盲",
@@ -322,6 +323,7 @@ L:RegisterTranslations("zhCN", function()
["curse of tongues"] = "语言诅咒",
["curse of weakness"] = "虚弱诅咒",
["curse of exhaustion"] = "疲劳诅咒",
["dark harvest"] = "黑暗收割",
["immolate"] = "献祭",
["death coil"] = "死亡缠绕",
["banish"] = "放逐",
+13 -13
View File
@@ -25,7 +25,7 @@ so that it doesn't block your clicks when it's not displaying mobs.
`/cursive curse <spellName:str>|<guid?:str>|<options?:comma separated str>`: Casts spell if not already on target/guid
EXAMPLE: `/cursive curse corruption|target` will attempt to cast corruption on your target if it's not already on them
EXAMPLE: `/cursive curse Corruption|target` will attempt to cast Corruption on your target if it's not already on them
and they aren't cc'ed.
### Multicurse
@@ -33,7 +33,7 @@ and they aren't cc'ed.
`/cursive multicurse <spellName:str>|<priority?:str>|<options?:comma separated str>`: Picks target based on priority and
casts spell if not already on target and they aren't cc'ed.
EXAMPLE: `/cursive multicurse corruption|HIGHEST_HP` will attempt to cast corruption picking the target with the highest
EXAMPLE: `/cursive multicurse Corruption|HIGHEST_HP` will attempt to cast Corruption picking the target with the highest
HP that doesn't already have it and will warn you if it does nothing.
## Priority Options
@@ -82,8 +82,8 @@ All commands can take the following options separated by commas:
- `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 targets that already have a shared debuff.",
EXAMPLE: `/cursive multicurse corruption|HIGHEST_HP|warnings,resistsound,expiringsound,minhp=10000,refreshtime=2`
EXAMPLE: `/cursive multicurse curse of recklessness|RAID_MARK|name=Touched Warrior,ignorespelltexture=Spell_Shadow_UnholyStrength,resistsound,expiringsound`
EXAMPLE: `/cursive multicurse Corruption|HIGHEST_HP|warnings,resistsound,expiringsound,minhp=10000,refreshtime=2`
EXAMPLE: `/cursive multicurse Curse of Recklessness|RAID_MARK|name=Touched Warrior,ignorespelltexture=Spell_Shadow_UnholyStrength,resistsound,expiringsound`
## Important info
@@ -93,16 +93,16 @@ Otherwise, all commands will prioritize targets within 28 yards of you first to
All commands will ignore targets with the following CCs on them:
- sleep
- entangling roots
- shackle undead
- polymorph
- Sleep
- Entangling Roots
- Shackle Undead
- Polymorph
- Turn Undead
- blind
- sap
- gouge
- freezing trap
- banish
- Blind
- Sap
- Gouge
- Freezing Trap
- Banish
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.
+6 -6
View File
@@ -141,9 +141,9 @@ local crowdControlledSpellIds = {
[28271] = { name = L["polymorph: turtle"], rank = L["Rank 1"], duration = 50 },
[28272] = { name = L["polymorph: pig"], rank = L["Rank 1"], duration = 50 },
[2878] = { name = L["Turn Undead"], rank = 1, duration = 10 },
[5627] = { name = L["Turn Undead"], rank = 2, duration = 15 },
[10326] = { name = L["Turn Undead"], rank = 3, duration = 20 },
[2878] = { name = L["turn undead"], rank = 1, duration = 10 },
[5627] = { name = L["turn undead"], rank = 2, duration = 15 },
[10326] = { name = L["turn undead"], rank = 3, duration = 20 },
[2094] = { name = L["blind"], rank = 1, duration = 10 },
[21060] = { name = L["blind"], rank = 1, duration = 10 },
@@ -183,15 +183,15 @@ local crowdControlledSpellIds = {
[20740] = { name = "Dominate Mind" },
[17405] = { name = "Domination" },
[3442] = { name = "Enslave" },
[13181] = { name = "Gnomish mind control Cap" },
[26740] = { name = "Gnomish mind control Cap" },
[13181] = { name = "Gnomish Mind Control Cap" },
[26740] = { name = "Gnomish Mind Control Cap" },
[12483] = { name = "Hex of Jammal'an" },
[25772] = { name = "Mental Domination" },
[7967] = { name = "Naralex's Nightmare" },
[19469] = { name = "Poison Mind" },
[17244] = { name = "Possess" },
[22667] = { name = "Shadow Command" },
[20668] = { name = "sleepwalk" },
[20668] = { name = "Sleepwalk" },
[785] = { name = "True Fulfillment" },
[26195] = { name = "Whisperings of C'Thun" },
[26197] = { name = "Whisperings of C'Thun" },
+89 -2
View File
@@ -15,7 +15,14 @@ local curses = {
[18931] = true,
[18932] = true,
},
darkHarvestSpellIds = {
[52550] = true,
[52551] = true,
[52552] = true,
},
darkHarvestData = {},
guids = {},
isChanneling = false,
pendingCast = {},
resistSoundGuids = {},
expiringSoundGuids = {},
@@ -103,7 +110,7 @@ function curses:ScanTooltipForDuration(curseSpellID)
end
function curses:GetCurseDuration(curseSpellID)
if curses.trackedCurseIds[curseSpellID].variable_duration then
if curses.trackedCurseIds[curseSpellID].variableDuration then
return curses:ScanTooltipForDuration(curseSpellID)
end
@@ -140,6 +147,17 @@ Cursive:RegisterEvent("LEARNED_SPELL_IN_TAB", function()
curses:LoadCurses()
end)
local function StopChanneling()
curses.isChanneling = false
end
Cursive:RegisterEvent("SPELLCAST_CHANNEL_START", function()
curses.isChanneling = true
end);
Cursive:RegisterEvent("SPELLCAST_CHANNEL_STOP", StopChanneling);
Cursive:RegisterEvent("SPELLCAST_INTERRUPTED", StopChanneling);
Cursive:RegisterEvent("SPELLCAST_FAILED", StopChanneling);
Cursive:RegisterEvent("UNIT_CASTEVENT", function(casterGuid, targetGuid, event, spellID, castDuration)
-- immolate will fire both start and cast
if event == "CAST" then
@@ -184,6 +202,21 @@ Cursive:RegisterEvent("UNIT_CASTEVENT", function(casterGuid, targetGuid, event,
-- 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
curses.darkHarvestData = {
spellID = spellID,
targetGuid = targetGuid,
castDuration = curses:ScanTooltipForDuration(spellID),
start = GetTime()
}
end
end
end)
@@ -233,8 +266,61 @@ Cursive:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_OTHER", function(message)
end
)
function curses:GetLastTickTime(curseData)
local ticks = curses.trackedCurseIds[curseData.spellID].numTicks
if not ticks then
return GetTime()
end
local tickTime = curseData.duration / ticks
local currentTime = GetTime() + tickTime * .2 -- dh won't apply to previous tick if within 20% of tick time
return math.floor((currentTime - curseData.start) / tickTime) * tickTime + curseData.start
end
function curses:TrackDarkHarvest(curseData)
if curses.darkHarvestData["targetGuid"] and curses.darkHarvestData["targetGuid"] == curseData["targetGuid"] then
local dhActive = false
-- check if still channeling
if curses.isChanneling then
local dhTimeRemaining = curses.darkHarvestData.castDuration - (GetTime() - curses.darkHarvestData.start)
-- check if dh still active based on cast duration
if dhTimeRemaining > 0 then
dhActive = true
-- dh is active
if not curseData["dhStartTime"] then
curseData["dhStartTime"] = curses:GetLastTickTime(curseData) -- dh will reduce full tick duration
end
end
end
if curseData["dhStartTime"] and dhActive == false and not curseData["dhEndTime"] then
-- if dh no longer active, store end time if not already stored
curseData["dhEndTime"] = GetTime()
end
end
end
function curses:GetDarkHarvestReduction(curseData)
if curseData["dhStartTime"] then
local endTime = curseData["dhEndTime"] or GetTime()
local dhActiveTime = endTime - curseData["dhStartTime"]
if dhActiveTime > 0 then
return dhActiveTime * .2 -- 20% reduction
end
end
return 0
end
function curses:TimeRemaining(curseData)
return math.ceil(curseData.duration - (GetTime() - curseData.start))
local dhReduction = 0
if curses.trackedCurseIds[curseData.spellID].darkHarvest then
curses:TrackDarkHarvest(curseData)
dhReduction = curses:GetDarkHarvestReduction(curseData)
end
return math.ceil(curseData.duration - (GetTime() - curseData.start) - dhReduction)
end
function curses:EnableResistSound(guid)
@@ -329,6 +415,7 @@ function curses:ApplyCurse(spellID, targetGuid, startTime)
duration = duration,
start = startTime,
spellID = spellID,
targetGuid = targetGuid
}
end
+25 -25
View File
@@ -31,34 +31,34 @@ function getDruidSpells()
[18657] = { name = L["hibernate"], rank = 2, duration = 30 },
[18658] = { name = L["hibernate"], rank = 3, duration = 40 },
[5570] = { name = L["insect swarm"], rank = 1, duration = 18, variable_duration = true },
[24974] = { name = L["insect swarm"], rank = 2, duration = 18, variable_duration = true },
[24975] = { name = L["insect swarm"], rank = 3, duration = 18, variable_duration = true },
[24976] = { name = L["insect swarm"], rank = 4, duration = 18, variable_duration = true },
[24977] = { name = L["insect swarm"], rank = 5, duration = 18, variable_duration = true },
[5570] = { name = L["insect swarm"], rank = 1, duration = 18, variableDuration = true },
[24974] = { name = L["insect swarm"], rank = 2, duration = 18, variableDuration = true },
[24975] = { name = L["insect swarm"], rank = 3, duration = 18, variableDuration = true },
[24976] = { name = L["insect swarm"], rank = 4, duration = 18, variableDuration = true },
[24977] = { name = L["insect swarm"], rank = 5, duration = 18, variableDuration = true },
[8921] = { name = L["moonfire"], rank = 1, duration = 9, variable_duration = true },
[8924] = { name = L["moonfire"], rank = 2, duration = 18, variable_duration = true },
[8925] = { name = L["moonfire"], rank = 3, duration = 18, variable_duration = true },
[8926] = { name = L["moonfire"], rank = 4, duration = 18, variable_duration = true },
[8927] = { name = L["moonfire"], rank = 5, duration = 18, variable_duration = true },
[8928] = { name = L["moonfire"], rank = 6, duration = 18, variable_duration = true },
[8929] = { name = L["moonfire"], rank = 7, duration = 18, variable_duration = true },
[9833] = { name = L["moonfire"], rank = 8, duration = 18, variable_duration = true },
[9834] = { name = L["moonfire"], rank = 9, duration = 18, variable_duration = true },
[9835] = { name = L["moonfire"], rank = 10, duration = 18, variable_duration = true },
[8921] = { name = L["moonfire"], rank = 1, duration = 9, variableDuration = true },
[8924] = { name = L["moonfire"], rank = 2, duration = 18, variableDuration = true },
[8925] = { name = L["moonfire"], rank = 3, duration = 18, variableDuration = true },
[8926] = { name = L["moonfire"], rank = 4, duration = 18, variableDuration = true },
[8927] = { name = L["moonfire"], rank = 5, duration = 18, variableDuration = true },
[8928] = { name = L["moonfire"], rank = 6, duration = 18, variableDuration = true },
[8929] = { name = L["moonfire"], rank = 7, duration = 18, variableDuration = true },
[9833] = { name = L["moonfire"], rank = 8, duration = 18, variableDuration = true },
[9834] = { name = L["moonfire"], rank = 9, duration = 18, variableDuration = true },
[9835] = { name = L["moonfire"], rank = 10, duration = 18, variableDuration = true },
[1822] = { name = L["rake"], rank = 1, duration = 9, variable_duration = true },
[1823] = { name = L["rake"], rank = 2, duration = 9, variable_duration = true },
[1824] = { name = L["rake"], rank = 3, duration = 9, variable_duration = true },
[9904] = { name = L["rake"], rank = 4, duration = 9, variable_duration = true },
[1822] = { name = L["rake"], rank = 1, duration = 9, variableDuration = true },
[1823] = { name = L["rake"], rank = 2, duration = 9, variableDuration = true },
[1824] = { name = L["rake"], rank = 3, duration = 9, variableDuration = true },
[9904] = { name = L["rake"], rank = 4, duration = 9, variableDuration = true },
[1079] = { name = L["rip"], rank = 1, duration = 12, variable_duration = true },
[9492] = { name = L["rip"], rank = 2, duration = 12, variable_duration = true },
[9493] = { name = L["rip"], rank = 3, duration = 12, variable_duration = true },
[9752] = { name = L["rip"], rank = 4, duration = 12, variable_duration = true },
[9894] = { name = L["rip"], rank = 5, duration = 12, variable_duration = true },
[9896] = { name = L["rip"], rank = 6, duration = 12, variable_duration = true },
[1079] = { name = L["rip"], rank = 1, duration = 12, variableDuration = true },
[9492] = { name = L["rip"], rank = 2, duration = 12, variableDuration = true },
[9493] = { name = L["rip"], rank = 3, duration = 12, variableDuration = true },
[9752] = { name = L["rip"], rank = 4, duration = 12, variableDuration = true },
[9894] = { name = L["rip"], rank = 5, duration = 12, variableDuration = true },
[9896] = { name = L["rip"], rank = 6, duration = 12, variableDuration = true },
[2908] = { name = L["soothe animal"], rank = 1, duration = 15 },
[8955] = { name = L["soothe animal"], rank = 2, duration = 15 },
+6 -6
View File
@@ -1,11 +1,11 @@
local L = AceLibrary("AceLocale-2.2"):new("Cursive")
function getShamanSpells()
return {
[8050] = { name = L["flame shock"], rank = 1, duration = 12, variable_duration = true },
[8052] = { name = L["flame shock"], rank = 2, duration = 12, variable_duration = true },
[8053] = { name = L["flame shock"], rank = 3, duration = 12, variable_duration = true },
[10447] = { name = L["flame shock"], rank = 4, duration = 12, variable_duration = true },
[10448] = { name = L["flame shock"], rank = 5, duration = 12, variable_duration = true },
[29228] = { name = L["flame shock"], rank = 6, duration = 12, variable_duration = true },
[8050] = { name = L["flame shock"], rank = 1, duration = 12, variableDuration = true },
[8052] = { name = L["flame shock"], rank = 2, duration = 12, variableDuration = true },
[8053] = { name = L["flame shock"], rank = 3, duration = 12, variableDuration = true },
[10447] = { name = L["flame shock"], rank = 4, duration = 12, variableDuration = true },
[10448] = { name = L["flame shock"], rank = 5, duration = 12, variableDuration = true },
[29228] = { name = L["flame shock"], rank = 6, duration = 12, variableDuration = true },
}
end
+22 -18
View File
@@ -1,20 +1,29 @@
local L = AceLibrary("AceLocale-2.2"):new("Cursive")
function getWarlockSpells()
return {
[172] = { name = L["corruption"], rank = 1, duration = 12, variable_duration = true },
[6222] = { name = L["corruption"], rank = 2, duration = 15, variable_duration = true },
[6223] = { name = L["corruption"], rank = 3, duration = 18, variable_duration = true },
[7648] = { name = L["corruption"], rank = 4, duration = 18, variable_duration = true },
[11671] = { name = L["corruption"], rank = 5, duration = 18, variable_duration = true },
[11672] = { name = L["corruption"], rank = 6, duration = 18, variable_duration = true },
[25311] = { name = L["corruption"], rank = 7, duration = 18, variable_duration = true },
[172] = { name = L["corruption"], rank = 1, duration = 12, variableDuration = true, darkHarvest = true, numTicks=4},
[6222] = { name = L["corruption"], rank = 2, duration = 15, variableDuration = true, darkHarvest = true, numTicks=5 },
[6223] = { name = L["corruption"], rank = 3, duration = 18, variableDuration = true, darkHarvest = true, numTicks=6 },
[7648] = { name = L["corruption"], rank = 4, duration = 18, variableDuration = true, darkHarvest = true, numTicks=6 },
[11671] = { name = L["corruption"], rank = 5, duration = 18, variableDuration = true, darkHarvest = true, numTicks=6 },
[11672] = { name = L["corruption"], rank = 6, duration = 18, variableDuration = true, darkHarvest = true, numTicks=6 },
[25311] = { name = L["corruption"], rank = 7, duration = 18, variableDuration = true, darkHarvest = true, numTicks=6 },
[980] = { name = L["curse of agony"], rank = 1, duration = 24, variable_duration = true },
[1014] = { name = L["curse of agony"], rank = 2, duration = 24, variable_duration = true },
[6217] = { name = L["curse of agony"], rank = 3, duration = 24, variable_duration = true },
[11711] = { name = L["curse of agony"], rank = 4, duration = 24, variable_duration = true },
[11712] = { name = L["curse of agony"], rank = 5, duration = 24, variable_duration = true },
[11713] = { name = L["curse of agony"], rank = 6, duration = 24, variable_duration = true },
[980] = { name = L["curse of agony"], rank = 1, duration = 24, variableDuration = true, darkHarvest = true, numTicks=12 },
[1014] = { name = L["curse of agony"], rank = 2, duration = 24, variableDuration = true, darkHarvest = true, numTicks=12 },
[6217] = { name = L["curse of agony"], rank = 3, duration = 24, variableDuration = true, darkHarvest = true, numTicks=12 },
[11711] = { name = L["curse of agony"], rank = 4, duration = 24, variableDuration = true, darkHarvest = true, numTicks=12 },
[11712] = { name = L["curse of agony"], rank = 5, duration = 24, variableDuration = true, darkHarvest = true, numTicks=12 },
[11713] = { name = L["curse of agony"], rank = 6, duration = 24, variableDuration = true, darkHarvest = true, numTicks=12 },
[18265] = { name = L["siphon life"], rank = 1, duration = 30, variableDuration = true, darkHarvest = true, numTicks=10 },
[18879] = { name = L["siphon life"], rank = 2, duration = 30, variableDuration = true, darkHarvest = true, numTicks=10 },
[18880] = { name = L["siphon life"], rank = 3, duration = 30, variableDuration = true, darkHarvest = true, numTicks=10 },
[18881] = { name = L["siphon life"], rank = 4, duration = 30, variableDuration = true, darkHarvest = true, numTicks=10 },
[52550] = { name = L["dark harvest"], rank = 1, duration = 8, variableDuration = true },
[52551] = { name = L["dark harvest"], rank = 2, duration = 8, variableDuration = true },
[52552] = { name = L["dark harvest"], rank = 3, duration = 8, variableDuration = true },
[603] = { name = L["curse of doom"], rank = 1, duration = 60 },
@@ -58,11 +67,6 @@ function getWarlockSpells()
[710] = { name = L["banish"], rank = 1, duration = 20 },
[18647] = { name = L["banish"], rank = 2, duration = 30 },
[18265] = { name = L["siphon life"], rank = 1, duration = 30, variable_duration = true },
[18879] = { name = L["siphon life"], rank = 2, duration = 30, variable_duration = true },
[18880] = { name = L["siphon life"], rank = 3, duration = 30, variable_duration = true },
[18881] = { name = L["siphon life"], rank = 4, duration = 30, variable_duration = true },
[5782] = { name = L["fear"], rank = 1, duration = 10 },
[6213] = { name = L["fear"], rank = 2, duration = 15 },
[6215] = { name = L["fear"], rank = 3, duration = 20 },