You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1001 lines
29 KiB

local _;
local _G = _G;
local VUHDO_BUFF_RAID = { };
local VUHDO_BUFF_RAID_FILTERED = { };
local VUHDO_PLAYER_GROUP = { "player" };
local VUHDO_BS_COLOR_EMPTY = 1;
local VUHDO_BS_COLOR_CD = 2;
local VUHDO_BS_COLOR_LOW = 3;
local VUHDO_BS_COLOR_MISSING = 4;
local VUHDO_BS_COLOR_OKAY = 5;
local VUHDO_NUM_LOWS = { };
local VUHDO_LAST_COLORS = { };
--
VUHDO_BUFFS = { };
VUHDO_BUFF_SETTINGS = { };
local VUHDO_CLICKED_BUFF = nil;
local VUHDO_CLICKED_TARGET = nil;
local VUHDO_IS_USED_SMART_BUFF;
VUHDO_BUFF_ORDER = { };
local sEmpty = { };
local sCooldownAliases = { };
-- Backdrops
BACKDROP_VUHDO_BUFF_SWATCH_PANEL_8_8_0000 = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true,
tileSize = 8,
edgeSize = 8,
};
BACKDROP_COLOR_VUHDO_BUFF_SWATCH_PANEL = CreateColor(0, 0, 0);
BACKDROP_VUHDO_BUFF_WATCH_MAIN_FRAME_16_16_5555 = {
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true,
tileSize = 16,
edgeSize = 16,
insets = { left = 5, right = 5, top = 5, bottom = 5 },
};
-- BURST CACHE ---------------------------------------------------
local VUHDO_RAID;
local VUHDO_RAID_NAMES;
local VUHDO_tableUniqueAdd;
local VUHDO_isInSameZone;
local VUHDO_isInBattleground;
local VUHDO_brightenTextColor;
local VUHDO_isConfigDemoUsers;
local GetTotemInfo = GetTotemInfo;
local table = table;
local strsub = strsub;
local GetTime = GetTime;
local GetSpellCooldown = GetSpellCooldown;
local GetSpellBookItemName = GetSpellBookItemName;
local GetSpellInfo = GetSpellInfo;
local InCombatLockdown = InCombatLockdown;
local GetWeaponEnchantInfo = GetWeaponEnchantInfo;
local UnitOnTaxi = UnitOnTaxi;
local IsSpellInRange = IsSpellInRange;
local GetShapeshiftFormInfo = GetShapeshiftFormInfo;
local tonumber = tonumber;
local pairs = pairs;
local ipairs = ipairs;
local twipe = table.wipe;
local format = format;
local sConfig = { };
local sRebuffSecs;
local sRebuffPerc;
local sGermanOrEnglish = GetLocale() == "deDE" or GetLocale() == "enGB" or GetLocale() == "enUS";
-----------------------------------------------------------------------------
function VUHDO_buffWatchInitLocalOverrides()
VUHDO_RAID = _G["VUHDO_RAID"];
VUHDO_RAID_NAMES = _G["VUHDO_RAID_NAMES"];
VUHDO_tableUniqueAdd = _G["VUHDO_tableUniqueAdd"];
VUHDO_isInSameZone = _G["VUHDO_isInSameZone"];
VUHDO_isInBattleground = _G["VUHDO_isInBattleground"];
VUHDO_brightenTextColor = _G["VUHDO_brightenTextColor"];
VUHDO_isConfigDemoUsers = _G["VUHDO_isConfigDemoUsers"];
sConfig = VUHDO_BUFF_SETTINGS["CONFIG"];
sRebuffSecs = sConfig["REBUFF_MIN_MINUTES"] * 60;
sRebuffPerc = sConfig["REBUFF_AT_PERCENT"] * 0.01;
end
----------------------------------------------------
--
function VUHDO_buffWatchOnMouseDown(aPanel)
if VUHDO_mayMoveHealPanels() then aPanel:StartMoving(); end
end
--
function VUHDO_buffWatchOnMouseUp(aPanel)
if VUHDO_mayMoveHealPanels() then
aPanel:StopMovingOrSizing();
local tCoords = VUHDO_BUFF_SETTINGS["CONFIG"]["POSITION"];
tCoords["point"], _, tCoords["relativePoint"], tCoords["x"], tCoords["y"] = aPanel:GetPoint();
end
end
--
local tCopy = { };
local function VUHDO_copyColor(aColor)
tCopy["R"], tCopy["G"], tCopy["B"], tCopy["O"] = aColor["R"], aColor["G"], aColor["B"], aColor["O"];
tCopy["TR"], tCopy["TG"], tCopy["TB"], tCopy["TO"] = aColor["TR"], aColor["TG"], aColor["TB"], aColor["TO"];
tCopy["useBackground"], tCopy["useText"], tCopy["useOpacity"] = aColor["useBackground"], aColor["useText"], aColor["useOpacity"];
return tCopy;
end
--
function VUHDO_isUseSingleBuff(aSwatch)
if VUHDO_BUFF_TARGET_SINGLE ~= aSwatch:GetAttribute("buff")[2] then return false;
elseif aSwatch:GetAttribute("lowtarget") == nil or InCombatLockdown() then return 2;
else return true; end
end
local function VUHDO_getWeaponEnchantMacroText(anEnchantName, aTargetType)
return format("/use [@none] %s\n/use %d\n/click StaticPopup1Button1 LeftButton",
anEnchantName, VUHDO_BUFF_TARGET_ENCHANT == aTargetType and 16 or 17);
end
--
local function VUHDO_setupBuffButtonAttributes(aModifierKey, aButtonId, anActionName, aButton, aTargetType)
if not VUHDO_strempty(anActionName) then
if VUHDO_BUFF_TARGET_ENCHANT == aTargetType or VUHDO_BUFF_TARGET_ENCHANT_OFF == aTargetType then
aButton:SetAttribute(aModifierKey .. "type" .. aButtonId, "macro");
aButton:SetAttribute(aModifierKey .. "macrotext" .. aButtonId, VUHDO_getWeaponEnchantMacroText(anActionName, aTargetType));
else
aButton:SetAttribute(aModifierKey .. "type" .. aButtonId, "spell");
aButton:SetAttribute(aModifierKey .. "spell" .. aButtonId, anActionName);
end
else
aButton:SetAttribute(aModifierKey .. "type" .. aButtonId, "");
end
end
--
function VUHDO_setupAllBuffButtonUnits(aButton, aUnit)
if not InCombatLockdown() then
aButton:SetAttribute("unit", aUnit or "_foo");
end
end
--
--local tModiKey, tButtonId;
function VUHDO_setupAllBuffButtonsTo(aButton, aBuffName, aUnit, aTargetType)
if InCombatLockdown() then return; end
VUHDO_setupAllBuffButtonUnits(aButton, aUnit);
for _, tWithMinus in pairs(VUHDO_MODIFIER_KEYS) do
for tCnt = 1, VUHDO_NUM_MOUSE_BUTTONS do
VUHDO_setupBuffButtonAttributes(tWithMinus, tCnt, tCnt ~= 2 and aBuffName or nil, aButton, aTargetType);
end
end
end
--
function VUHDO_buffSelectDropdownOnLoad()
UIDropDownMenu_SetInitializeFunction(VuhDoBuffSelectDropdown, VUHDO_buffSelectDropdown_Initialize);
UIDropDownMenu_SetDisplayMode(VuhDoBuffSelectDropdown, "MENU");
end
--
function VUHDO_buffSelectDropdown_Initialize(_, _)
if VUHDO_CLICKED_BUFF == nil or VUHDO_CLICKED_TARGET == nil or InCombatLockdown() then
return;
end
local tCategName = VUHDO_getBuffCategoryName(VUHDO_CLICKED_BUFF[1], VUHDO_CLICKED_BUFF[2]);
local tCateg = VUHDO_getPlayerClassBuffs()[tCategName];
local tSettings = VUHDO_BUFF_SETTINGS[tCategName];
local tTargetType = tCateg[1][2];
if #tCateg > 1 then
local tInfo;
for _, tCategBuff in ipairs(tCateg) do
local tBuffName = tCategBuff[1];
if VUHDO_BUFFS[tBuffName] then
tInfo = UIDropDownMenu_CreateInfo();
tInfo["text"] = tBuffName;
tInfo["keepShownOnClick"] = false;
tInfo["icon"] = VUHDO_BUFFS[tBuffName]["icon"];
tInfo["arg1"] = tCategName;
tInfo["func"] = VUHDO_buffSelectDropdownBuffSelected;
tInfo["arg2"] = tBuffName;
tInfo["checked"] = tSettings["buff"] == tBuffName;
UIDropDownMenu_AddButton(tInfo);
end
end
elseif VUHDO_BUFF_TARGET_RAID == tTargetType or VUHDO_BUFF_TARGET_SINGLE == tTargetType then
local tInfo;
local tText;
tInfo = UIDropDownMenu_CreateInfo();
tInfo["text"] = VUHDO_I18N_TRACK_BUFFS_FOR;
tInfo["isTitle"] = true;
tInfo["notCheckable"] = true;
UIDropDownMenu_AddButton(tInfo);
for _, tFilter in pairs(VUHDO_BUFF_FILTER_COMBO_TABLE) do
tInfo = UIDropDownMenu_CreateInfo();
tText = tFilter[2];
tInfo["text"] = tText;
tInfo["checked"] = VUHDO_BUFF_SETTINGS[tCategName]["filter"][tFilter[1]];
tInfo["arg1"] = tCategName;
tInfo["arg2"] = tFilter[1];
tInfo["func"] = VUHDO_buffSelectDropdownFilterSelected;
tInfo["isTitle"] = false;
tInfo["disabled"] = false;
UIDropDownMenu_AddButton(tInfo);
end
else
VuhDoBuffSelectDropdown:Hide();
local tTargetType = strsub(VUHDO_CLICKED_TARGET, 1, 1);
if tTargetType == "N" then
local tSelName = nil;
local tNextSel = false;
if VUHDO_RAID_NAMES[tSettings["name"]] then
for tName, _ in pairs(VUHDO_RAID_NAMES) do
if tName ~= "player" then
if tSelName == nil or tNextSel then
tSelName = tName;
if tNextSel then break; end
end
if tName == tSettings["name"] then tNextSel = true; end
end
end
tSettings["name"] = tSelName;
VUHDO_reloadBuffPanel();
else
tSettings["name"] = VUHDO_PLAYER_NAME;
end
end
end
end
--
function VUHDO_buffSelectDropdownBuffSelected(_, aCategoryName, aBuffName)
if aCategoryName then
VUHDO_BUFF_SETTINGS[aCategoryName]["buff"] = aBuffName;
VUHDO_reloadBuffPanel();
end
end
--
function VUHDO_buffSelectDropdownFilterSelected(_, aCategName, aFilterValue)
if aCategName then
local tAllFilters = VUHDO_BUFF_SETTINGS[aCategName]["filter"];
if VUHDO_ID_ALL == aFilterValue then
twipe(tAllFilters);
tAllFilters[VUHDO_ID_ALL] = true;
else
if tAllFilters[aFilterValue] then tAllFilters[aFilterValue] = nil;
else tAllFilters[aFilterValue] = true; end
tAllFilters[VUHDO_ID_ALL] = nil;
end
VUHDO_updateBuffFilters();
end
end
--
function VuhDoBuffPreClick(aButton, aMouseButton)
local tSwatch = aButton:GetParent();
local tVariant = tSwatch:GetAttribute("buff");
if "RightButton" == aMouseButton then
VUHDO_CLICKED_BUFF = tVariant;
VUHDO_CLICKED_TARGET = tSwatch:GetAttribute("target");
ToggleDropDownMenu(1, nil, VuhDoBuffSelectDropdown, aButton:GetName(), 0, -5);
end
VUHDO_IS_USED_SMART_BUFF = VUHDO_isUseSingleBuff(tSwatch);
local tBuff = tVariant[1];
if 2 == VUHDO_IS_USED_SMART_BUFF and aMouseButton == "LeftButton" then
UIErrorsFrame:AddMessage(VUHDO_I18N_SMARTBUFF_ERR_2 .. tBuff, 1, 0.1, 0.1, 1);
VUHDO_setupAllBuffButtonsTo(aButton, "", "", nil);
return;
end
local tTarget = VUHDO_IS_USED_SMART_BUFF
and tSwatch:GetAttribute("lowtarget") or tSwatch:GetAttribute("goodtarget");
VUHDO_setupAllBuffButtonsTo(aButton, tBuff, tTarget, tVariant[2]);
if not tTarget and aMouseButton ~= "RightButton" then
UIErrorsFrame:AddMessage(VUHDO_I18N_SMARTBUFF_ERR_2 .. tBuff, 1, 0.1, 0.1, 1);
end
end
--
function VuhDoBuffPostClick(aButton, aMouseButton)
if VUHDO_IS_USED_SMART_BUFF then
local tVariant = aButton:GetParent():GetAttribute("buff");
VUHDO_setupAllBuffButtonsTo(aButton, tVariant[1], aButton:GetParent():GetAttribute("goodtarget"), tVariant[2]);
end
end
--
function VUHDO_getAllUniqueSpells()
local tUniqueBuffs = { };
local tUniqueCategs = { };
for tCategName, tCategBuffs in pairs(VUHDO_getPlayerClassBuffs()) do
local tSpellName = tCategBuffs[1][1];
if VUHDO_BUFFS[tSpellName] and VUHDO_BUFF_TARGET_UNIQUE == tCategBuffs[1][2] then
tUniqueBuffs[#tUniqueBuffs + 1] = tSpellName;
tUniqueCategs[tSpellName] = tCategName;
end
end
return tUniqueBuffs, tUniqueCategs;
end
--
function VUHDO_initBuffsFromSpellBook()
local tParentSpellName, tChildSpellName, tSpellId, tIcon;
-- Patch 6.0.2 broke the spell book for a certain class of spells which 'transform' into other spells
-- eg. Lightning Shield becomes Water Shield, Seal of Command becomes Seal of Truth
-- the workaround is to always check for existance in the spell book using the 'source' or 'parent'
-- spell name then map the 'source' spell name to the correct 'derived' or 'child' spell info
-- eg. GetSpellBookItemInfo("Lightning Shield") will return a spell ID only for Lightning Shield,
-- however when a Resto Shaman calls GetSpellInfo("Lightning Shield") it returns the correct
-- information for the derived spell Water Shield
VUHDO_BUFFS = { };
for _, tCateg in pairs(VUHDO_getPlayerClassBuffs()) do
for _, tCategSpells in pairs(tCateg) do
tParentSpellName = tCategSpells[1];
_, tSpellId = GetSpellBookItemInfo(tParentSpellName);
if tSpellId then
tChildSpellName, _, tIcon, _, _, _, tSpellId = GetSpellInfo(tParentSpellName);
VUHDO_BUFFS[tChildSpellName] = {
["icon"] = tIcon,
["id"] = tSpellId
};
if tChildSpellName ~= tParentSpellName then
VUHDO_BUFFS[tParentSpellName] = {
["icon"] = tIcon,
["id"] = tSpellId
};
end
VUHDO_CLASS_BUFFS_BY_TARGET_TYPE[tCategSpells[2]][tParentSpellName] = true;
end
end
end
for tClassName, _ in pairs(VUHDO_CLASS_BUFFS) do
if VUHDO_PLAYER_CLASS ~= tClassName then
VUHDO_CLASS_BUFFS[tClassName] = nil;
end
end
end
--
function VUHDO_isBuffOfTargetType(aBuffName, aTargetType)
return VUHDO_CLASS_BUFFS_BY_TARGET_TYPE[aTargetType][aBuffName] and true or false;
end
--
function VUHDO_getBuffCategoryName(aBuffName, aTargetType)
for tCategName, tCategBuffs in pairs(VUHDO_getPlayerClassBuffs()) do
for _, tBuffVariant in pairs(tCategBuffs) do
if aBuffName == tBuffVariant[1] and aTargetType == tBuffVariant[2] then
return tCategName;
end
end
end
return nil;
end
--
local tInfo;
local function VUHDO_setUnitMissBuff(aUnit, aCategSpec, someVariants, aCategName)
if not (VUHDO_BUFF_SETTINGS[aCategName]["missingColor"] or sEmpty)["show"] then return; end
tInfo = VUHDO_RAID[aUnit];
if tInfo then
-- Don't show missing buffs on vehicles
if tInfo["isPet"] and VUHDO_RAID[tInfo["ownerUnit"]] and VUHDO_RAID[tInfo["ownerUnit"]]["isVehicle"] then
return;
end
if not tInfo["missbuff"] or tInfo["missbuff"] > VUHDO_BUFF_ORDER[aCategSpec] then
tInfo["missbuff"] = VUHDO_BUFF_ORDER[aCategSpec];
tInfo["mibucateg"] = aCategName;
tInfo["mibuvariants"] = someVariants;
end
end
end
--
local tTexture, tStart, tRest, tDuration;
local tMissGroup = { };
local tLowGroup = { };
local tOkayGroup = { };
local tOorGroup = { };
local tGoodTarget;
local tLowestRest;
local tLowestUnit;
local tTotemFound, tStart;
local tNow;
local tInRange;
local tCount;
local tMaxCount;
local tIsWatchUnit;
local tInfo;
local tCategName;
local tIsAvailable;
local tIsNotInBattleground;
local tBuffGroup;
local function VUHDO_getMissingBuffs(aBuffInfo, someUnits, aCategSpec)
tCategName = aCategSpec;
twipe(tMissGroup);
twipe(tLowGroup);
twipe(tOkayGroup);
twipe(tOorGroup);
tGoodTarget = nil;
tLowestRest = nil;
tLowestUnit = nil;
tNow = GetTime();
tMaxCount = 0;
if UnitOnTaxi("player") and VUHDO_BUFF_TARGET_SELF ~= aBuffInfo[2] then
return tMissGroup, tLowGroup, tGoodTarget, tLowestRest, tLowestUnit, tOkayGroup, tOorGroup, tMaxCount;
end
tIsNotInBattleground = not VUHDO_isInBattleground();
for _, tUnit in pairs(someUnits) do
tInfo = VUHDO_RAID[tUnit];
if "focus" == tUnit or "target" == tUnit or tInfo == nil or tInfo["isPet"] then
tIsWatchUnit = false;
elseif "player" == tUnit then
tIsWatchUnit = true;
elseif VUHDO_isInSameZone(tUnit) and (tInfo["visible"] or tIsNotInBattleground) then
tIsWatchUnit = true;
else
tIsWatchUnit = false;
end
if tIsWatchUnit then
tInRange = (IsSpellInRange(aBuffInfo[1], tUnit) == 1) or tInfo["baseRange"];
tIsAvailable = tInfo["connected"] and not tInfo["dead"];
_, tTexture, tCount, _, tStart, tRest, _, _ = VUHDO_unitBuff(tUnit, aBuffInfo[1]);
if not tTexture then
for tCnt = 3, 10 do
tBuffGroup = aBuffInfo[tCnt];
if not tBuffGroup then break; end
for _, tSameGroupBuff in pairs(tBuffGroup) do
_, tTexture, tCount, _, tStart, tRest, _, _ = VUHDO_unitBuff(tUnit, tSameGroupBuff);
if tTexture then break; end
end
if not tTexture then break; end -- Kein Buff in einer der Gruppen? => Raus, nachbuffen
end
end
if tTexture then
tStart = tStart or 0;
tRest = tRest and tRest - tNow or 0;
tCount = tCount or 0
if tCount > tMaxCount then tMaxCount = tCount; end
if (tRest < sRebuffSecs or tRest / tStart < sRebuffPerc) and tRest > 0 then
tLowGroup[#tLowGroup + 1] = tUnit;
if not tInRange and tIsAvailable then
tOorGroup[#tOorGroup + 1] = tUnit;
end
else
tOkayGroup[#tOkayGroup + 1] = tUnit;
end
if tLowestRest == nil or tRest < tLowestRest then
tLowestRest = tRest;
if tInRange then tLowestUnit = tUnit; end
end
end
if tIsAvailable then
if not tTexture then
tMissGroup[#tMissGroup + 1] = tUnit;
if not tInRange and tIsAvailable then
tOorGroup[#tOorGroup + 1] = tUnit;
end
VUHDO_setUnitMissBuff(tUnit, aCategSpec, aBuffInfo, tCategName);
if tInRange then
tLowestUnit = tUnit;
tLowestRest = 0;
end
end
if 10 == aBuffInfo[2] then tGoodTarget = "player"; -- VUHDO_BUFF_TARGET_RAID
elseif 9 == aBuffInfo[2] then tGoodTarget = "target"; -- VUHDO_BUFF_TARGET_HOSTILE
elseif 3 == aBuffInfo[2] or tInRange then tGoodTarget = tUnit; -- VUHDO_BUFF_TARGET_UNIQUE
end
end
end
end
return tMissGroup, tLowGroup, tGoodTarget, tLowestRest, tLowestUnit, tOkayGroup, tOorGroup, tMaxCount;
end
--
local tFilters;
local tIsPetArray = { ["isPet"] = true };
local function VUHDO_updateFilter(aCategName)
tFilters = VUHDO_BUFF_SETTINGS[aCategName]["filter"];
if tFilters[VUHDO_ID_ALL] then
VUHDO_BUFF_RAID_FILTERED[aCategName] = VUHDO_BUFF_RAID;
else
VUHDO_BUFF_RAID_FILTERED[aCategName] = { };
for tModelId, _ in pairs(tFilters) do
for _, tUnit in pairs(VUHDO_GROUPS[tModelId]) do
if not (VUHDO_RAID[tUnit] or tIsPetArray)["isPet"] then
VUHDO_tableUniqueAdd(VUHDO_BUFF_RAID_FILTERED[aCategName], tUnit);
end
end
end
end
end
--
function VUHDO_updateBuffFilters()
for tCategSpec, _ in pairs(VUHDO_getPlayerClassBuffs()) do
VUHDO_updateFilter(tCategSpec);
end
end
--
function VUHDO_updateBuffRaidGroup()
twipe(VUHDO_BUFF_RAID);
for tUnit, tInfo in pairs(VUHDO_RAID) do
if "focus" ~= tUnit and "target" ~= tUnit and not tInfo["isPet"] then
VUHDO_BUFF_RAID[#VUHDO_BUFF_RAID + 1] = tUnit;
end
end
VUHDO_updateBuffFilters();
end
--
local tDestGroup;
local tPlayerGroup;
local tTargetType;
local tEnchantDuration;
local tHasEnchant;
local tCategName;
local tNameGroup = { };
local tIsActive;
local tRest, tName, tTotemNum, tTexture;
local function VUHDO_getMissingBuffsForCode(aTargetCode, aBuffInfo, aCategSpec)
if "N" == strsub(aTargetCode, 1, 1) then
tNameGroup[1] = VUHDO_RAID_NAMES[strsub(aTargetCode, 2)];
tDestGroup = tNameGroup;
else
tTargetType = aBuffInfo[2];
if VUHDO_BUFF_TARGET_RAID == tTargetType or VUHDO_BUFF_TARGET_SINGLE == tTargetType then
tCategName = aCategSpec;
if VUHDO_BUFF_RAID_FILTERED[tCategName] then
tDestGroup = VUHDO_BUFF_RAID_FILTERED[tCategName];
else
tDestGroup = VUHDO_BUFF_RAID;
end
elseif VUHDO_BUFF_TARGET_OWN_GROUP == tTargetType then
tDestGroup = VUHDO_GROUPS[(VUHDO_RAID["player"] or {})["group"] or 1];
elseif VUHDO_BUFF_TARGET_STANCE == tTargetType then
for tCnt = 1, NUM_STANCE_SLOTS do
_, tName, tIsActive = GetShapeshiftFormInfo(tCnt);
if tIsActive and tName == aBuffInfo[1] then
return sEmpty, sEmpty, "player", 0, "player", VUHDO_PLAYER_GROUP, sEmpty, 0;
end
end
VUHDO_setUnitMissBuff("player", aCategSpec, aBuffInfo, aCategSpec);
return VUHDO_PLAYER_GROUP, sEmpty, "player", 0, "player", sEmpty, sEmpty, 0;
elseif VUHDO_BUFF_TARGET_ENCHANT == tTargetType then
tHasEnchant, tEnchantDuration = GetWeaponEnchantInfo();
if tHasEnchant and (not sGermanOrEnglish or strfind(aBuffInfo[1], VUHDO_getWeaponEnchantName(16), 1, true)) then
return sEmpty, sEmpty, "player", tEnchantDuration * 0.001, "player", VUHDO_PLAYER_GROUP, sEmpty, 0;
end
VUHDO_setUnitMissBuff("player", aCategSpec, aBuffInfo, aCategSpec);
return VUHDO_PLAYER_GROUP, sEmpty, "player", 0, "player", sEmpty, sEmpty, 0;
elseif VUHDO_BUFF_TARGET_ENCHANT_OFF == tTargetType then
_, _, _, _, tHasEnchant, tEnchantDuration = GetWeaponEnchantInfo();
if tHasEnchant and (not sGermanOrEnglish or strfind(aBuffInfo[1], VUHDO_getWeaponEnchantName(17), 1, true)) then
return sEmpty, sEmpty, "player", tEnchantDuration * 0.001, "player", VUHDO_PLAYER_GROUP, sEmpty, 0;
end
VUHDO_setUnitMissBuff("player", aCategSpec, aBuffInfo, aCategSpec);
return VUHDO_PLAYER_GROUP, sEmpty, "player", 0, "player", sEmpty, sEmpty, 0;
elseif VUHDO_BUFF_TARGET_TOTEM == tTargetType then
for tTotemNum = 1, 4 do
_, tName, tStart, tDuration, tTexture = GetTotemInfo(tTotemNum);
if tTexture == VUHDO_BUFFS[aBuffInfo[1]]["icon"] then
if tName ~= aBuffInfo[1] then
sCooldownAliases[aBuffInfo[1]] = tName;
end
tRest = tDuration - (GetTime() - tStart);
if tRest < 0 then tRest = 0; end
return sEmpty, sEmpty, "player", tRest, "player", VUHDO_PLAYER_GROUP, sEmpty, 0;
end
end
VUHDO_setUnitMissBuff("player", aCategSpec, aBuffInfo, aCategSpec);
return VUHDO_PLAYER_GROUP, sEmpty, "player", 0, "player", sEmpty, sEmpty, 0;
else
-- If self we only care if buff isn't on player
tDestGroup = VUHDO_PLAYER_GROUP;
end
end
return VUHDO_getMissingBuffs(aBuffInfo, tDestGroup or sEmpty, aCategSpec);
end
--
local function VUHDO_setBuffSwatchColor(aSwatch, aColorInfo, aColorType)
if VUHDO_LAST_COLORS[aSwatch:GetName()] == aColorType then return; end
local tColor = VUHDO_getDiffColor(VUHDO_copyColor(sConfig["SWATCH_BG_COLOR"]), aColorInfo);
aSwatch:SetBackdropColor(VUHDO_backColor(tColor));
local tName = aSwatch:GetName();
if tColor["useText"] then
_G[tName .. "MessageLabelLabel"]:SetTextColor(VUHDO_textColor(tColor));
_G[tName .. "TimerLabelLabel"]:SetTextColor(VUHDO_textColor(tColor));
_G[tName .. "CounterLabelLabel"]:SetTextColor(VUHDO_textColor(tColor));
tColor = VUHDO_brightenTextColor(VUHDO_copyColor(aColorInfo), 0.2);
_G[tName .. "GroupLabelLabel"]:SetTextColor(VUHDO_textColor(tColor));
end
VUHDO_LAST_COLORS[tName] = aColorType;
end
--
local function VUHDO_setBuffSwatchInfo(aSwatchName, anInfoText)
_G[aSwatchName .. "MessageLabelLabel"]:SetText(anInfoText);
end
--
local function VUHDO_setBuffSwatchCount(aSwatchName, aText)
_G[aSwatchName .. "CounterLabelLabel"]:SetText(aText);
end
--
local tCountStr;
local function VUHDO_setBuffSwatchTimer(aSwatchName, aSecsNum, aCount)
if (aSecsNum or -1) >= 0 then
tCountStr = ((aCount or 0) > 0 and not VUHDO_BUFF_SETTINGS["CONFIG"]["HIDE_CHARGES"])
and format("|cffffffff%dx |r", aCount) or "";
_G[aSwatchName .. "TimerLabelLabel"]:SetText(format("%s%d:%02d", tCountStr, aSecsNum / 60, aSecsNum % 60));
else
_G[aSwatchName .. "TimerLabelLabel"]:SetText("");
end
end
--
local tStart, tDuration;
local function VUHDO_getSpellCooldown(aSpellName)
if sCooldownAliases[aSpellName] then
tStart, tDuration = GetSpellCooldown(sCooldownAliases[aSpellName], BOOKTYPE_SPELL);
else
tStart, tDuration = GetSpellCooldown(VUHDO_BUFFS[aSpellName]["id"]);
end
if (tDuration or 0) == 0 then return 0, 0;
else return (tStart or 0) + tDuration - GetTime(), tDuration; end
end
--
local tMissGroup;
local tLowGroup;
local tGoodTarget;
local tLowestRest;
local tLowestUnit;
local tOkayGroup;
local tOorGroup;
local tCooldown, tTotalCd;
local tRefSpell;
local tSwatchName;
local tMaxCount;
local tCategSpec;
local tVariant;
local tTargetCode;
function VUHDO_updateBuffSwatch(aSwatch)
tSwatchName = aSwatch:GetName();
tVariant = aSwatch:GetAttribute("buff");
tTargetCode = aSwatch:GetAttribute("target");
tCategSpec = aSwatch:GetAttribute("buffName");
if not tTargetCode or not tVariant then return; end
tLowestUnit, tGoodTarget = nil, nil;
tRefSpell = tVariant[1];
if not VUHDO_BUFFS[tRefSpell] or not VUHDO_BUFFS[tRefSpell]["id"] then return; end
tCooldown, tTotalCd = VUHDO_getSpellCooldown(tRefSpell);
if tCooldown > 1.5 then
VUHDO_setBuffSwatchColor(aSwatch, sConfig["SWATCH_COLOR_BUFF_COOLDOWN"], VUHDO_BS_COLOR_CD);
VUHDO_setBuffSwatchInfo(tSwatchName, VUHDO_I18N_BW_CD);
VUHDO_setBuffSwatchCount(tSwatchName, "");
VUHDO_setBuffSwatchTimer(tSwatchName, tCooldown, nil);
if tTotalCd > 59 then VUHDO_BUFFS[tRefSpell]["wasOnCd"] = true; end
else
if VUHDO_BUFFS[tRefSpell]["wasOnCd"] and VUHDO_BUFF_SETTINGS["CONFIG"]["HIGHLIGHT_COOLDOWN"] then
VUHDO_UIFrameFlash(aSwatch, 0.3, 0.3, 5, true, 0, 0.3);
VUHDO_BUFFS[tRefSpell]["wasOnCd"] = false;
end
tMissGroup, tLowGroup, tGoodTarget, tLowestRest, tLowestUnit, tOkayGroup, tOorGroup, tMaxCount
= VUHDO_getMissingBuffsForCode(tTargetCode, tVariant, tCategSpec);
if #tMissGroup > 0 then
VUHDO_setBuffSwatchColor(aSwatch, sConfig["SWATCH_COLOR_BUFF_OUT"], VUHDO_BS_COLOR_MISSING);
if not tGoodTarget or #tMissGroup + #tLowGroup - #tOorGroup == 0 then
VUHDO_setBuffSwatchInfo(tSwatchName, VUHDO_I18N_BW_RNG_YELLOW);
VUHDO_setBuffSwatchCount(tSwatchName, "" .. #tOorGroup);
VUHDO_setBuffSwatchTimer(tSwatchName, 0, nil, tMaxCount);
else
VUHDO_setBuffSwatchInfo(tSwatchName, VUHDO_I18N_BW_GO);
if #tOorGroup > 0 then
VUHDO_setBuffSwatchCount(tSwatchName, format("%d/%d", #tMissGroup + #tLowGroup - #tOorGroup, #tMissGroup + #tLowGroup));
else
VUHDO_setBuffSwatchCount(tSwatchName, format("%d", #tMissGroup + #tLowGroup));
end
VUHDO_setBuffSwatchTimer(tSwatchName, 0, nil);
end
elseif #tLowGroup > 0 then
VUHDO_setBuffSwatchColor(aSwatch, sConfig["SWATCH_COLOR_BUFF_LOW"], VUHDO_BS_COLOR_LOW);
VUHDO_setBuffSwatchInfo(tSwatchName, tGoodTarget and VUHDO_I18N_BW_LOW or VUHDO_I18N_BW_RNG_RED);
if #tOorGroup > 0 then
VUHDO_setBuffSwatchCount(tSwatchName, format("%d/%d", #tLowGroup - #tOorGroup, #tLowGroup));
else
VUHDO_setBuffSwatchCount(tSwatchName, format("%d", #tLowGroup));
end
VUHDO_setBuffSwatchTimer(tSwatchName, tLowestRest, tMaxCount);
else
VUHDO_setBuffSwatchColor(aSwatch, sConfig["SWATCH_COLOR_BUFF_OKAY"], VUHDO_BS_COLOR_OKAY);
if #tOkayGroup == 0 then
VUHDO_setBuffSwatchInfo(tSwatchName, VUHDO_I18N_BW_N_A);
elseif not tGoodTarget then
VUHDO_setBuffSwatchInfo(tSwatchName, VUHDO_I18N_BW_RNG_RED);
else
VUHDO_setBuffSwatchInfo(tSwatchName, VUHDO_I18N_BW_OK);
end
VUHDO_setBuffSwatchCount(tSwatchName, #tOkayGroup);
if tLowestRest == 0 then
VUHDO_setBuffSwatchTimer(tSwatchName, nil);
else
VUHDO_setBuffSwatchTimer(tSwatchName, tLowestRest, tMaxCount);
end
end
end
if not InCombatLockdown() then
aSwatch:SetAttribute("lowtarget", tLowestUnit);
aSwatch:SetAttribute("goodtarget", tGoodTarget);
end
VUHDO_NUM_LOWS[tSwatchName] = #(tLowGroup or sEmpty) + #(tMissGroup or sEmpty);
end
--
local tAllSwatches;
local tOldMissBuffs = { };
function VUHDO_updateBuffPanel()
if VUHDO_isConfigDemoUsers() then return; end
for tUnit, tInfo in pairs(VUHDO_RAID) do
tOldMissBuffs[tUnit] = tInfo["missbuff"];
tInfo["missbuff"] = nil;
end
tAllSwatches = VUHDO_getAllBuffSwatches();
for _, tUpdSwatch in pairs(tAllSwatches) do
if tUpdSwatch:IsShown() then VUHDO_updateBuffSwatch(tUpdSwatch); end
end
for tUnit, tInfo in pairs(VUHDO_RAID) do
if tOldMissBuffs[tUnit] ~= tInfo["missbuff"] then
tInfo["debuff"], tInfo["debuffName"] = VUHDO_determineDebuff(tUnit);
VUHDO_updateHealthBarsFor(tUnit, VUHDO_UPDATE_DEBUFF);
end
end
twipe(tOldMissBuffs);
end
--
function VUHDO_execSmartBuffPre(self)
if InCombatLockdown() then
UIErrorsFrame:AddMessage(VUHDO_I18N_SMARTBUFF_ERR_1, 1, 0.1, 0.1, 1);
return false;
end
local tAllSwatches = VUHDO_getAllBuffSwatchesOrdered();
local tVariants = nil;
local tTargetCode = nil;
local tRefSpell = nil;
local tMaxLow = 0;
local tMaxLowSpell = nil;
local tMaxLowTarget = nil;
local tCategSpec;
local tMissGroup, tLowGroup, tGoodTarget, tLowestUnit, tOorGroup;
local tNumLow, tCooldown, tTotalCd;
local tCooldown, tTotalCd;
for _, tCheckSwatch in ipairs(tAllSwatches) do
if tCheckSwatch:IsShown() then
tVariants = tCheckSwatch:GetAttribute("buff");
tTargetCode = tCheckSwatch:GetAttribute("target");
tCategSpec = tCheckSwatch:GetAttribute("buffname");
tRefSpell = tVariants[1];
tMissGroup, tLowGroup, tGoodTarget, _, tLowestUnit, _, tOorGroup, _
= VUHDO_getMissingBuffsForCode(tTargetCode, tVariants, tCategSpec);
tNumLow = #tMissGroup + #tLowGroup;
if not VUHDO_BUFFS[tRefSpell] or not VUHDO_BUFFS[tRefSpell]["id"] then
tCooldown, tTotalCd = 0, 0;
else
tCooldown, tTotalCd = VUHDO_getSpellCooldown(tRefSpell);
end
if tNumLow > tMaxLow and tCooldown <= 1.5 and VUHDO_BUFF_TARGET_HOSTILE ~= tVariants[2] then
if (tGoodTarget == nil) then
UIErrorsFrame:AddMessage(VUHDO_I18N_SMARTBUFF_ERR_2 .. tRefSpell, 1, 0.1, 0.1, 1);
elseif #tOorGroup > 0 then
UIErrorsFrame:AddMessage("VuhDo: " .. #tOorGroup .. VUHDO_I18N_SMARTBUFF_ERR_3 .. tRefSpell, 1, 0.1, 0.1, 1);
else
tMaxLow = tNumLow;
tMaxLowTarget = VUHDO_isUseSingleBuff(tCheckSwatch) and tLowestUnit or tGoodTarget;
tMaxLowSpell = tVariants[1];
end
end
end
end
if not tMaxLowSpell then
UIErrorsFrame:AddMessage(VUHDO_I18N_SMARTBUFF_ERR_4, 1, 1, 0.1, 1);
return;
end
if not VUHDO_BUFFS[tMaxLowSpell] or not VUHDO_BUFFS[tMaxLowSpell]["id"] then
tCooldown, tTotalCd = 0, 0;
else
tCooldown, tTotalCd = VUHDO_getSpellCooldown(tMaxLowSpell);
end
if tCooldown > 0 then return; end
local tName = VUHDO_RAID_NAMES[tMaxLowTarget] or VUHDO_RAID[tMaxLowTarget]["name"];
UIErrorsFrame:AddMessage(VUHDO_I18N_SMARTBUFF_OKAY_1 .. tMaxLowSpell .. VUHDO_I18N_SMARTBUFF_OKAY_2 .. tName, 0.1, 1, 0.1, 1);
VuhDoSmartCastGlassButton:SetAttribute("unit", tMaxLowTarget);
VuhDoSmartCastGlassButton:SetAttribute("type1", "spell");
VuhDoSmartCastGlassButton:SetAttribute("spell1", tMaxLowSpell);
end
--
function VUHDO_execSmartBuffPost()
VuhDoSmartCastGlassButton:SetAttribute("unit", nil);
VuhDoSmartCastGlassButton:SetAttribute("type1", nil);
end
--
function VUHDO_resetBuffSwatchInfos()
twipe(VUHDO_LAST_COLORS);
end