AnySCT 0.3.1
This commit is contained in:
@@ -24,7 +24,6 @@ AnySCT_STYLE = {
|
||||
fadeOutWord = 1.0, -- Miss / Dodge / Parry / Block ...
|
||||
fadeOutAbsorb = 0.09, -- "Absorb" is a quick flicker
|
||||
riseHeight = 120, -- px a normal text rises (engine: 2 world units; screen distance varies)
|
||||
critRiseFactor = 0, -- crits do not rise, they pop in place
|
||||
sizeScale = 0.018333, -- text pixel size = scale x screen diagonal (1024x768 -> 23 px)
|
||||
critSizeScale = 0.0275, -- crits (1024x768 -> 35 px)
|
||||
shadow = 0.002, -- shadow offset, fraction of the viewport per axis (down-right)
|
||||
@@ -230,6 +229,43 @@ S.ANCHOR_W, S.ANCHOR_H, S.ANCHOR_LABEL_SIZE, S.PLATE_LABEL_SIZE = 200, 30, 12, 1
|
||||
function S.EstTextWidth(text, size) return string.len(text) * size * 0.62 end
|
||||
-- Where anchor-mode damage lines start so they clear the box (and the list label above it).
|
||||
function S.AnchorLineOffset(showLabel) return showLabel and 16 or 2 end
|
||||
-- ---- stack geometry -------------------------------------------------------------------------
|
||||
-- A line occupies [bottom - suffixH, bottom + numberH]: the number sits on its anchor point, the
|
||||
-- suffix (spell / name) hangs below it. Crits are reserved at the peak of their size pop. A new line
|
||||
-- is inserted at the bottom; every older line of the same mob moves up by the new line's height plus
|
||||
-- the suffix height of the line directly above it, which is what makes the new line fit under it.
|
||||
function S.CritPeak(kf)
|
||||
local m = 1
|
||||
for i = 1, table.getn(kf) do if kf[i][2] > m then m = kf[i][2] end end
|
||||
return m
|
||||
end
|
||||
-- Distance of a line's anchor point from its start: the same rise rate for every line of a tower, so
|
||||
-- older lines (larger t) only ever move away from newer ones.
|
||||
function S.LineOffset(t, dur, rise, push) return t / dur * rise + push end
|
||||
function S.NumberHeight(base, isCrit, peak) return isCrit and base * peak or base end
|
||||
function S.SuffixHeight(base, hasSuffix)
|
||||
if not hasSuffix then return 0 end
|
||||
local sz = math.floor(base * 0.3)
|
||||
if sz < 10 then sz = 10 end
|
||||
return sz + 2
|
||||
end
|
||||
function S.StackAdvance(base, isCrit, peak, prevSuffixH)
|
||||
return S.NumberHeight(base, isCrit, peak) + (prevSuffixH or 0)
|
||||
end
|
||||
-- A crit of a tiny proc must not pop at full crit size: scale by the amount against the source's
|
||||
-- running average hit (0.5 .. 1).
|
||||
function S.CritFactor(amount, ref)
|
||||
if not ref or ref <= 0 then return 1 end
|
||||
local f = (amount or 0) / ref
|
||||
if f > 1 then return 1 end
|
||||
if f < 0.5 then return 0.5 end
|
||||
return f
|
||||
end
|
||||
function S.UpdateRef(ref, amount)
|
||||
if not ref then return amount end
|
||||
return ref + (amount - ref) * 0.1
|
||||
end
|
||||
|
||||
-- ---- merging identical attacks ---------------------------------------------------------------
|
||||
-- Is the result a word (Miss / Dodge / ...)? Same rule as S.Format.
|
||||
function S.IsWordResult(res, opt)
|
||||
@@ -370,6 +406,8 @@ if CreateFrame then
|
||||
local POOL_MAX = 100 -- slot tables only; FontStrings are created on first use (ensureFs)
|
||||
local critAnimated = S.CurveAnimated(STYLE.critKeyframes)
|
||||
local critActive = S.CurveActive(STYLE.critKeyframes)
|
||||
local avgHit = {} -- per source: running average hit, for the crit pop scale
|
||||
local critPeak = S.CritPeak(STYLE.critKeyframes)
|
||||
local GAP = 3 -- px between the plate top and the text
|
||||
|
||||
local anchor, float, listLabel
|
||||
@@ -548,13 +586,14 @@ if CreateFrame then
|
||||
if t < STYLE.fadeIn then a = t / STYLE.fadeIn end
|
||||
if t > s.fadeOut then a = a * (s.dur - t) / (s.dur - s.fadeOut) end
|
||||
local rise = s.rise
|
||||
-- crits rise with the tower like every other line: a line that stood still would
|
||||
-- let the newer, rising lines below it run into it
|
||||
if s.crit then
|
||||
rise = rise * STYLE.critRiseFactor
|
||||
if critAnimated then
|
||||
s.fs:SetTextHeight(s.base * S.KeyScale(STYLE.critKeyframes, t / s.dur))
|
||||
end
|
||||
end
|
||||
local off = (t / s.dur * rise + s.push) * s.dir
|
||||
local off = S.LineOffset(t, s.dur, rise, s.push) * s.dir
|
||||
s.fs:ClearAllPoints()
|
||||
if s.plate then
|
||||
needScan = true
|
||||
@@ -632,9 +671,26 @@ if CreateFrame then
|
||||
local base = S.TextSize(scale, factor, sw, sh)
|
||||
s.base = base * mul
|
||||
|
||||
-- older lines of the same mob move one text height away
|
||||
-- tiny crits (procs) pop smaller: scale by the amount against the source's running average hit
|
||||
local refKey = res.source or "?"
|
||||
if not isWord and res.kind ~= "heal" then
|
||||
if s.crit then s.base = s.base * S.CritFactor(res.amount, avgHit[refKey]) end
|
||||
avgHit[refKey] = S.UpdateRef(avgHit[refKey], res.amount or 0)
|
||||
end
|
||||
s.sfxH = S.SuffixHeight(s.base, suffix ~= nil)
|
||||
|
||||
-- older lines of the same mob make room for this line's real height (crit peak included) plus
|
||||
-- the suffix hanging below the line right above it
|
||||
local prevSfx, prevT = 0, nil
|
||||
for j = 1, POOL_MAX do
|
||||
if slots[j].active and slots[j].key == key then slots[j].push = slots[j].push + s.base end
|
||||
local m = slots[j]
|
||||
if m.active and m.key == key and j ~= i and (not prevT or m.t < prevT) then
|
||||
prevT, prevSfx = m.t, m.sfxH or 0
|
||||
end
|
||||
end
|
||||
local adv = S.StackAdvance(s.base, s.crit, critPeak, prevSfx)
|
||||
for j = 1, POOL_MAX do
|
||||
if slots[j].active and slots[j].key == key and j ~= i then slots[j].push = slots[j].push + adv end
|
||||
end
|
||||
|
||||
s.active = true
|
||||
|
||||
Reference in New Issue
Block a user