add name filter option

This commit is contained in:
pepopo978
2024-12-13 17:14:58 -08:00
parent 49855bd341
commit 9d9c8a7c7e
3 changed files with 85 additions and 57 deletions
+2
View File
@@ -10,6 +10,7 @@ L:RegisterTranslations("enUS", function()
["Play a sound when a curse is about to expire."] = true,
["Allow out of combat targets to be multicursed. Would only consider using this solo to avoid potentially griefing raids/dungeons by pulling unintended mobs."] = true,
["Minimum HP for a target to be considered. Example usage minhp=10000. "] = true,
["Filter targets by name. Can be a partial match. If no match is found, the command will do nothing."] = true,
["Time threshold at which to allow refreshing a curse. Default is 0 seconds."] = true,
["Ignore the current target when choosing target for multicurse. Does not affect 'curse' command."] = true,
["/cursive curse <spellName:str>|<guid?:str>|<options?:List<str>>: Casts spell if not already on target/guid"] = true,
@@ -158,6 +159,7 @@ L:RegisterTranslations("zhCN", function()
["Play a sound when a curse is about to expire."] = "当诅咒即将到期时播放声音.\n 详细使用说明及示例请查看readme文件",
["Allow out of combat targets to be multicursed. Would only consider using this solo to avoid potentially griefing raids/dungeons by pulling unintended mobs."] = "允许战斗外目标被多重诅咒。只有在单人游戏中才会考虑使用这个选项,以避免在副本中意外拉到怪物而造成困扰.",
["Minimum HP for a target to be considered. Example usage minhp=10000. "] = "目标考虑的最小生命值。例如:minhp=10000.",
["Filter targets by name. Can be a partial match. If no match is found, the command will do nothing."] = "通过名称过滤目标。可以是部分匹配。如果没有找到匹配项,命令将不执行.",
["Time threshold at which to allow refreshing a curse. Default is 0 seconds."] = "允许刷新诅咒的时间阈值。默认是0秒.例如:refreshtime=2",
["Ignore the current target when choosing target for multicurse. Does not affect 'curse' command."] = "选择多重诅咒目标时忽略当前目标。不影响‘诅咒’命令。",
["/cursive curse <spellName:str>|<guid?:str>|<options?:List<str>>: Casts spell if not already on target/guid"] = "/cursive curse <法术名称>|<目标ID>|<选项列表,用半角逗号分隔>: 如果目标/ID身上没有此法术,目标ID可以是以下内容(mouseover), (player), (pet), (party)(%d), (partypet)(%d), (raid)(%d+), (raidpet)(%d+), (target), (targettarget)",
+3 -1
View File
@@ -78,14 +78,16 @@ All commands can take the following options separated by commas:
- `ignoretarget` : "Ignore the current target when choosing target for multicurse. Does not affect 'curse' command.",
- `minhp=<number>` : "Minimum HP for a target to be considered.",
- `refreshtime=<number>` : "Time threshold at which to allow refreshing a curse. Default is 0 seconds.",
- `name=<str>` : "Filter targets by name. Can be a partial match. If no match is found, the command will do nothing.",
EXAMPLE: `/cursive multicurse Corruption|HIGHEST_HP|warnings,resistsound,expiringsound,minhp=10000,refreshtime=2`
EXAMPLE: `/cursive multicurse Curse of Recklessness|RAID_MARK|name=Touched Warrior,resistsound,expiringsound`
## Important info
If you have my latest nampower, it will use the SpellInRange function from that to provide improved range checking.
All commands will prioritize targets within 28 yards of you first to have a better chance of being in range.
Otherwise, all commands will prioritize targets within 28 yards of you first to have a better chance of being in range.
All commands will ignore targets with the following CCs on them:
+80 -56
View File
@@ -11,6 +11,7 @@ local commandOptions = {
minhp = L["Minimum HP for a target to be considered. Example usage minhp=10000. "],
refreshtime = L["Time threshold at which to allow refreshing a curse. Default is 0 seconds."],
ignoretarget = L["Ignore the current target when choosing target for multicurse. Does not affect 'curse' command."],
name = L["Filter targets by name. Can be a partial match. If no match is found, the command will do nothing."],
}
local commands = {
@@ -54,6 +55,11 @@ local function parseOptions(optionsStr)
if refreshTime then
options["refreshtime"] = tonumber(refreshTime)
end
elseif option == "name" then
local _, _, name = string.find(optionsStr, "name=([%w%s]+)")
if name then
options["name"] = name
end
elseif string.find(optionsStr, option) then
options[option] = true
end
@@ -247,64 +253,72 @@ local function pickTarget(selectedPriority, spellNameNoRank, checkRange, options
if not options["ignoretarget"] or guid ~= currentTargetGuid then
-- check if in combat already or player is actively targeting the mob
if ignoreInFight or Cursive.filter.infight(guid) or guid == currentTargetGuid then
local passedRangeCheck = false
if IsSpellInRange then
-- use IsSpellInRange from nampower if available
local result = IsSpellInRange(spellNameNoRank, guid)
if result == -1 then
passedRangeCheck = checkRange == false or CheckInteractDistance(guid, 4) -- fallback to old range check
else -- 0 or 1
passedRangeCheck = result == 1
end
else
-- prioritize targets within 28 yards first to improve chances of being in range
passedRangeCheck = checkRange == false or CheckInteractDistance(guid, 4)
local passedNameCheck = true
if options["name"] then
local name = UnitName(guid)
passedNameCheck = string.find(name, options["name"])
end
if passedRangeCheck then
-- check if the target has the curse
if not Cursive.curses:HasCurse(spellNameNoRank, guid, refreshTime) and not isMobCrowdControlled(guid) then
local mobHp = UnitHealth(guid)
if not minHp or mobHp >= minHp then
local primaryValue = -1
local secondaryValue = -1
if selectedPriority == PRIORITY_HIGHEST_HP then
primaryValue = UnitHealth(guid) or 0
elseif selectedPriority == PRIORITY_RAID_MARK then
primaryValue = GetRaidTargetIndex(guid) or 0
elseif selectedPriority == PRIORITY_RAID_MARK_SQUARE then
primaryValue = GetSquarePrioRaidTargetIndex(guid)
elseif selectedPriority == PRIORITY_INVERSE_RAID_MARK then
primaryValue = -1 * (GetRaidTargetIndex(guid) or 9)
elseif selectedPriority == PRIORITY_HIGHEST_HP_RAID_MARK then
secondaryValue = GetRaidTargetIndex(guid) or 0
if secondaryValue > 0 and not seenRaidMark then
highestPrimaryValue = -10 -- reset highestPriorityValue if this is the first raid mark we've seen
seenRaidMark = true
end
primaryValue = UnitHealth(guid) or 0
elseif selectedPriority == PRIORITY_HIGHEST_HP_RAID_MARK_SQUARE then
secondaryValue = GetSquarePrioRaidTargetIndex(guid)
if secondaryValue > -2 and not seenRaidMark then
highestPrimaryValue = -10 -- reset highestPriorityValue if this is the first raid mark we've seen
seenRaidMark = true
end
primaryValue = UnitHealth(guid) or 0
elseif selectedPriority == PRIORITY_HIGHEST_HP_INVERSE_RAID_MARK then
secondaryValue = -1 * (GetRaidTargetIndex(guid) or 9)
if secondaryValue > -9 and not seenRaidMark then
highestPrimaryValue = -10 -- reset highestPriorityValue if this is the first raid mark we've seen
seenRaidMark = true
end
primaryValue = UnitHealth(guid) or 0
end
if primaryValue > highestPrimaryValue then
highestPrimaryValue = primaryValue
highestSecondaryValue = secondaryValue
targetedGuid = guid
elseif primaryValue == highestPrimaryValue and secondaryValue > highestSecondaryValue then
highestSecondaryValue = secondaryValue
targetedGuid = guid
if passedNameCheck then
local passedRangeCheck = false
if IsSpellInRange then
-- use IsSpellInRange from nampower if available
local result = IsSpellInRange(spellNameNoRank, guid)
if result == -1 then
passedRangeCheck = checkRange == false or CheckInteractDistance(guid, 4) -- fallback to old range check
else -- 0 or 1
passedRangeCheck = result == 1
end
else
-- prioritize targets within 28 yards first to improve chances of being in range
passedRangeCheck = checkRange == false or CheckInteractDistance(guid, 4)
end
if passedRangeCheck then
-- check if the target has the curse
if not Cursive.curses:HasCurse(spellNameNoRank, guid, refreshTime) and not isMobCrowdControlled(guid) then
local mobHp = UnitHealth(guid)
if not minHp or mobHp >= minHp then
local primaryValue = -1
local secondaryValue = -1
if selectedPriority == PRIORITY_HIGHEST_HP then
primaryValue = UnitHealth(guid) or 0
elseif selectedPriority == PRIORITY_RAID_MARK then
primaryValue = GetRaidTargetIndex(guid) or 0
elseif selectedPriority == PRIORITY_RAID_MARK_SQUARE then
primaryValue = GetSquarePrioRaidTargetIndex(guid)
elseif selectedPriority == PRIORITY_INVERSE_RAID_MARK then
primaryValue = -1 * (GetRaidTargetIndex(guid) or 9)
elseif selectedPriority == PRIORITY_HIGHEST_HP_RAID_MARK then
secondaryValue = GetRaidTargetIndex(guid) or 0
if secondaryValue > 0 and not seenRaidMark then
highestPrimaryValue = -10 -- reset highestPriorityValue if this is the first raid mark we've seen
seenRaidMark = true
end
primaryValue = UnitHealth(guid) or 0
elseif selectedPriority == PRIORITY_HIGHEST_HP_RAID_MARK_SQUARE then
secondaryValue = GetSquarePrioRaidTargetIndex(guid)
if secondaryValue > -2 and not seenRaidMark then
highestPrimaryValue = -10 -- reset highestPriorityValue if this is the first raid mark we've seen
seenRaidMark = true
end
primaryValue = UnitHealth(guid) or 0
elseif selectedPriority == PRIORITY_HIGHEST_HP_INVERSE_RAID_MARK then
secondaryValue = -1 * (GetRaidTargetIndex(guid) or 9)
if secondaryValue > -9 and not seenRaidMark then
highestPrimaryValue = -10 -- reset highestPriorityValue if this is the first raid mark we've seen
seenRaidMark = true
end
primaryValue = UnitHealth(guid) or 0
end
if primaryValue > highestPrimaryValue then
highestPrimaryValue = primaryValue
highestSecondaryValue = secondaryValue
targetedGuid = guid
elseif primaryValue == highestPrimaryValue and secondaryValue > highestSecondaryValue then
highestSecondaryValue = secondaryValue
targetedGuid = guid
end
end
end
end
@@ -349,6 +363,16 @@ function Cursive:Curse(spellName, targetedGuid, options)
end
end
if targetedGuid and options["name"] then
local name = UnitName(targetedGuid)
if not string.find(name, options["name"]) then
if options["warnings"] then
DEFAULT_CHAT_FRAME:AddMessage(curseNoTarget)
end
return
end
end
-- remove (Rank x) from spellName if it exists
local spellNameNoRank = string.gsub(spellName, "%(.+%)", "")