📄 statusbars.lua
字号:
);
end
-- show or hide frame
local function showFrame(frame, visible)
if visible then frame:Show(); else frame:Hide(); end
end
-- common text visibility update (for when settings changed)
local function updateTextVisibility(vars)
local p = option(vars, 'percentage');
showFrame(vars.text, option(vars, 'text') ~= '');
showFrame(vars.ptext, p ~= PercentageNone and option(vars, 'ptext') ~= '');
if p == PercentageLeft then
vars.ptext:SetPoint('CENTER', '$Parent', 'CENTER', -171, 1);
vars.ptext:SetJustifyH('RIGHT');
elseif p == PercentageRight then
vars.ptext:SetPoint('CENTER', '$Parent', 'CENTER', 170, 1);
vars.ptext:SetJustifyH('LEFT');
end
end
-- get the color a bar or text is supposed to have
local function getBarColor(vars, prefix)
local colt = vars[prefix .. 'colorrules'];
local rules = colt.rules;
local i;
for i = 1, table.getn(rules) do
local rule = rules[i];
c = rule(vars);
if c ~= nil then
return c;
end
end
return colt.default;
end
local function updateTextColors(vars)
local tc = getBarColor(vars, 't');
local pc = getBarColor(vars, 'p');
vars.text:SetTextColor(tc[1], tc[2], tc[3]);
vars.ptext:SetTextColor(pc[1], pc[2], pc[3]);
end
-- return a { r,g,b } table representing the color mentioned in the string
-- accepts named colors and rgb/rrggbb hexadecimal
local function parseColor(s)
if s == 'red' then
return { 1, 0, 0 };
elseif s == 'green' then
return { 0, 1, 0 };
elseif s == 'blue' then
return { 0, 0, 1 };
elseif s == 'cyan' then
return { 0, 1, 1 };
elseif s == 'magenta' then
return { 1, 0, 1 };
elseif s == 'yellow' then
return { 1, 1, 0 };
elseif s == 'orange' then
return { 1, 0.5, 0 };
elseif s == 'white' then
return { 1, 1, 1 };
elseif s == 'black' then
return { 0, 0, 0 };
else
local i,j, r,g,b = string.find(s, '^(%x)(%x)(%x)$');
if i then
return { tonumber(r, 16) / 15, tonumber(g, 16) / 15, tonumber(b, 16) / 15 };
end
i,j, r,g,b = string.find(s, '^(%x%x)(%x%x)(%x%x)$');
if i then
return { tonumber(r, 16) / 255, tonumber(g, 16) / 255, tonumber(b, 16) / 255 };
end
consolePrint(STATUSBARS_INVALID_COLOR .. s .. '".');
end
end
-- compile the color selection rules in the string
-- returns a table containing default color and rule functions
local function compileColorRules(colorstring)
local rules = {}
local ruleslist = { n = 0 }
-- for all spans
for span in string.gfind(colorstring, '([^%s]+)') do
-- find conditional color expression
local i,j, op, value, percentage, col = string.find(span, '^([<>=!~]=?)(%d+)(%%?):(%w+)$');
if i == nil then
-- no conditional, look for default color
i,j, col = string.find(span, '^(%w+)$');
if i == nil then
consolePrint(STATUSBARS_INVALID_COLOR .. colorstring .. '".');
return;
elseif rules.default ~= nil then
consolePrint(STATUSBARS_MULTIPLE_DEFAULT_COLOR .. colorstring .. '".');
return;
else
-- unique color found, set default if the color is valid
col = parseColor(col);
if col == nil then return end;
rules.default = col;
end
else
-- conditional found
col = parseColor(col);
if col == nil then return end;
-- create limit value getter
value = tonumber(value);
local get;
if percentage == '%' then
get = function(vars) return vars.lastFraction*100 end;
else
get = function(vars) return vars.lastValue end;
end
-- create comparison function
local cmp;
if op == '=' or op == '==' then
cmp = function(vars) return get(vars) == value end;
elseif op == '!=' or op == '~=' then
cmp = function(vars) return get(vars) ~= value end;
elseif op == '<' then
cmp = function(vars) return get(vars) < value end;
elseif op == '>' then
cmp = function(vars) return get(vars) > value end;
elseif op == '<=' then
cmp = function(vars) return get(vars) <= value end;
elseif op == '>=' then
cmp = function(vars) return get(vars) >= value end;
else
consolePrint(STATUSBARS_UNKNOWN_OPERATOR .. op .. '".');
return;
end
-- create final rule
local rule = function(vars)
if cmp(vars) then
return col;
end
end;
table.insert(ruleslist, rule);
end
end
-- check that there is a default color
if rules.default == nil then
consolePrint(STATUSBARS_NO_DEFAULT_COLOR .. colorstring .. '".');
return;
end
rules.rules = ruleslist;
return rules;
end
-- update background and flash texture
local function updateFlashDisplayCommon(vars, barvars)
local level = vars._flashLevel;
local extra = barvars._extraFlash or 0;
local sum = level + extra;
if sum > 0.01 then
-- set background color
barvars._flashActive = true;
local a = level*FlashBGAlpha + (1-level)*DefaultBGAlpha;
vars.frame:SetBackdropColor(level, 0, 0, a);
-- show flash overlay and update color
barvars.foverlay:SetVertexColor(level*FlashBGAlpha + extra, extra, extra);
barvars.foverlay:Show();
elseif barvars._flashActive ~= false then
-- reset background color and hide flash overlay
barvars._flashActive = false;
barvars.frame:SetBackdropColor(0, 0, 0, DefaultBGAlpha);
barvars.foverlay:Hide();
end
end
-- stop flashing immediately
local function abortFlashCommon(vars)
vars.flash = false;
vars._flashing = false;
vars._lastFlashTime = 0;
vars._flashLevel = 0;
vars:updateFlashDisplay();
end
-- update flashing background
local function updateFlashCommon(vars, force)
if vars._flashing or force then
local time = GetTime();
local d = time - vars._lastFlashTime;
if d < 0 or d > FlashDuration then
d = 0;
if vars.flash then
vars._lastFlashTime = time;
else
vars._flashing = false;
vars._lastFlashTime = 0;
vars._flashLevel = 0;
vars:updateFlashDisplay();
return;
end
end
local c = 1 - abs(d - FlashDuration*0.5) / (FlashDuration*0.5);
vars._flashLevel = c;
vars:updateFlashDisplay();
end
end
-- start flashing
local function startFlash(vars)
vars.flash = true;
vars._flashing = true;
vars:updateFlash();
end
-- stop flashing softly
local function stopFlash(vars)
vars.flash = false;
vars:updateFlash();
end
-- convenience function for updating all dynamic state of a bar
local function update(vars)
-- dummy version, replaced by update_real when settings are loaded
end
local function update_real(vars)
vars:onEvent(nil);
end
-- update bar to match new settings
local function updateSettings(vars)
vars.never = option(vars, 'enable') == EnableNever;
if vars.never then
tickingBars[vars] = nil;
end
local cs = option(vars, 'color');
if cs then
vars.colorrules = compileColorRules(cs);
end
vars.tcolorrules = compileColorRules(option(vars, 'tcolor'));
vars.pcolorrules = compileColorRules(option(vars, 'pcolor'));
vars.settingsLoaded = true;
updateTextVisibility(vars);
vars:abortFlash();
if vars.visible then
vars.frame:SetAlpha(option(vars, 'alpha'));
end
update(vars);
vars:updateColor();
showFrame(vars.frame, not vars.never);
assignGroups();
sortNeighborBars(vars);
end
local function updateAllSettings()
table.foreach(bars,
function(key, val)
updateSettings(val);
end
);
end
-- common OnEvent
local function eventCommon(vars, event)
if event == 'VARIABLES_LOADED' then
if (variables_loaded ~= true) then
StatusBars_Register();
end
variables_loaded = true;
end
if variables_loaded and UnitExists('player') then
local pn = UnitName('player');
if playerName ~= pn and pn ~= nil and pn ~= UNKNOWNBEING and pn ~= UKNOWNBEING and pn ~= UNKNOWNOBJECT then
playerName = pn;
load_time = GetTime() + 1;
end
end
end
local function eventCommon_real(vars, event)
if event == 'PLAYER_ENTERING_WORLD' then
vars._inCombat = false;
vars._hasAggro = false;
elseif event == 'PLAYER_ENTER_COMBAT' then
vars._inCombat = true;
elseif event == 'PLAYER_LEAVE_COMBAT' then
vars._inCombat = false;
elseif event == 'PLAYER_REGEN_DISABLED' then
vars._hasAggro = true;
elseif event == 'PLAYER_REGEN_ENABLED' then
vars._hasAggro = false;
end
end
local function notifyingFade(vars, frame, mode, time, start, end_)
vars.fading = true;
local fade = {};
fade.mode = mode;
fade.timeToFade = time;
fade.startAlpha = start;
fade.endAlpha = end_;
fade.finishedFunc = function()
vars.fading = false;
vars:onEvent();
sortNeighborBars(vars);
end;
UIFrameFade(frame, fade);
end
-- fade frame in or out if needed
local function fadeFrame(vars, visible)
local frame = vars.frame;
local current = vars.targetVisibility;
if current ~= visible then
sortNeighborBars(vars);
local alpha = option(vars, 'alpha');
if visible then
notifyingFade(vars, frame, 'IN', FadeInDuration, frame:GetAlpha(), alpha);
else
notifyingFade(vars, frame, 'OUT', FadeOutDuration, frame:GetAlpha(), 0);
end
vars.targetVisibility = visible;
end
end
-- common bar update
-- determines visibility, updates text and handles flash activation
local function updateCommon(vars)
-- dummy version, replaced by updateCommon_real when settings are loaded
end
local function updateCommon_real(vars)
-- get values
local curV = vars.getCurrent();
local maxV = vars.getMax();
local fraction = 0;
if curV > 0.001 and maxV > 0.001 then
fraction = curV / maxV;
end
local oldvis = vars.visible;
-- store values
vars.lastValue = curV;
vars.lastMax = maxV;
vars.lastFraction = fraction;
-- determine visibility
local enable = option(vars, 'enable');
local show = false;
local update = true;
if vars.never or not vars.softEnable or maxV == 0 then
show = false;
update = false;
elseif enable == EnableAlways then
show = true;
elseif UnitIsDeadOrGhost('player') then
show = false;
elseif (enable == EnableInCombat or enable == EnableInCombatOnly) and (vars._inCombat or vars._hasAggro) then
show = true;
elseif enable ~= EnableInCombatOnly then
show = (fraction ~= vars.default);
end
-- update bar visibility
fadeFrame(vars, show);
vars.visible = show or vars.fading;
if show or oldvis then
-- update text and bar
if update and vars.settingsLoaded then
vars:updateValueDisplay();
end
-- update scale
vars.frame:SetScale(option(vars, 'scale') * UIParent:GetScale());
-- update flashing
local d = abs(fraction - vars.default);
if maxV == 0 then
stopFlash(vars);
elseif option(vars, 'flash') and d > option(vars, 'warn') then
startFlash(vars);
else
stopFlash(vars);
end
vars:updateTickEnable();
end
end
-- update power type (mana/rage/energy)
local function updatePowerType(vars, unit, logicalPrefix)
local exists = UnitExists(unit);
local index;
-- update first time and when index has changed
if exists and UnitManaMax(unit) > 0 then
index = UnitPowerType(unit);
else
index = vars._lastIndex or 0;
end
if index == vars._lastIndex then
return;
end
vars._lastIndex = index;
-- update bar color and default value
vars.default = 1;
if index == 0 then
-- mana
vars.logical = logicalPrefix .. 'mana';
elseif index == 1 then
-- rage
vars.default = 0;
vars.logical = logicalPrefix .. 'rage';
elseif index == 2 then
-- focus
vars.logical = logicalPrefix .. 'focus';
elseif index == 3 then
-- energy
vars.logical = logicalPrefix .. 'energy';
elseif index == 4 then
-- happiness
vars.logical = logicalPrefix .. 'mana';
end
updateSettings(vars);
end
-- determine if the combo bar should be visible and update if needed
local function updateComboEnable()
local t = (UnitPowerType('player') == 3) or combo:getCurrent() > 0;
if combo._hasCombo ~= t then
combo._hasCombo = t;
combo.softEnable = t;
updateCommon(combo);
end
end
-- update bar for other unit
local function updateOtherUnitCommon(vars)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -