Add files via upload

This commit is contained in:
Wurmschwanz
2026-10-30 19:29:29 +01:00
committed by GitHub
parent a9d9385003
commit 69a39b5709
4 changed files with 107 additions and 22 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
## Notes: Lightweight personal debuffs and class colors for Blizzard nameplates. Requires SuperWoW and ClassicAPI.
## Author: Wurmschwanz; nameplate discovery inspired by Shagu's Vanilla projects
## OptionalDeps: ShaguTweaks
## Version: 2.0.1
## Version: 2.0.2
## SavedVariablesPerCharacter: BNP_DB
core\core.lua
+1 -1
View File
@@ -1,5 +1,5 @@
BNP = BNP or {}
BNP.version = "2.0.1"
BNP.version = "2.0.2"
BNP.plates = BNP.plates or {}
BNP.detected = 0
BNP.debugEnabled = false
+104 -19
View File
@@ -124,10 +124,9 @@ end
local function SetCastbarSpark(bar, state, alpha)
if not bar or not bar.spark then return end
-- BNP stretches the StatusBar between two anchors instead of assigning a
-- fixed SetWidth like ShaguTweaks does. On the Vanilla 1.12 client GetWidth()
-- can lag behind / disagree with that anchor-defined render width. Keep the
-- exact logical width calculated from the same healthbar anchors instead.
-- On the Vanilla 1.12 client GetWidth() can lag a layout update.
-- Use the validated fixed logical width also used by the castbar itself,
-- never a transient/projected healthbar measurement.
local minValue, maxValue = bar:GetMinMaxValues()
local currentValue = bar:GetValue() or minValue or 0
minValue = minValue or 0
@@ -212,24 +211,77 @@ local function GetCastbarEndExtension(plate)
return 0
end
local function ApplyCastbarLayout(plate, bar)
-- Occasionally the projected Blizzard healthbar reports transitional geometry
-- when its nameplate moves/recycles. Do not let one bad width stretch the castbar
-- across the screen or displace its progress spark. Dimensions here are local
-- frame units; the normal nameplate/target scale still comes from the wrapper.
local CAST_MIN_HEALTH_WIDTH = 25
local CAST_MAX_HEALTH_WIDTH = 400
local CAST_WIDTH_JUMP_FACTOR = 1.50
local CAST_FALLBACK_HEALTH_WIDTH = 110
local function GetSafeHealthbarWidth(plate, bar)
if not plate or not plate.healthbar or not bar then return CAST_FALLBACK_HEALTH_WIDTH end
local measured = plate.healthbar:GetWidth()
local previous = bar.BNPStableHealthWidth
local wrapper = plate.BNPScaleWrapper
local originalWidth = wrapper and wrapper.originalWidth
-- Reject an oversized FIRST measurement too: otherwise the bad value
-- itself would be cached as the reference for all subsequent casts.
local firstWidthPlausible = previous or
type(originalWidth) ~= "number" or
originalWidth < 80 or originalWidth > CAST_MAX_HEALTH_WIDTH or
(type(measured) == "number" and measured <= originalWidth * 2)
if type(measured) == "number" and
measured >= CAST_MIN_HEALTH_WIDTH and measured <= CAST_MAX_HEALTH_WIDTH and
firstWidthPlausible and
(not previous or
(measured >= (previous / CAST_WIDTH_JUMP_FACTOR) and
measured <= (previous * CAST_WIDTH_JUMP_FACTOR))) then
bar.BNPStableHealthWidth = measured
return measured
end
if previous then return previous end
-- Even the first cast on a newly projected nameplate can land on a bad
-- geometry frame. The original plate width is a better fallback than the
-- transient healthbar width; if missing, use a Classic-sized default.
local fallback = originalWidth
if type(fallback) ~= "number" or
fallback < CAST_MIN_HEALTH_WIDTH or fallback > CAST_MAX_HEALTH_WIDTH then
fallback = CAST_FALLBACK_HEALTH_WIDTH
end
return fallback
end
local function ApplyCastbarLayout(plate, bar, healthWidth)
if not plate or not plate.healthbar or not bar then return end
local gap = BAR_GAP + GetBottomAuraClearance(plate)
local xOffset = GetCastbarXOffset()
local yOffset = GetCastbarYOffset()
local barStartOffset = GetCastbarStartOffset()
local endExtension = GetCastbarEndExtension(plate)
healthWidth = healthWidth or GetSafeHealthbarWidth(plate, bar)
-- A recycled plate may have received the wrapper AFTER the castbar was
-- created. Both castbar and icon must inherit the exact same parent scale.
local parent = plate.BNPScaleWrapper or plate
if bar:GetParent() ~= parent then bar:SetParent(parent) end
if bar.icon and bar.icon:GetParent() ~= parent then bar.icon:SetParent(parent) end
-- Anchor only the left edge and set a validated logical width explicitly.
-- The old dual-edge TOPLEFT/TOPRIGHT stretch followed bad healthbar geometry
-- during projection/movement, sometimes leaving a huge castbar for one unit.
local renderWidth = healthWidth + endExtension - barStartOffset
if renderWidth < 1 then renderWidth = 1 end
bar:ClearAllPoints()
bar:SetPoint("TOPLEFT", plate.healthbar, "BOTTOMLEFT", barStartOffset + xOffset, -gap + yOffset)
bar:SetPoint("TOPRIGHT", plate.healthbar, "BOTTOMRIGHT", endExtension + xOffset, -gap + yOffset)
-- Store the width implied by those two anchors. xOffset cancels because it
-- moves both edges equally. This is also the exact travel distance for the
-- cast spark.
local healthWidth = plate.healthbar:GetWidth() or 0
bar.BNPRenderWidth = healthWidth + endExtension - barStartOffset
if bar.BNPRenderWidth < 0 then bar.BNPRenderWidth = 0 end
bar:SetWidth(renderWidth)
bar.BNPRenderWidth = renderWidth
bar.BNPLayoutHealthWidth = healthWidth
bar.BNPLayoutEndExtension = endExtension
if bar.icon then
bar.icon:ClearAllPoints()
@@ -326,12 +378,18 @@ local function CreateCastbar(plate)
local gap = BAR_GAP + GetBottomAuraClearance(plate)
local xOffset = GetCastbarXOffset()
local yOffset = GetCastbarYOffset()
-- Initial placement uses the same guarded one-edge geometry as all later
-- layout updates. Never stretch the first frame between two live anchors.
local initialStartOffset = GetCastbarStartOffset()
local initialHealthWidth = GetSafeHealthbarWidth(plate, bar)
local initialEndExtension = GetCastbarEndExtension(plate)
local initialRenderWidth = initialHealthWidth + initialEndExtension - initialStartOffset
if initialRenderWidth < 1 then initialRenderWidth = 1 end
bar:SetPoint("TOPLEFT", plate.healthbar, "BOTTOMLEFT", initialStartOffset + xOffset, -gap + yOffset)
bar:SetPoint("TOPRIGHT", plate.healthbar, "BOTTOMRIGHT", 14 + xOffset, -gap + yOffset)
local initialHealthWidth = plate.healthbar:GetWidth() or 0
bar.BNPRenderWidth = initialHealthWidth + 14 - initialStartOffset
if bar.BNPRenderWidth < 0 then bar.BNPRenderWidth = 0 end
bar:SetWidth(initialRenderWidth)
bar.BNPRenderWidth = initialRenderWidth
bar.BNPLayoutHealthWidth = initialHealthWidth
bar.BNPLayoutEndExtension = initialEndExtension
bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
bar:SetStatusBarColor(1.0, 0.8, 0.0)
bar:SetMinMaxValues(0, 1)
@@ -661,9 +719,36 @@ updater:SetScript("OnUpdate", function()
else
local bar = CreateCastbar(plate)
if bar then
-- Active bars already run through this updater. Check only their
-- lightweight geometry here; no additional nameplate scan is added.
-- Recover on the next frame when projected width/parent changes,
-- while rejecting any transient oversized healthbar measurement.
local bottomClearance = GetBottomAuraClearance(plate)
if bar.BNPBottomAuraClearance ~= bottomClearance then
ApplyCastbarLayout(plate, bar)
local healthWidth = GetSafeHealthbarWidth(plate, bar)
local endExtension = GetCastbarEndExtension(plate)
local expectedParent = plate.BNPScaleWrapper or plate
if bar.BNPBottomAuraClearance ~= bottomClearance or
bar.BNPLayoutHealthWidth ~= healthWidth or
bar.BNPLayoutEndExtension ~= endExtension or
bar:GetParent() ~= expectedParent or
(bar.icon and bar.icon:GetParent() ~= expectedParent) then
ApplyCastbarLayout(plate, bar, healthWidth)
end
-- Do not allow an external layout reset or reused nameplate frame
-- to leave the castbar/icon at a different local scale or height.
-- Normal target/nameplate scaling is inherited from the wrapper.
if bar:GetScale() ~= 1 then bar:SetScale(1) end
if bar.icon and bar.icon:GetScale() ~= 1 then bar.icon:SetScale(1) end
local desiredHeight = GetCastbarHeight()
if math.abs((bar:GetHeight() or 0) - desiredHeight) > 0.1 then
bar:SetHeight(desiredHeight)
end
local desiredWidth = bar.BNPRenderWidth or 1
local currentWidth = bar:GetWidth() or 0
if currentWidth > desiredWidth * 1.5 or
(currentWidth > 1 and currentWidth < desiredWidth / 1.5) then
bar:SetWidth(desiredWidth)
end
local name
+1 -1
View File
@@ -97,7 +97,7 @@ BNP.OtherDebuffDefs = {
{ key="judgementoflight", label="Judgement of Light", category="utility", duration=10,
spellIDs={20185,20344,20345,20346}, description="10s\nMelee attacks heal attacker for 61" },
{ key="judgementofwisdom", label="Judgement of Wisdom", category="utility", duration=10,
spellIDs={20186,20354,20355}, description="10s\nAttacks restore 33 mana to attacker" },
spellIDs={20186,20354,20355,51751,51752}, description="10s\nAttacks restore 33 mana to attacker" },
{ key="judgementofthecrusader", label="Judgement of the Crusader", category="utility", duration=10,
spellIDs={21183,20188,20300,20301,20302,20303}, description="10s\nIncreases Holy damage taken by 140 and Increases melee and ranged AP" },
},