mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
pfui nameplate tank list support for targeting conditional
This commit is contained in:
+164
-4
@@ -2198,6 +2198,110 @@ function CleveRoids.GetCountModeArgs(conditionalValue)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- PFUI TANK INTEGRATION
|
||||
-- ============================================================================
|
||||
-- Integrates with pfUI's tank systems for targeting loose mobs
|
||||
-- Checks BOTH:
|
||||
-- 1. pfUI.uf.raid.tankrole (raid frame right-click toggle)
|
||||
-- 2. pfUI_config.nameplates.combatofftanks (nameplate off-tank names setting)
|
||||
|
||||
-- Cache for parsed nameplate off-tank names (lowercase)
|
||||
local pfUIOfftankCache = nil
|
||||
local pfUIOfftankCacheTime = 0
|
||||
|
||||
--- Parse pfUI nameplate off-tank names setting into a lookup table
|
||||
--- @return table Lowercase name -> true lookup
|
||||
local function GetPfUIOfftanks()
|
||||
-- Cache for 5 seconds to avoid repeated string parsing
|
||||
local now = GetTime()
|
||||
if pfUIOfftankCache and (now - pfUIOfftankCacheTime) < 5 then
|
||||
return pfUIOfftankCache
|
||||
end
|
||||
|
||||
pfUIOfftankCache = {}
|
||||
pfUIOfftankCacheTime = now
|
||||
|
||||
-- Check pfUI_config.nameplates.combatofftanks (# separated list)
|
||||
if type(pfUI_config) == "table" and
|
||||
type(pfUI_config.nameplates) == "table" and
|
||||
type(pfUI_config.nameplates.combatofftanks) == "string" then
|
||||
local list = pfUI_config.nameplates.combatofftanks
|
||||
-- pfUI uses # as separator: "#Name1#Name2#Name3"
|
||||
for name in string.gfind(list, "[^#]+") do
|
||||
name = string.gsub(name, "^%s*(.-)%s*$", "%1") -- trim whitespace
|
||||
if name ~= "" then
|
||||
pfUIOfftankCache[string.lower(name)] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return pfUIOfftankCache
|
||||
end
|
||||
|
||||
--- Check if pfUI tank data is available (either source)
|
||||
--- @return boolean True if any pfUI tank system is accessible
|
||||
function CleveRoids.HasPfUITanks()
|
||||
-- Check raid frame tankrole
|
||||
local hasRaidTanks = type(pfUI) == "table" and
|
||||
type(pfUI.uf) == "table" and
|
||||
type(pfUI.uf.raid) == "table" and
|
||||
type(pfUI.uf.raid.tankrole) == "table"
|
||||
|
||||
-- Check nameplate off-tank config
|
||||
local hasNameplateTanks = type(pfUI_config) == "table" and
|
||||
type(pfUI_config.nameplates) == "table" and
|
||||
type(pfUI_config.nameplates.combatofftanks) == "string" and
|
||||
pfUI_config.nameplates.combatofftanks ~= ""
|
||||
|
||||
return hasRaidTanks or hasNameplateTanks
|
||||
end
|
||||
|
||||
--- Check if a player is marked as a tank in pfUI (either source)
|
||||
--- @param name string - Player name to check
|
||||
--- @return boolean True if player is marked as tank
|
||||
function CleveRoids.IsPlayerTank(name)
|
||||
if not name then return false end
|
||||
|
||||
-- Check raid frame tankrole (exact case)
|
||||
if type(pfUI) == "table" and
|
||||
type(pfUI.uf) == "table" and
|
||||
type(pfUI.uf.raid) == "table" and
|
||||
type(pfUI.uf.raid.tankrole) == "table" and
|
||||
pfUI.uf.raid.tankrole[name] then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check nameplate off-tank names (lowercase comparison)
|
||||
local offtanks = GetPfUIOfftanks()
|
||||
if offtanks[string.lower(name)] then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Check if a unit is targeting any player marked as tank
|
||||
--- @param unit string - Unit token to check (e.g., "target")
|
||||
--- @return boolean True if unit's target is a tank
|
||||
function CleveRoids.IsTargetingAnyTank(unit)
|
||||
-- Default to "target" if unit is nil
|
||||
unit = unit or "target"
|
||||
|
||||
-- Get the unit's target
|
||||
local targetOfUnit = unit .. "target"
|
||||
if not UnitExists(targetOfUnit) then
|
||||
return false
|
||||
end
|
||||
|
||||
local targetName = UnitName(targetOfUnit)
|
||||
if not targetName then
|
||||
return false
|
||||
end
|
||||
|
||||
return CleveRoids.IsPlayerTank(targetName)
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- CURSIVE ADDON INTEGRATION
|
||||
-- ============================================================================
|
||||
@@ -5098,15 +5202,41 @@ CleveRoids.Keywords = {
|
||||
return true
|
||||
end,
|
||||
|
||||
-- [targeting:unit] - Target is targeting specified unit
|
||||
-- [targeting:tank] - Target is targeting ANY player marked as tank in pfUI
|
||||
targeting = function(conditionals)
|
||||
return Or(conditionals.targeting, function (unit)
|
||||
return (UnitIsUnit("targettarget", unit) == 1)
|
||||
local target = conditionals.target or "target"
|
||||
|
||||
-- Handle single "tank" keyword directly (most common case)
|
||||
local val = conditionals.targeting
|
||||
if val == "tank" or (type(val) == "table" and val[1] == "tank" and not val[2]) then
|
||||
return CleveRoids.IsTargetingAnyTank(target)
|
||||
end
|
||||
|
||||
return Or(val, function (unit)
|
||||
if unit == "tank" then
|
||||
return CleveRoids.IsTargetingAnyTank(target)
|
||||
end
|
||||
return (UnitIsUnit(target .. "target", unit) == 1)
|
||||
end)
|
||||
end,
|
||||
|
||||
-- [notargeting:unit] - Target is NOT targeting specified unit
|
||||
-- [notargeting:tank] - Target is NOT targeting ANY tank (loose mob!)
|
||||
notargeting = function(conditionals)
|
||||
return NegatedMulti(conditionals.notargeting, function (unit)
|
||||
return UnitIsUnit("targettarget", unit) ~= 1
|
||||
local target = conditionals.target or "target"
|
||||
|
||||
-- Handle single "tank" keyword directly (most common case)
|
||||
local val = conditionals.notargeting
|
||||
if val == "tank" or (type(val) == "table" and val[1] == "tank" and not val[2]) then
|
||||
return not CleveRoids.IsTargetingAnyTank(target)
|
||||
end
|
||||
|
||||
return NegatedMulti(val, function (unit)
|
||||
if unit == "tank" then
|
||||
return not CleveRoids.IsTargetingAnyTank(target)
|
||||
end
|
||||
return UnitIsUnit(target .. "target", unit) ~= 1
|
||||
end, conditionals, "notargeting")
|
||||
end,
|
||||
|
||||
@@ -5128,6 +5258,36 @@ CleveRoids.Keywords = {
|
||||
return UnitIsPlayer(conditionals.target)
|
||||
end,
|
||||
|
||||
-- [istank] - Target unit is marked as tank in pfUI
|
||||
-- [istank:unit] - Specified unit is marked as tank
|
||||
istank = function(conditionals)
|
||||
if conditionals.istank and type(conditionals.istank) == "table" then
|
||||
-- Check specific unit: [istank:focus]
|
||||
return Or(conditionals.istank, function(unit)
|
||||
local name = UnitName(unit)
|
||||
return CleveRoids.IsPlayerTank(name)
|
||||
end)
|
||||
end
|
||||
-- Check target: [istank]
|
||||
local target = conditionals.target or "target"
|
||||
local name = UnitName(target)
|
||||
return CleveRoids.IsPlayerTank(name)
|
||||
end,
|
||||
|
||||
-- [noistank] - Target unit is NOT marked as tank in pfUI
|
||||
noistank = function(conditionals)
|
||||
if conditionals.noistank and type(conditionals.noistank) == "table" then
|
||||
-- Check specific unit: [noistank:focus]
|
||||
return NegatedMulti(conditionals.noistank, function(unit)
|
||||
return not CleveRoids.IsPlayerTank(UnitName(unit))
|
||||
end, conditionals, "noistank")
|
||||
end
|
||||
-- Check target: [noistank]
|
||||
local target = conditionals.target or "target"
|
||||
local name = UnitName(target)
|
||||
return not CleveRoids.IsPlayerTank(name)
|
||||
end,
|
||||
|
||||
-- [inrange] or [inrange:Spell] - Target is in range of spell
|
||||
-- [inrange:Spell>N] - More than N enemies are in range of spell (count mode)
|
||||
inrange = function(conditionals)
|
||||
|
||||
@@ -5312,6 +5312,8 @@ SlashCmdList["CLEVEROID"] = function(msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid testtalent <spellID> - Test talent modifier for a spell')
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffffaa00Debuff Tracking Debug:|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid debuffdebug [spell] - Debug debuff tracking on target')
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffffaa00pfUI Tank Integration:|r")
|
||||
DEFAULT_CHAT_FRAME:AddMessage('/cleveroid tankdebug - Debug tank targeting conditionals')
|
||||
return
|
||||
end
|
||||
|
||||
@@ -5883,6 +5885,94 @@ SlashCmdList["CLEVEROID"] = function(msg)
|
||||
return
|
||||
end
|
||||
|
||||
-- tankdebug (debug pfUI tank integration)
|
||||
if cmd == "tankdebug" then
|
||||
CleveRoids.Print("=== Tank Debug ===")
|
||||
|
||||
-- Check pfUI availability
|
||||
if not CleveRoids.HasPfUITanks() then
|
||||
CleveRoids.Print("|cffff0000pfUI tank system not available!|r")
|
||||
CleveRoids.Print(" pfUI loaded: " .. tostring(type(pfUI) == "table"))
|
||||
CleveRoids.Print(" pfUI_config: " .. tostring(type(pfUI_config) == "table"))
|
||||
return
|
||||
end
|
||||
|
||||
CleveRoids.Print("|cff00ff00pfUI tank system available|r")
|
||||
|
||||
-- List raid frame tanks
|
||||
CleveRoids.Print(" ")
|
||||
CleveRoids.Print("|cffffaa00Raid Frame Tanks (right-click toggle):|r")
|
||||
local raidTankCount = 0
|
||||
if type(pfUI) == "table" and type(pfUI.uf) == "table" and
|
||||
type(pfUI.uf.raid) == "table" and type(pfUI.uf.raid.tankrole) == "table" then
|
||||
for name, isTank in pairs(pfUI.uf.raid.tankrole) do
|
||||
if isTank then
|
||||
CleveRoids.Print(" - " .. name)
|
||||
raidTankCount = raidTankCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
if raidTankCount == 0 then
|
||||
CleveRoids.Print(" (none)")
|
||||
end
|
||||
|
||||
-- List nameplate off-tank names
|
||||
CleveRoids.Print(" ")
|
||||
CleveRoids.Print("|cffffaa00Nameplate Off-Tank Names (config setting):|r")
|
||||
local npTankCount = 0
|
||||
if type(pfUI_config) == "table" and type(pfUI_config.nameplates) == "table" then
|
||||
local list = pfUI_config.nameplates.combatofftanks or ""
|
||||
if list ~= "" then
|
||||
CleveRoids.Print(" Raw setting: \"" .. list .. "\"")
|
||||
-- pfUI uses # as separator
|
||||
for name in string.gfind(list, "[^#]+") do
|
||||
name = string.gsub(name, "^%s*(.-)%s*$", "%1") -- trim
|
||||
if name ~= "" then
|
||||
CleveRoids.Print(" - " .. name .. " (lowercase: " .. string.lower(name) .. ")")
|
||||
npTankCount = npTankCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if npTankCount == 0 then
|
||||
CleveRoids.Print(" (none)")
|
||||
end
|
||||
|
||||
-- Check current target
|
||||
CleveRoids.Print(" ")
|
||||
CleveRoids.Print("|cffffaa00Current Target Check:|r")
|
||||
if not UnitExists("target") then
|
||||
CleveRoids.Print(" No target selected")
|
||||
else
|
||||
local targetName = UnitName("target") or "Unknown"
|
||||
CleveRoids.Print(" Your target: " .. targetName)
|
||||
|
||||
if UnitExists("targettarget") then
|
||||
local ttName = UnitName("targettarget") or "Unknown"
|
||||
CleveRoids.Print(" Target's target: " .. ttName)
|
||||
local isTank = CleveRoids.IsPlayerTank(ttName)
|
||||
if isTank then
|
||||
CleveRoids.Print(" |cff00ff00" .. ttName .. " IS marked as tank|r")
|
||||
else
|
||||
CleveRoids.Print(" |cffff8800" .. ttName .. " is NOT marked as tank|r")
|
||||
CleveRoids.Print(" (lowercase check: " .. string.lower(ttName) .. ")")
|
||||
end
|
||||
else
|
||||
CleveRoids.Print(" Target's target: (none)")
|
||||
end
|
||||
|
||||
-- Test the conditional functions
|
||||
CleveRoids.Print(" ")
|
||||
CleveRoids.Print("|cffffaa00Conditional Results:|r")
|
||||
local isTargetingTank = CleveRoids.IsTargetingAnyTank("target")
|
||||
CleveRoids.Print(" IsTargetingAnyTank('target'): " .. tostring(isTargetingTank))
|
||||
CleveRoids.Print(" [targeting:tank] would be: " .. tostring(isTargetingTank))
|
||||
CleveRoids.Print(" [notargeting:tank] would be: " .. tostring(not isTargetingTank))
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- Unknown command fallback
|
||||
CleveRoids.Print("Usage:")
|
||||
DEFAULT_CHAT_FRAME:AddMessage("/cleveroid - Show current settings")
|
||||
|
||||
@@ -132,7 +132,8 @@ All conditionals support negation with `no` prefix (e.g., `[nocombat]`, `[nobuff
|
||||
| `type` | `[type:Undead/Beast]` | Creature type |
|
||||
| `isplayer` | `[isplayer]` | Target is a player |
|
||||
| `isnpc` | `[isnpc]` | Target is an NPC |
|
||||
| `targeting` | `[targeting:player]` | Unit targeting you |
|
||||
| `targeting` | `[targeting:player]` `[targeting:tank]` | Unit targeting you / any tank |
|
||||
| `istank` | `[istank]` `[@focus,istank]` | Unit is marked as tank (pfUI) |
|
||||
| `casting` | `[casting:"Spell"]` | Unit casting spell |
|
||||
| `party` | `[party]` `[party:focus]` | Unit in your party |
|
||||
| `raid` | `[raid]` `[raid:mouseover]` | Unit in your raid |
|
||||
@@ -211,6 +212,50 @@ All conditionals support negation with `no` prefix (e.g., `[nocombat]`, `[nobuff
|
||||
| `tte` | TimeToKill | `[tte:<5]` | Time to execute (20% HP) |
|
||||
| `cursive` | Cursive | `[cursive:Rake>3]` | GUID debuff tracking |
|
||||
| `moving` | MonkeySpeed | `[moving:>100]` | Speed % (100=normal run) |
|
||||
| `targeting:tank` | pfUI | `[targeting:tank]` | Target is attacking any tank |
|
||||
| `istank` | pfUI | `[istank]` | Target is marked as tank |
|
||||
|
||||
### pfUI Tank Integration
|
||||
|
||||
Identify loose mobs in trash pulls by checking if enemies are targeting designated tanks. Works with pfUI's tank marking systems.
|
||||
|
||||
**Tank Conditionals:**
|
||||
| Conditional | Description |
|
||||
|-------------|-------------|
|
||||
| `[targeting:tank]` | Target IS attacking any player marked as tank |
|
||||
| `[notargeting:tank]` | Target is NOT attacking any tank (loose mob!) |
|
||||
| `[istank]` | Target unit IS marked as tank |
|
||||
| `[noistank]` | Target unit is NOT marked as tank |
|
||||
|
||||
**Setting Up Tanks in pfUI:**
|
||||
|
||||
1. **Nameplate Off-Tank Names** (recommended): `/pfui` → Nameplates → Off-Tank Names
|
||||
- Add tank names separated by `#`: `#TankName1#TankName2#TankName3`
|
||||
- These names will show different colored nameplates AND work with `[targeting:tank]`
|
||||
|
||||
2. **Raid Frame Toggle**: Right-click a player in raid frames → "Toggle as Tank"
|
||||
- Only works when raid frames are visible
|
||||
|
||||
**Example Macros:**
|
||||
```lua
|
||||
-- Pick up loose mobs (not targeting any tank)
|
||||
/cast [multiscan:nearest,notargeting:tank,harm] Taunt
|
||||
|
||||
-- Only taunt if mob is targeting you (tank)
|
||||
/cast [targeting:player] Sunder Armor
|
||||
|
||||
-- Assist tanks - attack what they're tanking
|
||||
/cast [multiscan:nearest,targeting:tank,harm] Sunder Armor
|
||||
|
||||
-- Emergency taunt on loose mob hitting a healer
|
||||
/cast [notargeting:tank,notargeting:player] Taunt
|
||||
```
|
||||
|
||||
**Debug Command:**
|
||||
```
|
||||
/cleveroid tankdebug
|
||||
```
|
||||
Shows all marked tanks, current target info, and conditional results.
|
||||
|
||||
### Warrior Slam Conditionals
|
||||
For optimizing Slam rotations without clipping auto-attacks:
|
||||
@@ -294,6 +339,7 @@ Scans enemies and soft-casts without changing your target. Requires UnitXP_SP3.
|
||||
/cast [multiscan:skull,harm] Eviscerate
|
||||
/cast [multiscan:markorder] Sinister Strike
|
||||
/cast [multiscan:highesthp,noimmune:stun] Cheap Shot
|
||||
/cast [multiscan:nearest,notargeting:tank,harm] Taunt -- Pick up loose mobs (pfUI)
|
||||
```
|
||||
|
||||
**Priorities:**
|
||||
|
||||
Reference in New Issue
Block a user