Add files via upload
This commit is contained in:
+1
-1
@@ -1465,7 +1465,7 @@ function BNP:CreateOptions()
|
||||
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetText("Inactive Combat Color", 1, 0.82, 0)
|
||||
GameTooltip:AddLine("Uses a third color only for enemies in combat that are temporarily unable to attack (fear, sheep, stuns or fleeing). Idle enemies are excluded.", 1, 1, 1, true)
|
||||
GameTooltip:AddLine("Requires a confirmed CC or fleeing state, even if the enemy still has a target. Losing a target alone does not change the color. Independent of Invert Tank Colors.", 0.8, 0.8, 0.8, true)
|
||||
GameTooltip:AddLine("Detects active CC and fleeing states. Also treats living enemies in combat at 30% health or less with no target as likely fleeing. Idle enemies and corpses are excluded. Independent of Invert Tank Colors.", 0.8, 0.8, 0.8, true)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
noTarget:SetScript("OnLeave", function() GameTooltip:Hide() end)
|
||||
|
||||
+7
-3
@@ -2340,7 +2340,7 @@ local function CaptureLiveDebuffSnapshot(unit, now)
|
||||
local auraName, texture, stacks, dtype, duration, expirationTime, source,
|
||||
isStealable, nameplateShowPersonal, auraSpellID =
|
||||
BNP._ClassicUnitAuraBySlot(unit, slots[i])
|
||||
if auraName then
|
||||
if auraName or (auraSpellID and auraSpellID > 0) then
|
||||
count = count + 1
|
||||
local entry = entries[count]
|
||||
if not entry then
|
||||
@@ -2937,20 +2937,24 @@ function BNP:CacheTankControlSnapshot(plate, guid, snapshot)
|
||||
or not self:IsTankModeEnabled() then
|
||||
plate.BNPTankControlGUID = nil
|
||||
plate.BNPTankControlled = nil
|
||||
plate.BNPTankChargeStun = nil
|
||||
return
|
||||
end
|
||||
local controlled = false
|
||||
local controlled, chargeStun = false, false
|
||||
local i
|
||||
for i = 1, snapshot.count do
|
||||
local entry = snapshot.entries[i]
|
||||
local def = ResolveGlobalCCDef(entry[4], entry[10])
|
||||
if def and self.TankDisablingCC and self.TankDisablingCC[def.key] then
|
||||
controlled = true
|
||||
break
|
||||
-- The applied Charge stun can arrive before the combat flag. It is
|
||||
-- itself evidence of an opening attack; a cast attempt alone is not.
|
||||
if def.key == "charge_stun" then chargeStun = true; break end
|
||||
end
|
||||
end
|
||||
plate.BNPTankControlGUID = guid
|
||||
plate.BNPTankControlled = controlled
|
||||
plate.BNPTankChargeStun = chargeStun
|
||||
end
|
||||
|
||||
-- One initial read when enabling the option on an already visible plate.
|
||||
|
||||
@@ -967,14 +967,16 @@ local function InstallAlphaGuard(plate)
|
||||
-- query inside ApplyForeignTagVisual is already cached to 10 Hz.
|
||||
ApplyForeignTagVisual(current)
|
||||
|
||||
-- Native projection can reset the raid icon anchor on any frame. Correct
|
||||
-- visible marks before rendering; the Y-offset loop leaves their anchors
|
||||
-- to raidmarks.lua. This only compares existing geometry, with no unit or
|
||||
-- aura queries, and skips plates whose native raid icon is hidden.
|
||||
if BNP.MaintainRaidMarkPosition then BNP:MaintainRaidMarkPosition(current) end
|
||||
|
||||
current.BNPVisualGuardElapsed = (current.BNPVisualGuardElapsed or 0) + (arg1 or 0)
|
||||
if current.BNPVisualGuardElapsed >= 0.05 then
|
||||
current.BNPVisualGuardElapsed = 0
|
||||
|
||||
-- Blizzard and the scale/Y-offset wrapper may restore the native raid icon
|
||||
-- anchor while the plate is being projected. Reapply the optional custom
|
||||
-- Raid Mark position on the throttled safety pass.
|
||||
if BNP.MaintainRaidMarkPosition then BNP:MaintainRaidMarkPosition(current) end
|
||||
if BNP.MaintainTargetScale then BNP:MaintainTargetScale(current) end
|
||||
ApplyTargetGlow(current)
|
||||
ApplyTargetArrows(current)
|
||||
|
||||
+10
-1
@@ -47,6 +47,13 @@ function BNP:ApplyRaidMarkPosition(plate)
|
||||
local point, relativeTo, relativePoint, x, y = GetCustomAnchor(plate, position)
|
||||
if not point or not relativeTo then return end
|
||||
|
||||
-- Keep the native icon with the scaled plate visuals if the client restores
|
||||
-- its parent. This preserves the same scaling and alpha as the healthbar.
|
||||
local wrapper = plate.BNPScaleWrapper
|
||||
if wrapper and icon.GetParent and icon.SetParent and icon:GetParent() ~= wrapper then
|
||||
icon:SetParent(wrapper)
|
||||
end
|
||||
|
||||
if not PointMatches(icon, point, relativeTo, relativePoint, x, y) then
|
||||
if not icon.ClearAllPoints or not icon.SetPoint then return end
|
||||
icon:ClearAllPoints()
|
||||
@@ -60,7 +67,9 @@ function BNP:MaintainRaidMarkPosition(plate)
|
||||
if not plate or not plate.IsShown or not plate:IsShown() then return end
|
||||
local icon = plate.raidicon
|
||||
if not icon then return end
|
||||
-- This path runs from the per-frame plate guard. Most plates have no active
|
||||
-- This path runs after native/offset updates on EVERY rendered frame. A
|
||||
-- throttled repair leaves the native anchor visible between repairs.
|
||||
-- Most plates have no active
|
||||
-- raid mark, so avoid GetPoint/anchor comparisons until Blizzard actually
|
||||
-- shows the icon. The first visible frame will still be corrected instantly.
|
||||
if icon.IsShown and not icon:IsShown() then return end
|
||||
|
||||
+7
-1
@@ -604,7 +604,13 @@ function BNP:MaintainNameplateYOffset(plate)
|
||||
local states = wrapper.BNPAnchorStates or {}
|
||||
local i
|
||||
for i = 1, table.getn(states) do
|
||||
RestoreAnchorState(states[i], wrapper)
|
||||
local state = states[i]
|
||||
-- Raid marks own their custom Top/Left/Right anchor. Restoring the native
|
||||
-- anchor here every frame fights raidmarks.lua and makes the icon jump
|
||||
-- between both positions whenever the nameplate Y offset is enabled.
|
||||
if state.object ~= plate.raidicon or not self.MaintainRaidMarkPosition then
|
||||
RestoreAnchorState(state, wrapper)
|
||||
end
|
||||
end
|
||||
|
||||
ApplyWrapperOffset(plate, wrapper)
|
||||
|
||||
+38
-14
@@ -35,27 +35,32 @@ local function HasCachedControl(plate, guid, now)
|
||||
BNP:PrimeTankControlSnapshot(plate, guid, now)
|
||||
end
|
||||
if plate.BNPTankControlGUID == guid and plate.BNPClassicAuraEventDriven then
|
||||
return plate.BNPTankControlled and true or false
|
||||
return plate.BNPTankControlled and true or false, plate.BNPTankChargeStun and true or false
|
||||
end
|
||||
local cache = BNP.guidAuras and BNP.guidAuras[guid]
|
||||
local controlled = false
|
||||
local key, aura
|
||||
if cache then
|
||||
for key, aura in pairs(cache) do
|
||||
if BNP.TankDisablingCC[key] and aura.expires and aura.expires > now then return true end
|
||||
if BNP.TankDisablingCC[key] and aura.expires and aura.expires > now then
|
||||
controlled = true
|
||||
if key == "charge_stun" then return true, true end
|
||||
end
|
||||
end
|
||||
end
|
||||
cache = BNP.guidLiveCCs and BNP.guidLiveCCs[guid]
|
||||
if cache then
|
||||
for key, aura in pairs(cache) do
|
||||
if BNP.TankDisablingCC[key] and (aura.eventDriven or now - (aura.lastSeen or 0) <= 0.60) then
|
||||
return true
|
||||
controlled = true
|
||||
if key == "charge_stun" and aura.expires and aura.expires > now then return true, true end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
return controlled, false
|
||||
end
|
||||
|
||||
local function IsTemporarilyInactive(plate, guid, now)
|
||||
local function IsTemporarilyInactive(plate, guid, now, targetExists)
|
||||
-- One optional descriptor read covers combat, stun, confusion and fleeing,
|
||||
-- including low-health fleeing with a retained target. No tooltip/aura scan.
|
||||
local flags
|
||||
@@ -66,13 +71,29 @@ local function IsTemporarilyInactive(plate, guid, now)
|
||||
local inCombat
|
||||
if flags then inCombat = HasFlag(flags, 524288)
|
||||
else inCombat = UnitAffectingCombat and UnitAffectingCombat(guid) end
|
||||
if not inCombat then return false end
|
||||
if not inCombat then
|
||||
-- Do not wait for the combat flag when the actual opening Charge stun
|
||||
-- is already in the harmful-aura snapshot. Pre-pull sheep/sap stay out.
|
||||
local controlled, chargeStun = HasCachedControl(plate, guid, now)
|
||||
return controlled and chargeStun
|
||||
end
|
||||
if flags and (HasFlag(flags, 262144) or HasFlag(flags, 4194304) or HasFlag(flags, 8388608)) then
|
||||
return true
|
||||
end
|
||||
-- A missing target alone is not evidence of CC or fleeing. It also occurs
|
||||
-- during death, pet return and ordinary target switches.
|
||||
return HasCachedControl(plate, guid, now)
|
||||
if HasCachedControl(plate, guid, now) then return true end
|
||||
|
||||
-- Fleeing to seek assistance can clear the target without a CC aura or a
|
||||
-- fleeing flag, and GetUnitField is optional (Nampower). Keep this fallback
|
||||
-- deliberately narrow: in combat, no target, alive, <= 30% HP, not casting.
|
||||
-- This is a heuristic, not proof of fleeing. No per-frame scan or timer.
|
||||
if targetExists or not UnitHealth or not UnitHealthMax then return false end
|
||||
local health = UnitHealth(guid)
|
||||
if not health or health <= 0 then return false end
|
||||
local maximum = UnitHealthMax(guid)
|
||||
if not maximum or maximum <= 0 or health / maximum > 0.30 then return false end
|
||||
if UnitCastingInfo and UnitCastingInfo(guid) then return false end
|
||||
if UnitChannelInfo and UnitChannelInfo(guid) then return false end
|
||||
return true
|
||||
end
|
||||
|
||||
local playerGUID = nil
|
||||
@@ -99,10 +120,11 @@ local function GetPlateGUID(plate)
|
||||
end
|
||||
|
||||
local function GetTargetGUID(guid)
|
||||
if not guid then return nil end
|
||||
if not guid then return nil, false end
|
||||
local exists, targetGUID = UnitExists(guid .. "target")
|
||||
if exists then return targetGUID end
|
||||
return nil
|
||||
-- An existing target whose GUID is temporarily unavailable is not "none".
|
||||
if exists then return targetGUID, true end
|
||||
return nil, false
|
||||
end
|
||||
|
||||
local function GetBar(plate)
|
||||
@@ -246,9 +268,9 @@ function BNP:UpdateTankModePlate(plate)
|
||||
local myGUID = GetPlayerGUID()
|
||||
if not myGUID then return end
|
||||
|
||||
local targetGUID = GetTargetGUID(guid)
|
||||
local targetGUID, targetExists = GetTargetGUID(guid)
|
||||
local now = thirdColor and GetTime()
|
||||
if thirdColor and IsTemporarilyInactive(plate, guid, now) then
|
||||
if thirdColor and IsTemporarilyInactive(plate, guid, now, targetExists) then
|
||||
local r, g, b = self:GetTankNoTargetColor()
|
||||
ApplyTankColor(plate, bar, r, g, b)
|
||||
plate.BNPTankNoTargetActive = true
|
||||
@@ -298,6 +320,7 @@ function BNP:UpdateTankMode()
|
||||
for plate in pairs(self.plates or {}) do
|
||||
plate.BNPTankControlGUID = nil
|
||||
plate.BNPTankControlled = nil
|
||||
plate.BNPTankChargeStun = nil
|
||||
end
|
||||
end
|
||||
self:RefreshTankMode()
|
||||
@@ -339,6 +362,7 @@ function BNP:InstallTankMode()
|
||||
ClearTankState(current)
|
||||
current.BNPTankControlGUID = nil
|
||||
current.BNPTankControlled = nil
|
||||
current.BNPTankChargeStun = nil
|
||||
BNP:UpdateTankModePlate(current)
|
||||
end)
|
||||
|
||||
|
||||
@@ -78,6 +78,9 @@ BNP.WarriorAuras = {
|
||||
{
|
||||
key = "charge_stun",
|
||||
names = { "Charge Stun" },
|
||||
-- The harmful stun, not the Charge cast (100 / 6178 / 11578).
|
||||
-- Match even before a localized aura name is available.
|
||||
spellIDs = { 7922 },
|
||||
duration = 1,
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user