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.

1099 lines
36 KiB

--Narcissus Corruption Module for CharacterStatsPane
--Create a bar that shows: current corruption value and thresholds
local FILLED_BAR_HEIGHT = 75;
--Though contents will be localized\overwritten after login, I save these in case there's a bandwidth congestion caused by intalling too much addons.
local CorruptionEffectInfo = {
[1] = {["name"] = "Grasping Tendrils", ["description"] = "Taking damage has a chance to reduce your movement speed for 5 sec. The magnitude of the snare increases with further Corruption."},
[2] = {["name"] = "Eye of Corruption", ["description"] = "Your spells and abilities have a chance to summon an Eye of Corruption for 8 sec. The Eye inflicts increasing Shadow damage to you every 2 sec while you remain in range."},
[3] = {["name"] = "Grand Delusions", ["description"] = "Taking damage has a chance to summon a Thing From Beyond, which pursues you for 8 sec. Its speed increases with further Corruption."},
[4] = {["name"] = "Cascading Disaster", ["description"] = "If you are struck by the Thing From Beyond, you will be immediately afflicted by Grasping Tendrils and Eye of Corruption."},
[5] = {["name"] = "Inevitable Doom", ["description"] = "All damage taken is magnified and healing received is reduced, increasing with further Corruption."},
};
local _, addon = ...
local OLD_CURRUPTION_LEVEL;
local L = Narci.L;
local FadeFrame = NarciAPI_FadeFrame;
local GetCorruptionResistance = GetCorruptionResistance;
local GetCorruption = GetCorruption;
local GetSpellInfo = addon.TransitionAPI.GetSpellInfo;
local pi = math.pi;
local cos = math.cos;
local max = math.max;
local min = math.min;
local floor = math.floor;
local CR_VERSATILITY_DAMAGE_TAKEN = CR_VERSATILITY_DAMAGE_TAKEN;
local function inOutSine(t, b, e, d)
return (b - e) / 2 * (cos(pi * t / d) - 1) + b
end
local AnimFrame = CreateFrame("Frame");
AnimFrame.t = 0;
AnimFrame.duration = 1;
AnimFrame:Hide();
local function UpdateDuration(self)
self.duration = max(math.abs(self.endHeight - self.startHeight) / 92, 0.4);
end
local function OnShowFunc(self)
self.t = 0;
UpdateDuration(self);
end
local function CallBackFunc(self)
self:Hide();
end
local function OnUpdateFunc(self, elapse)
self.t = self.t + elapse;
local height = inOutSine(self.t, self.startHeight, self.endHeight, self.duration);
if self.t >= self.duration then
height = self.endHeight;
CallBackFunc(self);
end
self.Bar:SetHeight(height);
end
AnimFrame:SetScript("OnShow", OnShowFunc);
AnimFrame:SetScript("OnUpdate", OnUpdateFunc);
local function SetBarTexts(corruptionLevel, totalCorruption)
local frame = Narci_CorruptionBar;
local Ceiling, Floor;
if corruptionLevel == 0 then
Ceiling = GetCorruptionResistance() or 0;
Floor = 0;
elseif corruptionLevel == 1 then
Ceiling = 20;
Floor = 1;
elseif corruptionLevel == 5 then
Ceiling = 0;
Floor = 80;
else
Ceiling = 20 * corruptionLevel;
Floor = Ceiling - 20;
end
local COLOR;
if corruptionLevel < 1 then
--When corruption level is 0, show total curruption and resistance
COLOR = "|cffa59bb5"; --Purple
elseif corruptionLevel < 2 then
COLOR = "|cffdbbc34"; --Yellow
elseif corruptionLevel < 4 then
COLOR = "|cfff26522"; --Orange
else
COLOR = "|cffee3224"; --red
end
--Avoid text overlapping
local diff = (Ceiling - totalCorruption)/(Ceiling - Floor);
local offsetY = 0;
if diff <= 0 or diff >= 1 then
offsetY = 0;
elseif diff <= 0.05 then
offsetY = -7;
elseif diff <= 0.1 then
offsetY = -6;
elseif diff >= 0.95 then
offsetY = 7;
elseif diff >= 0.9 then
offsetY = 6;
else
offsetY = 0;
end
frame.Current:SetPoint("LEFT", frame.Fluid, "TOP", 7, offsetY);
--
local Current = totalCorruption.." "..COLOR..corruptionLevel .."|r";
if Floor == 0 then
Floor = "";
end
if Ceiling == 0 then
Ceiling = "";
end
frame.Current:SetText(Current);
frame.Ceiling:SetText(Ceiling);
frame.Floor:SetText(Floor);
end
local function SmoothHeight(height, newCorruptionLevel, totalCorruption)
if not AnimFrame.Bar then
AnimFrame.Bar = Narci_CorruptionBar.Fluid;
end
AnimFrame:Hide();
AnimFrame.startHeight = AnimFrame.Bar:GetHeight();
if newCorruptionLevel > OLD_CURRUPTION_LEVEL then
AnimFrame.endHeight = FILLED_BAR_HEIGHT;
function CallBackFunc(self)
OLD_CURRUPTION_LEVEL = newCorruptionLevel;
AnimFrame.t = 0;
AnimFrame.startHeight = 0;
AnimFrame.endHeight = height;
if newCorruptionLevel > 0 then
AnimFrame.Bar:SetTexCoord(0.9375, 1, 0, 1);
end
UpdateDuration(self);
SetBarTexts(newCorruptionLevel, totalCorruption);
function CallBackFunc(self)
self:Hide();
end
end
elseif newCorruptionLevel < OLD_CURRUPTION_LEVEL then
AnimFrame.endHeight = 0.01;
function CallBackFunc(self)
OLD_CURRUPTION_LEVEL = newCorruptionLevel;
AnimFrame.t = 0;
AnimFrame.startHeight = FILLED_BAR_HEIGHT;
AnimFrame.endHeight = height;
if newCorruptionLevel == 0 then
AnimFrame.Bar:SetTexCoord(0.875, 0.9375, 0, 1);
end
UpdateDuration(self);
SetBarTexts(newCorruptionLevel, totalCorruption);
function CallBackFunc(self)
self:Hide();
end
end
else
AnimFrame.endHeight = height;
function CallBackFunc(self)
OLD_CURRUPTION_LEVEL = newCorruptionLevel;
self:Hide();
end
SetBarTexts(newCorruptionLevel, totalCorruption);
end
AnimFrame.newCorruptionLevel = newCorruptionLevel;
AnimFrame:Show();
end
function Narci_SetCorruptionBar(self, smooth)
local corruption = GetCorruption();
local corruptionResistance = GetCorruptionResistance();
local totalCorruption = max(corruption - corruptionResistance, 0);
local Ceiling, Floor, corruptionLevel;
local barHeight;
if corruption > 0 then
if totalCorruption < 1 then
Ceiling = corruptionResistance;
Floor = 0;
corruptionLevel = 0;
elseif totalCorruption < 20 then
Ceiling = 20;
Floor = 1;
corruptionLevel = 1;
elseif totalCorruption < 40 then
Ceiling = 40;
Floor = 20;
corruptionLevel = 2;
elseif totalCorruption < 60 then
Ceiling = 60;
Floor = 40;
corruptionLevel = 3;
elseif totalCorruption < 80 then
Ceiling = 80;
Floor = 60;
corruptionLevel = 4;
else
Ceiling = 80;
Floor = 80;
corruptionLevel = 5;
end
if corruptionLevel == 5 then
barHeight = FILLED_BAR_HEIGHT;
elseif corruptionLevel == 0 then
barHeight = max(FILLED_BAR_HEIGHT * corruption / Ceiling, 0.01);
totalCorruption = corruption;
else
barHeight = max(FILLED_BAR_HEIGHT * (totalCorruption - Floor) / (Ceiling - Floor), 0.01);
end
if totalCorruption > 80 then
--No cap when exceeding 80 corruption
Ceiling = "";
end
else
corruptionLevel = 0;
Ceiling = "";
Floor = "";
barHeight = 0.01;
end
if smooth then
SmoothHeight(barHeight, corruptionLevel, totalCorruption);
else
self.Fluid:SetHeight(barHeight);
SetBarTexts(corruptionLevel, totalCorruption);
OLD_CURRUPTION_LEVEL = corruptionLevel;
if corruptionLevel == 0 then
self.Fluid:SetTexCoord(0.875, 0.9375, 0, 1);
else
self.Fluid:SetTexCoord(0.9375, 1, 0, 1);
end
end
end
function Narci_CorruptionBar_OnEvent(self)
if not self.IsRefreshing then
self.IsRefreshing = true;
C_Timer.After(0, function()
Narci_SetCorruptionBar(self, true);
self.IsRefreshing = nil;
end)
end
end
local format = string.format;
local BreakUpLargeNumbers = BreakUpLargeNumbers;
local function SetTooltipText(entry, text1, text2)
local str;
if text2 then
str = format(entry.format, BreakUpLargeNumbers(text1), text2);
else
str = format(entry.format, text1);
end
entry.Effect:SetText(str);
end
local SetUpModel = NarciAPI_SetupModelScene;
local eyeOffset = 1.5;
local playerOffsetX = 0;
local playerOffsetZ = -0.5;
local playerModelInfo;
local PI = math.pi;
local facing = -PI/2.5;
local ModelOffsets = {
--[raceID] = {Eye male's, female's, male's Z, female's Z}
[1] = {1.6, 1.5, -0.58, -0.6}, -- Human
[2] = {1.6, 1.5, -0.54, -0.6}, -- Orc bow
[3] = {1.7, 1.5, -0.3, -0.4}, -- Dwarf
[4] = {1.6, 1.5, -0.8, -0.65}, -- Night Elf
[5] = {1.6, 1.5, -0.54, -0.5}, -- UD 0.9585 seems small
[6] = {1.9, 1.7, -0.6, -0.6}, -- Tauren
[7] = {1.7, 1.7, -0.1, -0.2}, -- Gnome
[8] = {1.6, 1.5, -0.58, -0.6}, -- Troll 0.9414 too high?
[9] = {1.8, 1.8, -0.32, -0.25}, -- Goblin
[10] = {1.45, 1.4, -0.58, -0.6}, -- Blood Elf
[11] = {1.6, 1.5, -0.6, -0.6}, -- Goat
[22] = {1.75, 1.5, -0.6, -0.6}, -- Worgen
[24] = {1.85, 1.7, -0.42, -0.58}, -- Pandaren
[27] = {1.45, 1.4, -0.72, -0.6}, -- Nightborne
--[29] = {1, }, -- Void Elf
--[28] = {490, 491}, -- Highmountain Tauren
--[30] = {488, 489}, -- Lightforged Draenei
[31] = {1.6, 1.5, -0.85, -0.8}, -- Zandalari
[32] = {1.7, 1.65, -0.6, -0.65}, -- Kul'Tiran
--[34] = {499, nil}, -- Dark Iron Dwarf
[35] = {1.7, 1.5, -0.3, -0.25}, -- Vulpera
--[36] = {495, 498}, -- Mag'har
--[37] = {929, 931}, -- Mechagnome
}
local function SetModelOffset()
local unit = "player";
local _, _, raceID = UnitRace(unit);
local genderID = UnitSex(unit);
if genderID and raceID then
genderID = genderID - 1;
else
return
end
if raceID == 25 or raceID == 26 then --Pandaren A|H
raceID = 24;
elseif raceID == 29 then
raceID = 10;
elseif raceID == 37 then
raceID = 7;
elseif raceID == 30 then
raceID = 11;
elseif raceID == 28 then
raceID = 6;
elseif raceID == 34 then
raceID = 3;
elseif raceID == 36 then
raceID = 2;
elseif raceID == 22 then
local _, inAlternateForm = HasAlternateForm();
if not inAlternateForm then
--Wolf
raceID = 22;
else
raceID = 1;
end
end
--Set offsetX for a few
if raceID == 11 then
if genderID == 1 then
playerOffsetX = 0.2;
end
elseif raceID == 2 then
playerOffsetX = -0.04;
elseif raceID == 5 then
if genderID == 1 then
playerOffsetX = -0.05;
else
playerOffsetX = -0.03;
end
elseif raceID == 24 then
if genderID == 1 then
playerOffsetX = -0.035;
end
elseif raceID == 31 then
if genderID == 1 then
playerOffsetX = -0.04;
end
elseif raceID == 35 then
playerOffsetX = -0.04;
elseif raceID == 27 then
if genderID == 2 then
playerOffsetX = -0.06;
end
end
local info = ModelOffsets[raceID];
if info then
eyeOffset = info[genderID] or eyeOffset;
playerOffsetZ = info[genderID + 2] or playerOffsetZ;
end
end
local playerSpeed = 1; --Alter animation when corruption changes
local chasingSpeed = 0.25;
local ringScale = 0.32; --
local ringOffset = -1.65; --
local function CalculateAnimation(corruption)
--Calculate running speed
playerSpeed = max( (100 - corruption - 10) / 100, 0.1);
chasingSpeed = max( (corruption - 15) / 100, 0.25);
ringScale = 0.18 + max( (corruption - 20) / 200 , 0);
ringOffset = min(-1.8 + ringScale , 0.5)
end
local function SetPlayerModel(model, visualIDs, animationID, fullBody, isReverseSpeed)
local playerActor = model.narciPlayerActor;
playerActor:ClearModel()
playerActor:SetAlpha(0);
local camera = model.narciPlayerCamera;
model:SetActiveCamera(camera);
--must-do
playerActor:SetSpellVisualKit(nil)
playerActor:SetModelByUnit("player");
------
C_Timer.After(0.0, function()
playerActor:SetSheathed(true);
playerActor:SetAlpha(1);
model:InitializeActor(playerActor, playerModelInfo); --Re-scale
local zoom;
if fullBody then
playerActor:SetYaw(-3.14/3);
playerActor:SetPosition(0, 0, 0);
zoom = 3.8;
else
playerActor:SetYaw(facing);
playerActor:SetPosition(playerOffsetX, 0, playerOffsetZ);
zoom = NarciAPI_GetCameraZoomDistanceByUnit("player");
end
if isReverseSpeed then
playerActor:SetAnimation(animationID, 0, chasingSpeed, 0);
else
playerActor:SetAnimation(animationID, 0, playerSpeed, 0);
end
--playerActor:SetDesaturation(0);
camera:SetZoomDistance(1.5);
camera:SnapAllInterpolatedValues();
C_Timer.After(0.0, function()
camera:SetZoomDistance(zoom);
if visualIDs then
local _type = type(visualIDs);
if _type == "number" then
playerActor:SetSpellVisualKit(visualIDs);
elseif _type == "table" then
for i = 1, #visualIDs do
playerActor:SetSpellVisualKit(visualIDs[i]);
end
end
else
playerActor:SetSpellVisualKit(nil);
end
end)
end);
end
local function SetPreview(index)
local model = Narci_CorruptionTooltip.ModelScene;
if index == model.previewIndex then
return
else
model.previewIndex = index;
end
if index == 1 then
SetModelOffset();
local effect1 = model.narciEffectActor1;
if effect1 then
effect1:Hide();
end
local effect2 = model.narciEffectActor2;
if effect2 then
effect2:Hide();
end
local actor = model.narciPlayerActor;
if actor then
actor:Hide();
end
local animationID;
if playerSpeed > 0.6 then
animationID = 5;
else
animationID = 4;
end
SetPlayerModel(model, {121838, 123875}, animationID, true, false); --123874 Red 123875 Purple residue
elseif index == 2 then
SetUpModel(model, 3004122, 3, "FRONT", 1, true);
SetUpModel(model, 943454, nil, {PI/12, PI}, 2);
local effect1 = model.narciEffectActor1;
effect1:SetPosition(0, 0, -1.65);
effect1:SetRequestedScale(1);
effect1:Show();
E1 = effect1;
local effect2 = model.narciEffectActor2;
effect2:SetRequestedScale(ringScale);
effect2:SetAnimation(158, 0, 0.5);
effect2:SetPosition(0, 0, ringOffset);
effect2:SetAlpha(1);
effect2:Show();
local actor = model.narciPlayerActor;
if actor then
actor:Hide();
end
elseif index == 3 then
SetModelOffset();
local effect1 = model.narciEffectActor1;
if effect1 then
effect1:SetAlpha(0);
C_Timer.After(0, function()
effect1:SetModelByFileID(611777); --Fixate Eye
effect1:SetPosition(0, 0, eyeOffset);
effect1:SetRequestedScale(0.8);
effect1:Show();
effect1:SetAlpha(1);
end)
end
local effect2 = model.narciEffectActor2;
if effect2 then
effect2:Hide();
end
local animationID;
if chasingSpeed > 0.75 then
animationID = 5;
else
animationID = 4;
end
SetPlayerModel(model, 111381, animationID, false, true); --Ghost 111381
elseif index == 4 then
SetModelOffset();
local effect1 = model.narciEffectActor1;
if effect1 then
effect1:Hide();
end
local effect2 = model.narciEffectActor2;
if effect2 then
effect2:Hide();
end
local actor = model.narciPlayerActor;
if actor then
actor:Hide();
end
SetPlayerModel(model, 78248, 4, false, false);
elseif index == 5 then
SetModelOffset();
local effect1 = model.narciEffectActor1;
if effect1 then
effect1:Hide();
end
local effect2 = model.narciEffectActor2;
if effect2 then
effect2:Hide();
end
local actor = model.narciPlayerActor;
if actor then
actor:Hide();
end
SetPlayerModel(model, 123874, 4, false, false);
end
end
local UIFrameFadeOut = UIFrameFadeOut;
local UIFrameFadeIn = UIFrameFadeIn;
local RunDelayedFunction = NarciAPI_RunDelayedFunction;
local function EntryButton_OnEnter(self)
self.Pointer:Show();
RunDelayedFunction(self, 0.2, function()
UIFrameFadeOut(self.Effect, 0.15, self.Effect:GetAlpha(), 0);
UIFrameFadeOut(self.Name, 0.15, self.Name:GetAlpha(), 0);
C_Timer.After(0.12, function()
if self:IsMouseOver() then
UIFrameFadeIn(self.Description, 0.15, 0, 1);
if not self:IsEnabled() then
return
end
SetPreview(self.id);
end
end)
end);
end
local function EntryButton_OnLeave(self)
self.Pointer:Hide();
local finalAlpha;
if self:IsEnabled() then
finalAlpha = 1;
else
finalAlpha = 0.4;
end
UIFrameFadeOut(self.Effect, 0.2, self.Effect:GetAlpha(), finalAlpha);
UIFrameFadeOut(self.Name, 0.2, self.Name:GetAlpha(), 1);
UIFrameFadeOut(self.Description, 0.2, self.Description:GetAlpha(), 0);
end
local function UpdateBarHeight(bar, effectiveCorruption)
local totalHeight = bar:GetHeight();
local tabHeight = totalHeight/5;
local height;
if effectiveCorruption == 1 then
height = tabHeight;
elseif effectiveCorruption == 0 then
height = 0;
else
height = tabHeight + 0.8*totalHeight* (min( effectiveCorruption / 80, 1));
end
bar.FluidFrame:SetHeight(height);
end
local IsSpellKnown = IsSpellKnown;
local function GetMagicReduction()
--Calculate passive reduction
local r;
if IsSpellKnown(203513) then
r = 0.15; --Demonic Wards Vengeance
elseif IsSpellKnown(278386) then
r = 0.1; --Demonic Wards Havoc
elseif IsSpellKnown(255668) or IsSpellKnown(59221) or IsSpellKnown(20579) then
r = 0.01; --1% Shadow DMG Racial VE, UD, Draenei --Highmountain omitted
else
r = 0;
end
return (1-r)
end
local function GetConstantReduction()
local r;
if IsSpellKnown(255659) then
r = UnitHealthMax("player") * 0.0003; --Highmountain Tauren Racial Rugged Tenacity
else
r = 0;
end
return r
end
local function UpdateCorruptionTooltip()
local corruption = GetCorruption();
local corruptionResistance = GetCorruptionResistance();
local corruption = max(corruption - corruptionResistance, 0);
local frame = Narci_CorruptionTooltip;
local slowBy, damageModifier, radius, delusionDamage, percentageHP;
local entry;
local level = 1;
local HP = UnitHealthMax("player");
local magicReduction = GetMagicReduction();
local eyeDamage = (0.5*corruption + 15) * (HP/1000) * magicReduction;
local delusionDamage = 0.35 * HP * magicReduction;
if corruption >= 1 then
level = 1;
frame.Entry1:Enable();
slowBy = min(corruption + 10, 99);
damageModifier = max(corruption - 75, 0);
radius = max(floor(10 * corruption / 4)/10, 5);
if corruption >= 20 then
level = 2;
frame.Entry2:Enable();
if corruption >= 40 then
level = 3;
frame.Entry3:Enable();
if corruption >= 60 then
level = 4;
frame.Entry4:Enable();
if corruption >= 80 then
level = 5;
frame.Entry5:Enable();
else
frame.Entry5:Disable();
end
else
frame.Entry4:Disable();
frame.Entry5:Disable();
end
else
frame.Entry3:Disable();
frame.Entry4:Disable();
frame.Entry5:Disable();
end
else
frame.Entry2:Disable();
frame.Entry3:Disable();
frame.Entry4:Disable();
frame.Entry5:Disable();
end
else
slowBy = 0;
damageModifier = 0;
radius = 5;
for i = 1, 5 do
entry = frame["Entry"..i];
entry:Disable();
end
end
CalculateAnimation(corruption);
SetPreview(level);
local reduction = GetCombatRatingBonus(CR_VERSATILITY_DAMAGE_TAKEN) + GetVersatilityBonus(CR_VERSATILITY_DAMAGE_TAKEN);
local constantReduction = GetConstantReduction(); --Reduction as constant instead of percentage
eyeDamage = floor(eyeDamage * (1 + damageModifier / 100) * (1 - reduction/100) + 0.5 - constantReduction);
delusionDamage = floor(delusionDamage * (1 + damageModifier / 100) * (1 - reduction/100) + 0.5 - constantReduction); --change me when they fix the bug
percentageHP = floor(10000 * delusionDamage / HP + 0.5) / 100;
SetTooltipText(frame.Entry1, slowBy);
SetTooltipText(frame.Entry2, eyeDamage, radius);
SetTooltipText(frame.Entry3, delusionDamage, percentageHP);
SetTooltipText(frame.Entry5, damageModifier);
UpdateBarHeight(frame.CorruptionBar, corruption);
local COLOR; --for corruption value
if level < 1 then
--When corruption level is 0, show total curruption and resistance
COLOR = "|cffa59bb5"; --Purple
elseif level < 2 then
COLOR = "|cffdbbc34"; --Yellow
elseif level < 4 then
COLOR = "|cfff26522"; --Orange
else
COLOR = "|cffee3224"; --red
end
frame.CorruptionBar.OverlayFrame.CorruptionValue:SetText(COLOR..corruption);
end
local function CorruptionTooltip_OnEvent(self)
if not self.IsRefreshing then
self.IsRefreshing = true;
C_Timer.After(0, function()
UpdateCorruptionTooltip(self, true);
self.IsRefreshing = nil;
end)
end
end
local function CorruptionTooltip_OnShow(self)
local bar = Narci_CorruptionBar;
if bar:IsShown() then
UIFrameFadeOut(bar, 0.25, 0 ,0);
end
self:RegisterEvent("COMBAT_RATING_UPDATE");
UpdateCorruptionTooltip();
end
local function CorruptionTooltip_OnHide(self)
self:UnregisterEvent("COMBAT_RATING_UPDATE");
local bar = Narci_CorruptionBar;
if bar:IsShown() then
UIFrameFadeIn(bar, 0.25, bar:GetAlpha() ,1);
end
self.ModelScene.previewIndex = -1;
self:Hide();
self:SetAlpha(0);
end
local function ShowOrHideModel()
local state = NarcissusDB.CorruptionTooltipModel;
local tooltip = Narci_CorruptionTooltip;
local button = tooltip.ModelToggle;
local model = tooltip.ModelScene;
if state then
button.tex1:SetTexCoord(0, 0.5, 0, 1);
button.tex2:SetTexCoord(0.5, 1, 0, 1);
button.tex3:SetTexCoord(0.5, 1, 0, 1);
model:Show();
tooltip:SetWidth(tooltip.expandedWidth);
tooltip.CloseButton:Show();
else
button.tex1:SetTexCoord(0.5, 0, 0, 1);
button.tex2:SetTexCoord(1, 0.5, 0, 1);
button.tex3:SetTexCoord(1, 0.5, 0, 1);
model:Hide();
tooltip:SetWidth(tooltip.basicWidth);
tooltip.CloseButton:Hide();
end
end
local function ModelToggle_OnClick(self)
NarcissusDB.CorruptionTooltipModel = not NarcissusDB.CorruptionTooltipModel;
ShowOrHideModel();
end
local function InitializeCorruptionTooltip()
--Set up the constant: Spell name, icon
local NUM_TAB = 5;
local TAB_HEIGHT = 72;
local BAR_WIDTH = 6;
local frame = Narci_CorruptionTooltip;
local entry;
local icons = {537022, 3004126, 1391768, 1119888, 575534};
local text;
--Set Scripts
frame:SetScript("OnEvent", CorruptionTooltip_OnEvent);
frame:SetScript("OnShow", CorruptionTooltip_OnShow);
frame:SetScript("OnHide", CorruptionTooltip_OnHide);
frame.ModelToggle:SetScript("OnClick", ModelToggle_OnClick);
--Sizing
local basicWidth, basicHeight = frame.Entry1:GetSize();
local totalHeight = basicHeight * NUM_TAB;
local modelWidth = totalHeight * 3/4;
local entryWidth = basicWidth;
for i = 1, NUM_TAB do
entry = frame["Entry"..i];
entry.id = i;
entry:SetHeight(TAB_HEIGHT);
entry.Name:SetText(CorruptionEffectInfo[i].name);
text = CorruptionEffectInfo[i].description;
entry.Description:SetText(CorruptionEffectInfo[i].description);
entry.format = L["Corruption Effect Format"..i];
entry.Icon:SetTexture(icons[i]);
entry.IconHighlight:SetTexture(icons[i]);
entry:SetScript("OnEnter", EntryButton_OnEnter);
entry:SetScript("OnLeave", EntryButton_OnLeave);
entry:SetScript("OnClick", function(self)
SetPreview(self.id);
for p = 1, NUM_TAB do
if p ~= i then
entry = frame["Entry"..p];
entry.Pointer:Hide();
entry.IsOn = false;
end
end
self.Pointer:Show();
self.IsOn = true;
end);
if i <= 3 then
entry:Enable();
end
end
SetTooltipText(frame.Entry4, "");
local parentFrame = CharacterStatsPane.ItemLevelFrame.Corruption;
C_Timer.After(0, function()
for i = 1, NUM_TAB do
entry = frame["Entry"..i];
while entry.Description:IsTruncated() do
entryWidth = frame.Entry1:GetWidth() + 10;
frame.Entry1:SetWidth(entryWidth);
end
end
local model = frame.ModelScene;
model:SetWidth(modelWidth);
local totalWidth = modelWidth + entryWidth + BAR_WIDTH;
frame:SetSize(totalWidth, totalHeight);
frame.basicWidth = entryWidth + BAR_WIDTH;
frame.expandedWidth = totalWidth;
local camera, playerActor;
SetModelOffset();
model:TransitionToModelSceneID(290, 1, 1, true);
SetupPlayerForModelScene(model, nil, true, true); --3 sheathWeapon
playerActor = model:GetPlayerActor();
playerActor:SetModelByUnit("player")
model.narciPlayerActor = playerActor;
camera = model:GetActiveCamera();
camera.minZoomDistance = 1.5;
model.narciPlayerCamera = camera;
SetPreview(2);
model.previewIndex = -1;
if parentFrame then
frame:ClearAllPoints();
frame:SetParent(parentFrame);
frame:SetPoint("TOPLEFT", parentFrame, "TOPRIGHT", -10, 12);
else
frame:Hide();
end
ShowOrHideModel();
UpdateCorruptionTooltip();
end)
end
--------------------------------------------------------------------------------------------------------
--Automatically toggle character pane when clicking upgrade item (Corrupting Core, Horrific Core)
--Show Highlight for backslot
local GetContainerItemID = GetContainerItemID;
local GetInventoryItemID = GetInventoryItemID;
local BlizzardCorruptionWidget_OnEnterFunction;
local BlizzardCorruptionWidget_OnLeaveFunction;
local function NewOnEnter(self)
local frame = Narci_CorruptionTooltip;
frame:ClearAllPoints();
frame.ModelScene.Background:SetGradientAlpha("VERTICAL", 1, 1, 1, 1, 1, 1, 1, 0.1);
frame:SetScale(1);
frame:SetParent(CharacterFrame);
frame:SetHitRectInsets(0, -32, -32, -24);
frame:SetPoint("TOPLEFT", self, "TOPRIGHT", -10, 12);
FadeFrame(frame, 0.2, "IN");
--Original
self.tooltipShowing = true;
self.Eye:SetAtlas("Nzoth-charactersheet-icon-glow", true);
PaperDollFrame_UpdateCorruptedItemGlows(true);
PlaySound(SOUNDKIT.NZOTH_EYE_SQUISH);
end
local function NewOnLeave(self)
local frame = Narci_CorruptionTooltip;
if not frame:IsMouseOver(0, 0, -6, 0) then
FadeFrame(frame, 0.2, "OUT");
end
--Original
self.tooltipShowing = false;
self.Eye:SetAtlas("Nzoth-charactersheet-icon", true);
PaperDollFrame_UpdateCorruptedItemGlows(false);
end
local function ShowItemlevelAndCorruptionInfo(frame)
if ( not frame.tooltip ) then
return;
end
GameTooltip:SetOwner(frame, "ANCHOR_RIGHT");
GameTooltip:SetText(frame.tooltip);
if ( frame.tooltip2 ) then
GameTooltip:AddLine(frame.tooltip2, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true);
end
local corruption = GetCorruption();
if corruption > 0 then
local corruptionResistance = GetCorruptionResistance();
local totalCorruption = math.max(corruption - corruptionResistance, 0);
GameTooltip_AddBlankLineToTooltip(GameTooltip);
GameTooltip_AddColoredDoubleLine(GameTooltip, CORRUPTION_TOOLTIP_LINE, corruption, HIGHLIGHT_FONT_COLOR, HIGHLIGHT_FONT_COLOR, false);
GameTooltip_AddColoredDoubleLine(GameTooltip, CORRUPTION_RESISTANCE_TOOLTIP_LINE, corruptionResistance, HIGHLIGHT_FONT_COLOR, HIGHLIGHT_FONT_COLOR, false);
GameTooltip_AddColoredDoubleLine(GameTooltip, TOTAL_CORRUPTION_TOOLTIP_LINE, totalCorruption, CORRUPTION_COLOR, CORRUPTION_COLOR, false);
end
end
--Preferences Corruption Tooltip Toggle--
local function ItemLevelFrame_OnEnter(self)
ShowItemlevelAndCorruptionInfo(self);
GameTooltip:Show();
end
local function ItemLevelFrame_withCorruptionTooltips_OnEnter(self)
ShowItemlevelAndCorruptionInfo(self)
CorruptionTooltips:SummaryHook(self);
GameTooltip:Show();
end
function Narci:SetUseCorruptionTooltip()
local ItemLevelFrame = CharacterStatsPane.ItemLevelFrame;
local BlizzardCorruptionWidget = ItemLevelFrame.Corruption;
if not BlizzardCorruptionWidget then return end
local IsAddOnLoaded = C_AddOns.IsAddOnLoaded;
local state = NarcissusDB.CorruptionTooltip;
if state then
GameTooltip_Hide();
if IsAddOnLoaded("CorruptionTooltips") then
ItemLevelFrame.onEnterFunc = ItemLevelFrame_withCorruptionTooltips_OnEnter;
else
ItemLevelFrame.onEnterFunc = ItemLevelFrame_OnEnter;
end
BlizzardCorruptionWidget:SetScript("OnEnter", NewOnEnter);
BlizzardCorruptionWidget:SetScript("OnLeave", NewOnLeave);
else
ItemLevelFrame.onEnterFunc = nil;
Narci_CorruptionTooltip:Hide();
BlizzardCorruptionWidget:SetScript("OnLeave", CharacterFrameCorruption_OnLeave);
if IsAddOnLoaded("CorruptionTooltips") then
BlizzardCorruptionWidget:SetScript("OnEnter", function(self)
CharacterFrameCorruption_OnEnter(self)
CorruptionTooltips:SummaryHook(self);
end)
else
BlizzardCorruptionWidget:SetScript("OnEnter", CharacterFrameCorruption_OnEnter);
end
end
--Fix Compatible Issue with DejaCharacterStats
if not NarcissusDB.CorruptionBar then return end
if IsAddOnLoaded("DejaCharacterStats") then
local Bar = Narci_CorruptionBar;
BlizzardCorruptionWidget:SetScript("OnHide", function(self)
Bar:SetAlpha(0);
end)
BlizzardCorruptionWidget:SetScript("OnShow", function(self)
Bar:SetAlpha(1);
end)
Bar:ClearAllPoints();
Bar:SetParent(CharacterFrame);
Bar:SetPoint("TOPLEFT", CharacterFrame, "TOPRIGHT", -4, -48);
if BlizzardCorruptionWidget:IsVisible() then
Bar:SetAlpha(1);
else
Bar:SetAlpha(0);
end
end
end
local function CorruptionTooltipSwitch_OnClick()
NarcissusDB.CorruptionTooltip = not NarcissusDB.CorruptionTooltip;
Narci:SetUseCorruptionTooltip()
end
local function GetCorruptionDescription(corruptionSpells)
local spellID, name, description;
local IsSpellCached = C_Spell.IsSpellDataCached;
for i = 1, #corruptionSpells do
spellID = corruptionSpells[i];
if IsSpellCached(spellID) and not CorruptionEffectInfo[i].isLocalized then
CorruptionEffectInfo[i].isLocalized = true;
name = GetSpellInfo(spellID);
if name and name ~= "" then
CorruptionEffectInfo[i].name = name;
end
description = GetSpellDescription(spellID);
if description and description ~= "" then
description = string.gsub(description, "\n.+", "");
CorruptionEffectInfo[i].description = description;
end
else
corruptionSpells.iteration = corruptionSpells.iteration + 1;
if corruptionSpells.iteration <= 8 then
C_Spell.RequestLoadSpellData(spellID);
C_Timer.After(0.2, function()
GetCorruptionDescription(corruptionSpells);
end)
return
else
InitializeCorruptionTooltip();
end
end
end
InitializeCorruptionTooltip();
C_Timer.After(0.2, function()
SetPreview(2);
end);
end
local Initialize = CreateFrame("Frame");
Initialize:RegisterEvent("PLAYER_ENTERING_WORLD");
Initialize:SetScript("OnEvent", function(self, event, ...)
self:UnregisterEvent(self);
local level = UnitLevel("player");
if level == 120 then
hooksecurefunc("UseContainerItem", function(bag, slot)
if bag and slot then
local id = GetContainerItemID(bag, slot);
if id == 171335 or id == 171354 or id == 171355 or id == 175062 then
id = GetInventoryItemID("player", 15); --Legendary Cloak
if id and id == 169223 then
ShowUIPanel(CharacterFrame);
local subFrame = _G["PaperDollFrame"];
if not subFrame:IsShown() then
ToggleCharacter("PaperDollFrame");
end
Narci_CloakHighlight.Bling:Play();
end
end
end
end)
end
SetModelOffset();
playerModelInfo = NarciAPI_GetActorInfoByUnit("player");
local BlizzardCorruptionWidget = CharacterStatsPane.ItemLevelFrame.Corruption;
if BlizzardCorruptionWidget then
BlizzardCorruptionWidget_OnEnterFunction = BlizzardCorruptionWidget:GetScript("OnEnter");
BlizzardCorruptionWidget_OnLeaveFunction = BlizzardCorruptionWidget:GetScript("OnLeave"); --Just in case they get changed in the future
end
Narci:SetUseCorruptionTooltip();
--Cache Negative Corruption Effect Info
local corruptionSpells = {
315176, --Grasping Tendrils
315154, --Eye of Corruption
315184, --Grand Delusions
315857, --Cascading Disaster
315179, --Inevitable Doom
}
for k, v in pairs(corruptionSpells) do
GetSpellInfo(v);
GetSpellDescription(v);
end
corruptionSpells.iteration = 0;
C_Timer.After(0.5, function()
GetCorruptionDescription(corruptionSpells);
end)
end)