--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 oldCorruptionLevel; local L = Narci.L; local FadeFrame = NarciAPI_FadeFrame; local GetCorruptionResistance = GetCorruptionResistance; local GetCorruption = GetCorruption; 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 > oldCorruptionLevel then AnimFrame.endHeight = FILLED_BAR_HEIGHT; function CallBackFunc(self) oldCorruptionLevel = 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 < oldCorruptionLevel then AnimFrame.endHeight = 0.01; function CallBackFunc(self) oldCorruptionLevel = 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) oldCorruptionLevel = 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); oldCorruptionLevel = 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 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)