--[[
This work is licensed under the Creative Commons Attribution - NonCommercial - ShareAlike 4.0 International License . To view a copy of this license , visit http : // creativecommons.org / licenses / by - nc - sa / 4.0 / .
--]]
--Settings storaged in NarcissusDB
local _ , addon = ...
local MsgAlertContainer = addon.MsgAlertContainer ;
local Narci = Narci ;
Narci.refreshCombatRatings = true ;
local slotTable = { } ;
local statTable = { } ;
local statTable_Short = { } ;
local L = Narci.L ;
local VIGNETTE_ALPHA = 0.5 ;
local IS_OPENED = false ; --Addon was opened by clicking
local MOG_MODE = false ;
local xmogMode = 0 ; -- 0 off 1 "Texts Only" 2 "Texts & Model"
local GetItemEnchantID = NarciAPI.GetItemEnchantID ;
local GetItemEnchantText = NarciAPI.GetItemEnchantText ;
local EnchantInfo = Narci.EnchantData ; --Bridge/GearBonus.lua
local IsItemSourceSpecial = NarciAPI.IsItemSourceSpecial ;
local Narci_LetterboxAnimation = NarciAPI_LetterboxAnimation ;
local SmartFontType = NarciAPI.SmartFontType ;
local LanguageDetector = NarciAPI.LanguageDetector ;
local IsItemSocketable = NarciAPI.IsItemSocketable ;
local SetBorderTexture = NarciAPI.SetBorderTexture ;
local GetBorderArtByItemID = NarciAPI.GetBorderArtByItemID ;
local DoesItemHaveDomationSocket = NarciAPI.DoesItemHaveDomationSocket ;
local GetDominationBorderTexture = NarciAPI.GetDominationBorderTexture ;
local GetItemDominationGem = NarciAPI.GetItemDominationGem ;
local GetVerticalRunicLetters = NarciAPI.GetVerticalRunicLetters ;
local GetTemporaryItemBuff = NarciAPI.GetTemporaryItemBuff ;
local FadeFrame = NarciFadeUI.Fade ;
--local GetCorruptedItemAffix = NarciAPI_GetCorruptedItemAffix;
local Narci_AlertFrame_Autohide = Narci_AlertFrame_Autohide ;
local C_Item = C_Item ;
local C_TransmogCollection = C_TransmogCollection ;
local After = C_Timer.After ;
local ItemLocation = ItemLocation ;
local GetAlternateFormInfo = C_PlayerInfo.GetAlternateFormInfo or HasAlternateForm ;
local floor = math.floor ;
local sin = math.sin ;
local cos = math.cos ;
local pi = math.pi ;
local max = math.max ;
local UIParent = _G.UIParent ;
local EquipmentFlyoutFrame ;
local ItemLevelFrame ;
local Toolbar ;
local RadarChart ;
local MiniButton ;
local NarciThemeUtil = NarciThemeUtil ;
hooksecurefunc ( " StaticPopup_Show " , function ( name )
if name == " EXPERIMENTAL_CVAR_WARNING " then
StaticPopup_Hide ( name ) ;
end
end )
local EL = CreateFrame ( " Frame " ) ; --Event Listener
EL : Hide ( ) ;
function Narci : UpdateVignetteStrength ( )
local alpha = tonumber ( NarcissusDB.VignetteStrength ) or 0.5 ;
VIGNETTE_ALPHA = alpha ;
Narci_Vignette.VignetteLeft : SetAlpha ( alpha ) ;
Narci_Vignette.VignetteRight : SetAlpha ( alpha ) ;
Narci_Vignette.VignetteRightSmall : SetAlpha ( alpha ) ;
Narci_PlayerModelGuideFrame.VignetteRightSmall : SetAlpha ( alpha ) ;
end
--[[
local TakenOutFrames = {
[ 2 ] = AzeriteEmpoweredItemUI , --
[ 3 ] = ItemSocketingFrame , --
[ 4 ] = ArtifactFrame , --
}
local function TakeOutFromUIParent ( frame , frameStrata , state )
local effectiveScale = UIParent : GetEffectiveScale ( ) ;
frameStrata = frameStrata or " MEDIUM " ;
if frame then
if state then
frame : SetParent ( nil ) ;
frame : SetFrameStrata ( frameStrata ) ;
frame : SetScale ( effectiveScale ) ;
else
frame : SetScale ( 1 ) ;
frame : SetParent ( UIParent ) ;
frame : SetFrameStrata ( frameStrata ) ;
end
end
end
--]]
--take out frames from UIParent, so they will still be visible when UI is hidden
local function TakeOutFrames ( state )
local frameNames = {
" AzeriteEmpoweredItemUI " , " AzeriteEssenceUI " , " ItemSocketingFrame " ,
} ;
local frame ;
if state then
local scale = UIParent : GetEffectiveScale ( ) ;
for _ , frameName in pairs ( frameNames ) do
frame = _G [ frameName ] ;
if frame then
frame : SetParent ( nil ) ;
frame : SetScale ( scale ) ;
end
end
else
for _ , frameName in pairs ( frameNames ) do
frame = _G [ frameName ] ;
if frame then
frame : SetParent ( UIParent ) ;
frame : SetScale ( 1 ) ;
end
end
end
end
local DefaultTooltip ;
function Narci_ShowButtonTooltip ( self )
DefaultTooltip : Hide ( ) ;
DefaultTooltip : SetOwner ( self , " ANCHOR_NONE " ) ;
if not self.tooltipHeadline then
return
end
DefaultTooltip : SetText ( self.tooltipHeadline ) ;
if self.IsOn then
DefaultTooltip : AddLine ( self.tooltipLineClose , 1 , 1 , 1 , true ) ;
else
DefaultTooltip : AddLine ( self.tooltipLineOpen , 1 , 1 , 1 , true ) ;
end
if self.tooltipSpecial then
DefaultTooltip : AddLine ( " " ) ;
DefaultTooltip : AddLine ( self.tooltipSpecial , 0.25 , 0.78 , 0.92 , true ) ;
end
DefaultTooltip : SetAlpha ( 0 ) ;
NarciAPI_ShowDelayedTooltip ( " BOTTOM " , self , " TOP " , 0 , 2 ) ;
end
function Narci : HideButtonTooltip ( )
DefaultTooltip : Hide ( ) ;
--DefaultTooltip:SetFrameStrata("TOOLTIP");
end
--[[ LibEasing
--
-- Original Lua implementations
-- from 'EmmanuelOga'
-- https://github.com/EmmanuelOga/easing/
--
-- Adapted from
-- Tweener's easing functions (Penner's Easing Equations)
-- and http://code.google.com/p/tweener/ (jstweener javascript version)
--
Disclaimer for Robert Penner ' s Easing Equations license:
TERMS OF USE - EASING EQUATIONS
Open source under the BSD License .
Copyright © 2001 Robert Penner
All rights reserved .
Redistribution and use in source and binary forms , with or without modification , are permitted provided that the following conditions are met :
* Redistributions of source code must retain the above copyright notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright notice , this list of conditions and the following disclaimer in the documentation and / or other materials provided with the distribution .
* Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
] ]
local function linear ( t , b , e , d )
return ( e - b ) * t / d + b
end
local function outSine ( t , b , e , d )
return ( e - b ) * sin ( t / d * ( pi / 2 ) ) + b
end
local function inOutSine ( t , b , e , d )
return ( b - e ) / 2 * ( cos ( pi * t / d ) - 1 ) + b
end
--------------------------------
local UIPA = CreateFrame ( " Frame " ) ; --UIParentAlphaAnimation
UIPA : Hide ( )
UIPA.t = 0 ;
UIPA.totalTime = 0 ;
UIPA.frame = UIParent ;
UIPA : SetScript ( " OnShow " , function ( self )
self.startAlpha = self.frame : GetAlpha ( ) ;
end ) ;
UIPA : SetScript ( " OnUpdate " , function ( self , elapsed )
self.t = self.t + elapsed
self.totalTime = self.totalTime + elapsed ;
if self.t < 0.08 then --Limit update frequency to mitigate the impact on FPS
return ;
else
self.t = 0 ;
end
local alpha = linear ( self.totalTime , self.startAlpha , self.endAlpha , 0.5 ) ;
if self.totalTime >= 0.5 then
alpha = self.endAlpha ;
self : Hide ( ) ;
end
self.frame : SetAlpha ( alpha ) ;
end ) ;
UIPA : SetScript ( " OnHide " , function ( self )
self.t = 0 ;
self.totalTime = 0 ;
end ) ;
--------------------------------
-----------CVar Backup----------
--------------------------------
local ConsoleExec = ConsoleExec ;
local GetCVar = GetCVar ;
local SetCVar = SetCVar ;
ConsoleExec ( " pitchlimit 88 " ) ;
local CVarTemp = { } ;
function CVarTemp : BackUp ( )
self.ZoomLevel = GetCameraZoom ( ) ;
self.DynamicPitch = tonumber ( GetCVar ( " test_cameraDynamicPitch " ) ) ;
self.OverShoulder = GetCVar ( " test_cameraOverShoulder " ) ;
self.MusicVolume = GetCVar ( " Sound_MusicVolume " ) ;
self.CameraViewBlendStyle = GetCVar ( " cameraViewBlendStyle " ) ;
end
function CVarTemp : BackUpDynamicCam ( )
self.DynmicCamShoulderOffsetZoomUpperBound = DynamicCam.db . profile.shoulderOffsetZoom . lowerBound ; --New
DynamicCam.db . profile.shoulderOffsetZoom . lowerBound = 0 ;
end
function CVarTemp : RestoreDynamicCam ( )
DynamicCam.db . profile.shoulderOffsetZoom . lowerBound = self.DynmicCamShoulderOffsetZoomUpperBound ;
end
local function GetKeepActionCam ( )
return CVarTemp.isDynamicCamLoaded or Narci.keepActionCam
end
CVarTemp.OverShoulder = tonumber ( GetCVar ( " test_cameraOverShoulder " ) ) ;
CVarTemp.DynamicPitch = tonumber ( GetCVar ( " test_cameraDynamicPitch " ) ) ; --No CVar directly shows the current state of ActionCam. Check this CVar for the moment. 1~On 2~Off
CVarTemp.MusicVolume = tonumber ( GetCVar ( " Sound_MusicVolume " ) ) ;
CVarTemp.ZoomLevel = 2 ;
local ZoomFactor = { } ;
ZoomFactor.Time = 1.5 ; --1.5 outSine
--ZoomFactor.Amplifier = 0.65; --0.65
ZoomFactor.toSpeedBasic = 0.004 ; --yawmovespeed 180
ZoomFactor.fromSpeedBasic = 1.05 ; --yawmovespeed 180
ZoomFactor.toSpeed = 0.005 ; --yawmovespeed 180
ZoomFactor.fromSpeed = 1.0 ; --yawmovespeed 180 outSine 1.4
ZoomFactor.SpeedFactor = 180 / tonumber ( GetCVar ( " cameraYawMoveSpeed " ) or 180 ) ;
ZoomFactor.Goal = 2.5 ; --2.5 with dynamic pitch
local MogModeOffset = 0 ;
local ZoomValuebyRaceID = {
--[raceID] = {ZoomValue Bust, factor1, factor2, ZoomValue for XmogMode},
[ 0 ] = { [ 2 ] = { 2.1 , 0.361 , - 0.1654 , 4 } , } , --Default Value
[ 1 ] = { [ 2 ] = { 2.1 , 0.3283 , - 0.02 , 4 } , --1 Human √
[ 3 ] = { 2.0 , 0.38 , 0.0311 , 3.6 } } ,
[ 2 ] = { [ 2 ] = { 2.4 , 0.2667 , - 0.1233 , 5.2 } , --2 Orc √
[ 3 ] = { 2.1 , 0.3045 , - 0.0483 , 5 } } ,
[ 3 ] = { [ 2 ] = { 2.0 , 0.2667 , - 0.0267 , 3.6 } , --3 Dwarf √
[ 3 ] = { 1.8 , 0.3533 , - 0.02 , 3.6 } } ,
[ 4 ] = { [ 2 ] = { 2.1 , 0.30 , - 0.0404 , 5 } , --4 NE √
[ 3 ] = { 2.1 , 0.329 , 0.025 , 4.6 } } ,
[ 5 ] = { [ 2 ] = { 2.1 , 0.3537 , - 0.15 , 4.2 } , --5 UD √
[ 3 ] = { 2.0 , 0.3447 , 0.03 , 3.6 } } ,
[ 6 ] = { [ 2 ] = { 4.5 , 0.2027 , - 0.18 , 5.5 } , --6 Tauren Male √
[ 3 ] = { 3.0 , 0.2427 , - 0.1867 , 5.5 } } ,
[ 7 ] = { [ 2 ] = { 2.1 , 0.329 , 0.0517 , 3.2 } , --7 Gnome √
[ 3 ] = { 2.1 , 0.329 , - 0.012 , 3.1 } } ,
[ 8 ] = { [ 2 ] = { 2.1 , 0.2787 , 0.04 , 5.2 } , --8 Troll √
[ 3 ] = { 2.1 , 0.355 , - 0.1317 , 5 } } ,
[ 9 ] = { [ 2 ] = { 2.1 , 0.2787 , 0.04 , 4.2 } , --9 Goblin √
[ 3 ] = { 2.1 , 0.3144 , - 0.054 , 4 } } ,
[ 10 ] = { [ 2 ] = { 2.1 , 0.361 , - 0.1654 , 4 } , --10 BloodElf Male √
[ 3 ] = { 2.1 , 0.3177 , 0.0683 , 3.8 } } ,
[ 11 ] = { [ 2 ] = { 2.4 , 0.248 , - 0.02 , 5.5 } , --11 Goat Male √
[ 3 ] = { 2.1 , 0.3177 , 0 , 5 } } ,
[ 24 ] = { [ 2 ] = { 2.5 , 0.2233 , - 0.04 , 5.2 } , --24 Pandaren Male √
[ 3 ] = { 2.5 , 0.2433 , 0.04 , 5.2 } } ,
[ 27 ] = { [ 2 ] = { 2.1 , 0.3067 , - 0.02 , 5.2 } , --27 Nightborne √
[ 3 ] = { 2.1 , 0.3347 , - 0.0563 , 4.7 } } ,
[ 28 ] = { [ 2 ] = { 3.5 , 0.2027 , - 0.18 , 5.5 } , --28 Tauren Male √
[ 3 ] = { 2.3 , 0.2293 , 0.0067 , 5.5 } } ,
[ 29 ] = { [ 2 ] = { 2.1 , 0.3556 , - 0.1038 , 4.5 } , --24 VE √
[ 3 ] = { 2.1 , 0.3353 , - 0.02 , 3.8 } } ,
[ 31 ] = { [ 2 ] = { 2.3 , 0.2387 , - 0.04 , 5.5 } , --32 Zandalari √
[ 3 ] = { 2.1 , 0.2733 , - 0.1243 , 5.5 } } ,
[ 32 ] = { [ 2 ] = { 2.3 , 0.2387 , 0.04 , 5.2 } , --32 Kul'Tiran √
[ 3 ] = { 2.1 , 0.312 , - 0.02 , 4.7 } } ,
[ 35 ] = { [ 2 ] = { 2.1 , 0.31 , - 0.03 , 3.1 } , --35 Vulpera √
[ 3 ] = { 2.1 , 0.31 , - 0.03 , 3.1 } } ,
[ " Wolf " ] = { [ 2 ] = { 2.6 , 0.2266 , - 0.02 , 5 } , --22 Worgen Wolf form √
[ 3 ] = { 2.1 , 0.2613 , - 0.0133 , 4.7 } } ,
[ " Druid " ] = { [ 1 ] = { 3.71 , 0.2027 , - 0.02 , 5 } , --Cat
[ 5 ] = { 4.8 , 0.1707 , - 0.04 , 5 } , --Bear
[ 31 ] = { 4.61 , 0.1947 , - 0.02 , 5 } , --Moonkin
[ 4 ] = { 4.61 , 0.1307 , - 0.04 , 5 } , --Swim
[ 27 ] = { 3.61 , 0.1067 , - 0.02 , 5 } , --Fly Swift
[ 29 ] = { 3.61 , 0.1067 , - 0.02 , 5 } , --Fly
[ 3 ] = { 4.91 , 0.184 , - 0.02 , 5 } , --Travel Form
[ 36 ] = { 4.2 , 0.1707 , - 0.04 , 5 } , --Treant
[ 2 ] = { 5.4 , 0.1707 , - 0.04 , 5 } , --Tree of Life
} ,
[ " Mounted " ] = { [ 1 ] = { 8 , 1.2495 , - 4 , 5.5 } } ,
--1 Human 32 Kultiran
--2 Orc
--3 Dwarf
--4 Night Elf
--5 Undead
--6 Tauren
--7 Gnome
--8 Troll
--9 Goblin
--10 Blood Elf
--11 Draenei
} ;
local _ , _ , playerRaceID = UnitRace ( " player " )
local playerGenderID = UnitSex ( " player " )
local _ , _ , playerClassID = UnitClass ( " player " ) ;
local distanceIndex = 1 ;
local ZoomInValue = ZoomValuebyRaceID [ 0 ] [ 1 ] ;
local ZoomInValue_XmogMode = 3.8 ;
local Shoulder_Factor1 = ZoomValuebyRaceID [ 0 ] [ 2 ] ;
local Shoulder_Factor2 = ZoomValuebyRaceID [ 0 ] [ 3 ] ;
local function ReIndexRaceID ( raceID )
if raceID == 25 or raceID == 26 then --Pandaren A|H
raceID = 24 ;
elseif raceID == 30 then --Lightforged
raceID = 11 ;
elseif raceID == 36 then --Mag'har Orc
raceID = 2 ;
elseif raceID == 34 then --DarkIron
raceID = 3 ;
elseif raceID == 37 then --Mechagnome
raceID = 7 ;
end
return raceID
end
playerRaceID = ReIndexRaceID ( playerRaceID )
ReIndexRaceID = nil ;
for raceKey , data in pairs ( ZoomValuebyRaceID ) do
local id = tonumber ( raceKey ) ;
if id and id > 1 and id ~= playerRaceID then
ZoomValuebyRaceID [ raceKey ] = nil ;
end
end
function Narci : InitializeCameraFactors ( )
if NarcissusDB and not NarcissusDB.UseBustShot then
distanceIndex = 4 ;
else
distanceIndex = 1 ;
end
end
local function ModifyCameraForMounts ( )
if IsMounted ( ) then
local index = " Mounted " ;
ZoomInValue = ZoomValuebyRaceID [ index ] [ 1 ] [ 1 ] ;
Shoulder_Factor1 = ZoomValuebyRaceID [ index ] [ 1 ] [ 2 ] ;
Shoulder_Factor2 = ZoomValuebyRaceID [ index ] [ 1 ] [ 3 ] ;
else
local zoom = ZoomValuebyRaceID [ playerRaceID ] or ZoomValuebyRaceID [ 1 ] ;
ZoomInValue = zoom [ playerGenderID ] [ 1 ] ;
Shoulder_Factor1 = zoom [ playerGenderID ] [ 2 ] ;
Shoulder_Factor2 = zoom [ playerGenderID ] [ 3 ] ;
ZoomInValue_XmogMode = zoom [ playerGenderID ] [ 4 ] ;
end
end
local function ModifyCameraForShapeshifter ( )
if IsMounted ( ) then
local index = " Mounted " ;
ZoomInValue = ZoomValuebyRaceID [ index ] [ 1 ] [ 1 ] ;
Shoulder_Factor1 = ZoomValuebyRaceID [ index ] [ 1 ] [ 2 ] ;
Shoulder_Factor2 = ZoomValuebyRaceID [ index ] [ 1 ] [ 3 ] ;
return ;
end
if playerRaceID ~= 22 and playerClassID ~= 11 then --22 Worgen 11 druid
local zoom = ZoomValuebyRaceID [ playerRaceID ] or ZoomValuebyRaceID [ 1 ] ;
ZoomInValue = zoom [ playerGenderID ] [ distanceIndex ] ;
Shoulder_Factor1 = zoom [ playerGenderID ] [ 2 ] ;
Shoulder_Factor2 = zoom [ playerGenderID ] [ 3 ] ;
ZoomInValue_XmogMode = zoom [ playerGenderID ] [ 4 ] ;
return ;
end
local raceID_shouldUse = 1 ;
if playerClassID ~= 11 then
--Not Druid
local _ , inAlternateForm = GetAlternateFormInfo ( ) ;
if not inAlternateForm then --Is curren in wolf form
raceID_shouldUse = " Wolf " ;
else
raceID_shouldUse = 1 ;
end
ZoomInValue = ZoomValuebyRaceID [ raceID_shouldUse ] [ playerGenderID ] [ distanceIndex ] ;
Shoulder_Factor1 = ZoomValuebyRaceID [ raceID_shouldUse ] [ playerGenderID ] [ 2 ] ;
Shoulder_Factor2 = ZoomValuebyRaceID [ raceID_shouldUse ] [ playerGenderID ] [ 3 ] ;
ZoomInValue_XmogMode = ZoomValuebyRaceID [ raceID_shouldUse ] [ playerGenderID ] [ 4 ] ;
return ;
else
--Druid
raceID_shouldUse = " Druid " ;
EL : RegisterEvent ( " UPDATE_SHAPESHIFT_FORM " ) ;
local formID = GetShapeshiftFormID ( ) ;
if ( not formID ) or ( not ZoomValuebyRaceID [ raceID_shouldUse ] [ formID ] ) then
if playerRaceID == 22 then
local _ , inAlternateForm = GetAlternateFormInfo ( ) ;
if not inAlternateForm then --Is curren in wolf form
raceID_shouldUse = " Wolf " ;
else
raceID_shouldUse = 1 ;
end
else
raceID_shouldUse = playerRaceID ;
end
formID = playerGenderID ;
elseif formID == 31 then
local _ , GlyphID = GetCurrentGlyphNameForSpell ( 24858 ) ; --Moonkin form with Glyph of Stars use regular configuration
if GlyphID and GlyphID == 114301 then
local zoom = ZoomValuebyRaceID [ playerRaceID ] or ZoomValuebyRaceID [ 1 ] ;
ZoomInValue = zoom [ playerGenderID ] [ distanceIndex ] ;
Shoulder_Factor1 = zoom [ playerGenderID ] [ 2 ] ;
Shoulder_Factor2 = zoom [ playerGenderID ] [ 3 ] ;
ZoomInValue_XmogMode = zoom [ playerGenderID ] [ 4 ] ;
return ;
end
end
ZoomInValue = ZoomValuebyRaceID [ raceID_shouldUse ] [ formID ] [ distanceIndex ] ;
Shoulder_Factor1 = ZoomValuebyRaceID [ raceID_shouldUse ] [ formID ] [ 2 ] ;
Shoulder_Factor2 = ZoomValuebyRaceID [ raceID_shouldUse ] [ formID ] [ 3 ] ;
ZoomInValue_XmogMode = ZoomValuebyRaceID [ raceID_shouldUse ] [ formID ] [ 4 ] ;
end
end
local SmoothShoulder = CreateFrame ( " Frame " ) ;
SmoothShoulder.t = 0 ;
SmoothShoulder.duration = 1 ;
SmoothShoulder : Hide ( ) ;
SmoothShoulder : SetScript ( " OnShow " , function ( self )
self.fromPoint = GetCVar ( " test_cameraOverShoulder " ) ;
end ) ;
SmoothShoulder : SetScript ( " OnUpdate " , function ( self , elapsed )
self.t = self.t + elapsed ;
local value = outSine ( self.t , self.fromPoint , self.toPoint , self.duration ) ;
if self.t >= self.duration then
value = self.toPoint ;
self : Hide ( ) ;
end
SetCVar ( " test_cameraOverShoulder " , value ) ;
end ) ;
SmoothShoulder : SetScript ( " OnHide " , function ( self )
self.t = 0 ;
end ) ;
local function SmoothShoulderCVar ( toPoint , clampToZero )
if not toPoint then
return
end
if clampToZero then
if toPoint < 0 then
toPoint = 0 ;
end
end
SmoothShoulder.t = 0 ;
SmoothShoulder.toPoint = toPoint ;
SmoothShoulder : Show ( ) ;
end
local UpdateShoulderCVar = { } ;
function UpdateShoulderCVar : Start ( increment , clampToZero )
if ( not self.pauseUpdate ) then
self.zoom = GetCameraZoom ( ) ;
self.pauseUpdate = true ;
After ( 0.1 , function ( ) -- Execute after 0.1s
self.pauseUpdate = nil ;
SmoothShoulderCVar ( self.zoom * Shoulder_Factor1 + Shoulder_Factor2 + MogModeOffset , clampToZero ) ;
end )
end
self.zoom = self.zoom + increment ;
end
local duration_Lock = 1.5 ;
local duration_Translation = 0.8 ;
function Narci_LeftLineAnimFrame_OnUpdate ( self , elapsed )
local toX = self.toX ;
local t = self.TimeSinceLastUpdate + elapsed ;
self.TimeSinceLastUpdate = t ;
local offsetX = outSine ( t , toX - 120 , toX , duration_Translation ) ; --outSine
if t >= duration_Translation then
offsetX = toX ;
self : Hide ( ) ;
end
if not self.frame then
self.frame = self : GetParent ( ) ;
end
self.frame : SetPoint ( self.anchorPoint , offsetX , 0 ) ;
end
function Narci_RightLineAnimFrame_OnUpdate ( self , elapsed )
local toX = self.toX ;
local t = self.TimeSinceLastUpdate + elapsed ;
self.TimeSinceLastUpdate = t ;
local offsetX = outSine ( t , self.fromX , toX , duration_Translation ) ;
if t >= duration_Translation then
offsetX = toX ;
self : Hide ( ) ;
end
if not self.frame then
self.frame = self : GetParent ( ) ;
end
self.frame : SetPoint ( self.anchorPoint , offsetX , 0 ) ;
end
--Views
local ViewProfile = {
isEnabled = true ,
} ;
function ViewProfile : Disable ( )
self.isEnabled = false ;
--print("Dynamic Cam Enabled")
end
function ViewProfile : SaveView ( index )
if self.isEnabled then
SaveView ( index ) ;
end
end
function ViewProfile : ResetView ( index )
if self.isEnabled then
ResetView ( index ) ;
end
end
---Camera
--[[
hooksecurefunc ( " CameraZoomIn " , function ( increment )
if IS_OPENED and ( xmogMode ~= 1 ) then
UpdateShoulderCVar : Start ( - increment ) ;
end
end )
hooksecurefunc ( " CameraZoomOut " , function ( increment )
if IS_OPENED and ( xmogMode ~= 1 ) then
UpdateShoulderCVar : Start ( increment ) ;
end
end )
--]]
local CameraMover = { } ;
Narci.CameraMover = CameraMover ;
function CameraMover : ZoomIn ( toPoint )
local goal = toPoint or ZoomFactor.Goal ;
ZoomFactor.Current = GetCameraZoom ( ) ;
if ZoomFactor.Current >= goal then
CameraZoomIn ( ZoomFactor.Current - goal ) ;
else
CameraZoomOut ( - ZoomFactor.Current + goal ) ;
end
end
function CameraMover : OnCameraChanged ( )
if not self.pauseUpdate then
self.pauseUpdate = true ;
After ( 0.05 , function ( )
self : ZoomIn ( ZoomInValue ) ;
self.pauseUpdate = nil ;
end ) ;
end
end
function CameraMover : SetBlend ( enable )
local divisor ;
if enable then
--Smooth
duration_Lock = 1.5 ;
duration_Translation = 0.8 ;
divisor = 20 ;
else
--Instant
duration_Lock = 0.4 ;
duration_Translation = 0.4 ;
divisor = 80 ;
end
for k , slot in pairs ( statTable ) do
local delay = ( slot : GetID ( ) ) / divisor ;
if slot.animIn then
slot.animIn . A2 : SetStartDelay ( delay ) ;
end
end
for k , slot in pairs ( statTable_Short ) do
local delay = ( slot : GetID ( ) ) / divisor ;
slot.animIn . A2 : SetStartDelay ( delay ) ;
end
RadarChart.animIn . A2 : SetStartDelay ( 9 / divisor ) ;
self.blend = enable ;
end
CameraMover.smoothYaw = NarciAPI_CreateAnimationFrame ( 1.5 ) ;
CameraMover.smoothYaw . MoveView = MoveViewRightStart ;
CameraMover.smoothYaw : SetScript ( " OnUpdate " , function ( frame , elapsed )
frame.total = frame.total + elapsed ;
local factor = ZoomFactor ;
local speed = inOutSine ( frame.total , factor.fromSpeed , factor.toSpeed , 1.5 ) ; --inOutSine
frame.MoveView ( speed ) ;
if frame.total >= 1.5 then
if not IsPlayerMoving ( ) then
frame.MoveView ( factor.toSpeed ) ;
else
MoveViewRightStop ( ) ;
end
frame : Hide ( ) ;
end
end ) ;
CameraMover.smoothPitch = NarciAPI_CreateAnimationFrame ( 1.5 ) ;
CameraMover.smoothPitch : SetScript ( " OnUpdate " , function ( frame , elapsed )
frame.total = frame.total + elapsed
--local x = frame.total;
--local EndDistance = ZoomFactor.Goal;
local PL = tostring ( outSine ( frame.total , 88 , 1 , frame.duration ) ) ; --outSine
ConsoleExec ( " pitchlimit " .. PL )
if frame.total >= frame.duration then
ConsoleExec ( " pitchlimit 1 " ) ;
After ( 0 , function ( )
ConsoleExec ( " pitchlimit 88 " ) ;
end )
frame : Hide ( ) ;
end
end ) ;
function CameraMover : InstantZoomIn ( )
SetCVar ( " cameraViewBlendStyle " , 2 ) ;
SetView ( 4 ) ;
ConsoleExec ( " pitchlimit 1 " ) ;
After ( 0 , function ( )
ConsoleExec ( " pitchlimit 88 " ) ;
end )
local zoom = ZoomInValue or GetCameraZoom ( ) ;
local shoulderOffset = zoom * Shoulder_Factor1 + Shoulder_Factor2 + MogModeOffset ;
SetCVar ( " test_cameraOverShoulder " , shoulderOffset ) ; --CameraZoomIn(0.0) --Smooth
self : ZoomIn ( ZoomInValue ) ;
self : ShowFrame ( ) ;
SetUIVisibility ( false ) ;
if not IsPlayerMoving ( ) and NarcissusDB.CameraOrbit then
MoveViewRightStart ( ZoomFactor.toSpeed ) ;
end
end
function CameraMover : HideUI ( )
if UIParent : IsShown ( ) then
UIPA.endAlpha = 0 ;
UIPA : Show ( ) ;
end
After ( 0.5 , function ( )
SetUIVisibility ( false ) ; --Same as pressing Alt + Z
After ( 0.3 , function ( )
UIParent : SetAlpha ( 1 ) ;
end )
end )
end
function CameraMover : Enter ( )
SetCVar ( " test_cameraDynamicPitch " , 1 ) ;
if self.blend then
if NarcissusDB.CameraOrbit and not IsPlayerMoving ( ) then
if NarcissusDB.CameraOrbit then
self.smoothYaw : Show ( ) ;
end
SetView ( 2 ) ;
end
if not IsFlying ( " player " ) then
self.smoothPitch : Show ( ) ;
end
After ( 0.1 , function ( )
self : ZoomIn ( ZoomInValue ) ;
After ( 0.7 , function ( )
self : ShowFrame ( ) ;
end )
end )
self : HideUI ( ) ;
else
if not self.hasInitialized then
if NarcissusDB.CameraOrbit then
self.smoothYaw : Show ( ) ;
end
SetView ( 2 ) ;
self.smoothPitch : Show ( ) ;
After ( 0.1 , function ( )
self : ZoomIn ( ZoomInValue ) ;
After ( 0.7 , function ( )
self : ShowFrame ( ) ;
end )
end )
After ( 1 , function ( )
if not IsMounted ( ) then
self.hasInitialized = true ;
SaveView ( 1 ) ;
end
end )
self : HideUI ( ) ;
else
self : InstantZoomIn ( ) ;
end
end
end
function CameraMover : Pitch ( )
self.smoothPitch : Show ( ) ;
end
------------------------------
------------------------------
local function ExitFunc ( )
IS_OPENED = false ;
xmogMode = 0 ;
MogModeOffset = 0 ;
NarciPlayerModelFrame1.xmogMode = 0 ;
EL : Hide ( ) ;
MoveViewRightStop ( ) ;
if not GetKeepActionCam ( ) then --(not CVarTemp.isDynamicCamLoaded and CVarTemp.DynamicPitch == 0) or not Narci.keepActionCam
SetCVar ( " test_cameraDynamicPitch " , 0 ) ; --Note: "test_cameraDynamicPitch" may cause camera to jitter while reseting the player's view
SmoothShoulderCVar ( 0 ) ;
After ( 1 , function ( )
ConsoleExec ( " actioncam off " ) ;
MoveViewRightStop ( ) ;
end )
else
--Restore the acioncam state
SmoothShoulderCVar ( CVarTemp.OverShoulder ) ;
SetCVar ( " test_cameraDynamicPitch " , CVarTemp.DynamicPitch ) ;
After ( 1 , function ( )
MoveViewRightStop ( ) ;
end )
end
ConsoleExec ( " pitchlimit 88 " ) ;
FadeFrame ( Narci_Vignette , 0.5 , 0 ) ;
if Narci_Attribute : IsVisible ( ) then
Narci_Attribute.animOut : Play ( ) ;
end
UIParent : SetAlpha ( 0 ) ;
After ( 0.1 , function ( )
UIPA.startAlpha = 0 ;
UIPA.endAlpha = 1 ;
UIPA : Show ( ) ;
SetUIVisibility ( true ) ;
--UIFrameFadeIn(UIParent, 0.5, 0, 1); --cause frame rate drop
Minimap : Show ( ) ;
local CameraFollowStyle = GetCVar ( " cameraSmoothStyle " ) ;
if CameraFollowStyle == " 0 " and ViewProfile.isEnabled then --workaround for auto-following
SetView ( 5 ) ;
else
SetView ( 2 ) ;
CameraMover : ZoomIn ( CVarTemp.ZoomLevel ) ;
end
SetCVar ( " cameraViewBlendStyle " , CVarTemp.CameraViewBlendStyle ) ;
end ) ;
Narci.isActive = false ;
Narci.isAFK = false ;
DefaultTooltip : Hide ( ) ;
MsgAlertContainer : Hide ( ) ;
UIErrorsFrame : Clear ( ) ;
end
--[[
local function SetDate ( )
local CalendarTime = C_Calendar.GetDate ( ) ;
local hour = CalendarTime.hour ;
local minute = CalendarTime.minute ;
if minute < 10 then
minute = " 0 " .. tostring ( minute )
end
Narci_Vignette.Time : SetText ( hour .. " : " .. minute )
local zoneText = GetMinimapZoneText ( )
Narci_Vignette.Location : SetText ( zoneText )
end
--]]
function Narci : EmergencyStop ( )
print ( " Camera has been reset. " ) ;
UIParent : SetAlpha ( 1 ) ;
MoveViewRightStop ( ) ;
MoveViewLeftStop ( ) ;
ViewProfile : ResetView ( 5 ) ;
ConsoleExec ( " pitchlimit 88 " ) ;
CVarTemp.OverShoulder = 0 ;
SetCVar ( " test_cameraOverShoulder " , 0 ) ;
SetCVar ( " cameraViewBlendStyle " , 1 ) ;
ConsoleExec ( " actioncam off " ) ;
Narci_ModelContainer : Hide ( ) ;
Narci_ModelSettings : Hide ( ) ;
Narci_Character : Hide ( ) ;
Narci_Attribute : Hide ( ) ;
Narci_Vignette : Hide ( ) ;
IS_OPENED = false ;
xmogMode = 0 ;
MogModeOffset = 0 ;
NarciPlayerModelFrame1.xmogMode = 0 ;
EL : Hide ( ) ;
end
-- Derivative from [[LibDBIcon-1.0]]
local MapShapeUtil = { } ;
MapShapeUtil.allShapes = {
[ " ROUND " ] = { true , true , true , true } ,
[ " SQUARE " ] = { false , false , false , false } ,
[ " CORNER-TOPLEFT " ] = { false , false , false , true } ,
[ " CORNER-TOPRIGHT " ] = { false , false , true , false } ,
[ " CORNER-BOTTOMLEFT " ] = { false , true , false , false } ,
[ " CORNER-BOTTOMRIGHT " ] = { true , false , false , false } ,
[ " SIDE-LEFT " ] = { false , true , false , true } ,
[ " SIDE-RIGHT " ] = { true , false , true , false } ,
[ " SIDE-TOP " ] = { false , false , true , true } ,
[ " SIDE-BOTTOM " ] = { true , true , false , false } ,
[ " TRICORNER-TOPLEFT " ] = { false , true , true , true } ,
[ " TRICORNER-TOPRIGHT " ] = { true , false , true , true } ,
[ " TRICORNER-BOTTOMLEFT " ] = { true , true , false , true } ,
[ " TRICORNER-BOTTOMRIGHT " ] = { true , true , true , false } ,
} ;
MapShapeUtil.cornerRadius = 10 ; --Minimap Button Offset
function MapShapeUtil : IsAnchoredToMinimap ( x , y )
local shape = GetMinimapShape and GetMinimapShape ( ) or " ROUND " ;
if shape == " SQUARE " then
local x1 , x2 = Minimap : GetLeft ( ) , Minimap : GetRight ( ) ;
local y1 , y2 = Minimap : GetBottom ( ) , Minimap : GetTop ( ) ;
local offset = self.cornerRadius + 2 ;
x1 = x1 - offset ;
x2 = x2 + offset ;
y1 = y1 - offset ;
y2 = y2 + offset ;
return ( x >= x1 and x <= x2 and y >= y1 and y <= y2 )
else
local r = Minimap : GetWidth ( ) / 2 + self.cornerRadius + 2 ;
local x0 , y0 = Minimap : GetCenter ( ) ;
local d = math.sqrt ( ( x - x0 ) ^ 2 + ( y - y0 ) ^ 2 ) ;
return d <= r
end
end
local function MinimapButton_SetAngle ( radian )
local x , y , q = cos ( radian ) , sin ( radian ) , 1 ;
if x < 0 then q = q + 1 end
if y > 0 then q = q + 2 end
local minimapShape = GetMinimapShape and GetMinimapShape ( ) or " ROUND " ;
local quadTable = MapShapeUtil.allShapes [ minimapShape ] ;
local w = ( Minimap : GetWidth ( ) / 2 ) + MapShapeUtil.cornerRadius ;
local h = ( Minimap : GetHeight ( ) / 2 ) + MapShapeUtil.cornerRadius ;
if quadTable [ q ] then
x , y = x * w , y * h ;
else
local diagRadiusW = math.sqrt ( 2 * ( w ) ^ 2 ) - MapShapeUtil.cornerRadius ;
local diagRadiusH = math.sqrt ( 2 * ( h ) ^ 2 ) - MapShapeUtil.cornerRadius ;
x = math.max ( - w , math.min ( x * diagRadiusW , w ) ) ;
y = math.max ( - h , math.min ( y * diagRadiusH , h ) ) ;
end
MiniButton : SetPoint ( " CENTER " , Minimap , " CENTER " , x , y ) ;
end
NarciMinimapButtonMixin = { } ;
function NarciMinimapButtonMixin : CreatePanel ( )
local Panel = self.Panel ;
local button ;
local buttons = { } ;
local LOCALIZED_NAMES = { L [ " Photo Mode " ] , DRESSUP_FRAME , L [ " Turntable " ] , ACHIEVEMENT_BUTTON } ; -- CHARACTER_BUTTON, "Character Info" "Dressing Room" "Achievements"
local frameNames = { } ;
frameNames [ 4 ] = " Narci_Achievement " ;
local func = {
Narci_OpenGroupPhoto ,
function ( )
Narci_ShowDressingRoom ( ) ;
end ,
function ( )
NarciOutfitShowcase : Open ( ) ;
end ,
function ( )
if not Narci_AchievementFrame then
Narci.LoadAchievementPanel ( ) ;
return
else
Narci_AchievementFrame : SetShown ( not Narci_AchievementFrame : IsShown ( ) ) ;
end
end
} ;
local numButtons = # LOCALIZED_NAMES ;
local BUTTON_HEIGHT = 24 ;
local offsetY = BUTTON_HEIGHT * ( numButtons - 1 ) / 2 ;
local middleHeight = 48 + ( numButtons - 4 ) * BUTTON_HEIGHT ;
local button1OffsetY = offsetY - middleHeight / 2 + BUTTON_HEIGHT / 2
local buttonFrameLevel = Panel : GetFrameLevel ( ) + 1 ;
local ClipFrame = Panel.ClipFrame ;
ClipFrame : SetFrameLevel ( buttonFrameLevel + 1 ) ;
ClipFrame : ClearAllPoints ( ) ;
ClipFrame : SetPoint ( " CENTER " , Panel.Middle , " CENTER " , 0 , offsetY ) ;
ClipFrame.Highlight : SetTexture ( " Interface/AddOns/Narcissus/Art/Minimap/Panel " , nil , nil , " TRILINEAR " ) ;
ClipFrame.PushedHighlight : SetTexture ( " Interface/AddOns/Narcissus/Art/Minimap/Panel " , nil , nil , " TRILINEAR " ) ;
local animHighlight = NarciAPI_CreateAnimationFrame ( 0.25 ) ;
animHighlight.object = ClipFrame ;
Panel : SetHeight ( numButtons * BUTTON_HEIGHT + self : GetHeight ( ) ) ;
Panel : SetScript ( " OnLeave " , function ( frame )
if not frame : IsMouseOver ( ) then
self : ShowPopup ( false ) ;
end
end )
Panel : SetScript ( " OnHide " , function ( frame )
frame : SetAlpha ( 0 ) ;
frame : Hide ( ) ;
animHighlight : Hide ( ) ;
ClipFrame : SetPoint ( " CENTER " , Panel.Middle , " CENTER " , 0 , offsetY ) ;
ClipFrame : Hide ( ) ;
self : UnregisterEvent ( " GLOBAL_MOUSE_DOWN " ) ;
end )
-----------------------------------------------------------
animHighlight : SetScript ( " OnUpdate " , function ( frame , elapsed )
frame.total = frame.total + elapsed ;
local y = inOutSine ( frame.total , frame.fromY , frame.toY , frame.duration ) ;
if frame.total >= frame.duration then
y = frame.toY ;
frame : Hide ( ) ;
end
frame.object : SetPoint ( " CENTER " , Panel.Middle , " CENTER " , 0 , y ) ;
end ) ;
self.lastIndex = 1 ;
local function UpdateHighlight ( buttonIndex )
ClipFrame : Show ( ) ;
if animHighlight : IsShown ( ) then
local newDirection ;
if buttonIndex > self.lastIndex then
newDirection = - 1 ;
else
newDirection = 1 ;
end
if newDirection ~= self.lastDirection then
animHighlight : Hide ( ) ;
local _ ;
_ , _ , _ , _ , animHighlight.fromY = ClipFrame : GetPoint ( ) ;
else
--animHighlight.total = animHighlight.total / 2;
end
else
local _ ;
_ , _ , _ , _ , animHighlight.fromY = ClipFrame : GetPoint ( ) ;
end
animHighlight.toY = offsetY - ( buttonIndex - 1 ) * 24 ;
animHighlight : Show ( ) ;
end
function self : IsInBound ( )
for i = 1 , numButtons do
if buttons [ i ] : IsMouseOver ( ) then
return true
end
end
return false
end
-----------------------------------------------------------
local panelEntrance = NarciAPI_CreateAnimationFrame ( 0.25 ) ;
self.panelEntrance = panelEntrance ;
panelEntrance.object = Panel.Middle ;
Panel.Middle : SetHeight ( middleHeight ) ;
panelEntrance.toHeight = middleHeight ;
panelEntrance : SetScript ( " OnUpdate " , function ( frame , elapsed )
frame.total = frame.total + elapsed ;
local height = outSine ( frame.total , frame.fromHeight , frame.toHeight , frame.duration ) ;
local buttonDistance = outSine ( frame.total , 12 , 0 , frame.duration ) ;
local alpha = math.min ( Panel : GetAlpha ( ) + elapsed / frame.duration , 1 ) ;
if frame.total >= frame.duration then
height = frame.toHeight ;
buttonDistance = 0 ;
alpha = 1 ;
frame : Hide ( ) ;
end
frame.object : SetHeight ( height ) ;
for i = 1 , numButtons do
if i == 1 then
buttons [ i ] : SetPoint ( " TOP " , Panel.Middle , " TOP " , 0 , button1OffsetY + buttonDistance ) ;
else
buttons [ i ] : SetPoint ( " TOP " , buttons [ i - 1 ] , " BOTTOM " , 0 , buttonDistance * math.sqrt ( i ) ) ;
end
end
Panel : SetAlpha ( alpha ) ;
end )
Panel : SetScript ( " OnShow " , function ( )
panelEntrance.total = 0 ;
if panelEntrance : IsShown ( ) then
panelEntrance.fromHeight = Panel : GetHeight ( ) ;
else
panelEntrance.fromHeight = 1 ;
panelEntrance : Show ( ) ;
end
end )
-----------------------------------------------------------
local function OnEnter ( button )
if not ClipFrame : IsShown ( ) then
FadeFrame ( ClipFrame , 0.2 , 1 ) ;
end
if button : IsEnabled ( ) then
UpdateHighlight ( button.index ) ;
end
SetCursor ( " Interface/CURSOR/Item.blp " ) ;
end
local function OnLeave ( button )
if not self : IsInBound ( ) then
FadeFrame ( ClipFrame , 0.2 , 0 ) ;
ResetCursor ( ) ;
end
if not Panel : IsMouseOver ( ) then
self : ShowPopup ( false ) ;
end
end
local function OnMouseDown ( )
ClipFrame.PushedHighlight : Show ( ) ;
end
local function OnMouseUp ( )
ClipFrame.PushedHighlight : Hide ( ) ;
end
for i = 1 , numButtons do
local frameName = frameNames [ i ] ;
if frameName then
frameName = frameName .. " _MinimapButton " ;
end
button = CreateFrame ( " Button " , frameName , Panel , " NarciMinimapPanelButtonTemplate " ) ;
tinsert ( buttons , button ) ;
button : SetFrameLevel ( buttonFrameLevel ) ;
button.BlackText : SetText ( LOCALIZED_NAMES [ i ] ) ;
button.WhiteText : SetText ( LOCALIZED_NAMES [ i ] ) ;
button.BlackText : SetParent ( ClipFrame ) ;
button.index = i ;
button.func = func [ i ] ;
if i == 1 then
button : SetPoint ( " TOP " , Panel.Middle , " TOP " , 0 , button1OffsetY ) ;
else
button : SetPoint ( " TOP " , buttons [ i - 1 ] , " BOTTOM " , 0 , 0 ) ;
--button:SetPoint("TOP", Panel.Middle, "TOP", 0, offsetY - middleHeight/2 + BUTTON_HEIGHT/2 - BUTTON_HEIGHT * (i - 1) );
end
button : SetScript ( " OnEnter " , OnEnter ) ;
button : SetScript ( " OnLeave " , OnLeave ) ;
button : SetScript ( " OnMouseDown " , OnMouseDown ) ;
button : SetScript ( " OnMouseUp " , OnMouseUp ) ;
button : SetScript ( " OnClick " , function ( frame , key )
self : ShowPopup ( false ) ;
if key == " LeftButton " and frame.func then
frame.func ( ) ;
end
end ) ;
if not func [ i ] then
button : Disable ( ) ;
end
end
self.buttons = buttons ;
self.CreatePanel = nil ;
end
function NarciMinimapButtonMixin : OnLoad ( )
MiniButton = self ;
self : RegisterForClicks ( " LeftButtonUp " , " RightButtonUp " , " MiddleButtonUp " ) ;
self : RegisterForDrag ( " LeftButton " ) ;
self.endAlpha = 1 ;
self : CreatePanel ( ) ;
--Create Popup Delay
local delay = NarciAPI_CreateAnimationFrame ( 0.35 ) ; --Mouseover Delay
self.onEnterDelay = delay ;
delay : SetScript ( " OnUpdate " , function ( frame , elapsed )
frame.total = frame.total + elapsed ;
if frame.total >= frame.duration then
if self : IsMouseOver ( ) then
self : ShowPopup ( true ) ;
end
frame : Hide ( ) ;
end
end )
local tooltip = self.TooltipFrame ;
tooltip.Left : SetVertexColor ( 0.686 , 0.914 , 0.996 ) ;
tooltip.Middle : SetVertexColor ( 0.686 , 0.914 , 0.996 ) ;
tooltip.Right : SetVertexColor ( 0.686 , 0.914 , 0.996 ) ;
--Position Update Frame
local f = CreateFrame ( " Frame " ) ;
self.PositionUpdator = f ;
f : Hide ( ) ;
f.t = 0 ;
f : SetScript ( " OnUpdate " , function ( )
local radian ;
local px , py = GetCursorPosition ( ) ;
px , py = px / f.uiScale , py / f.uiScale ;
radian = math.atan2 ( py - f.mapY , px - f.mapX ) ;
MinimapButton_SetAngle ( radian ) ;
NarcissusDB.MinimapButton . Position = radian ;
end )
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciMinimapButtonMixin : InitPosition ( )
if NarcissusDB.AnchorToMinimap then
self : ClearAllPoints ( ) ;
local radian = NarcissusDB.MinimapButton . Position ;
MinimapButton_SetAngle ( radian ) ;
end
end
function NarciMinimapButtonMixin : EnableButton ( )
NarcissusDB.ShowMinimapButton = true ;
self : Show ( ) ;
self : PlayBling ( ) ;
end
function NarciMinimapButtonMixin : ResetPosition ( )
NarcissusDB.MinimapButton . Position = ( - 0.83 * math.pi ) ;
NarcissusDB.AnchorToMinimap = true ;
self : InitPosition ( ) ;
self : EnableButton ( ) ;
end
function NarciMinimapButtonMixin : IsAnchoredToMinimap ( )
local x , y = self : GetCenter ( ) ;
return MapShapeUtil : IsAnchoredToMinimap ( x , y ) ;
end
function NarciMinimapButtonMixin : SetTooltipText ( text )
local tooltip = self.TooltipFrame ;
tooltip.Description : SetText ( text ) ;
local textWidth = tooltip.Description : GetWidth ( ) ;
tooltip : SetWidth ( max ( 32 , textWidth + 8 ) ) ;
tooltip : ClearAllPoints ( ) ;
local scale = UIParent : GetEffectiveScale ( ) ;
local x , y = self : GetCenter ( ) ;
y = y + 36 ;
tooltip : SetPoint ( " CENTER " , UIParent , " BOTTOMLEFT " , x * scale , y * scale ) ;
tooltip : Show ( ) ;
end
function NarciMinimapButtonMixin : StartRepositioning ( )
self : ShowPopup ( false ) ;
self : StopMovingOrSizing ( ) ;
self.PositionUpdator : Hide ( ) ;
self.TooltipFrame : Hide ( ) ;
self : ClearAllPoints ( ) ;
if not IsShiftKeyDown ( ) and self : IsAnchoredToMinimap ( ) then
self : SetTooltipText ( " Hold Shift for free move " ) ;
self.PositionUpdator . mapX , self.PositionUpdator . mapY = Minimap : GetCenter ( ) ;
self.PositionUpdator . uiScale = Minimap : GetEffectiveScale ( ) ;
self.PositionUpdator : Show ( ) ;
NarcissusDB.AnchorToMinimap = true ;
else
self : StartMoving ( ) ;
NarcissusDB.AnchorToMinimap = false ;
end
self : RegisterEvent ( " MODIFIER_STATE_CHANGED " ) ;
end
function NarciMinimapButtonMixin : OnDragStart ( )
self : StartRepositioning ( ) ;
end
function NarciMinimapButtonMixin : OnDragStop ( )
self.PositionUpdator : Hide ( ) ;
self : StopMovingOrSizing ( ) ;
self : SetUserPlaced ( true ) ;
if self : IsMouseOver ( ) then
self : OnEnter ( ) ;
end
self : UnregisterEvent ( " MODIFIER_STATE_CHANGED " ) ;
self.TooltipFrame : Hide ( ) ;
end
function NarciMinimapButtonMixin : PostClick ( button , down )
if button == " MiddleButton " then
Narci : EmergencyStop ( ) ;
end
end
function NarciMinimapButtonMixin : OnMouseDown ( )
self.onEnterDelay : Hide ( ) ;
end
function NarciMinimapButtonMixin : OnClick ( button , down )
self.onEnterDelay : Hide ( ) ;
GameTooltip : Hide ( ) ;
if button == " MiddleButton " then
return ;
elseif button == " RightButton " then
if IsShiftKeyDown ( ) then
NarcissusDB.ShowMinimapButton = false ;
print ( " Minimap button has been hidden. You may type /Narci minimap to re-enable it. " ) ;
self : Hide ( ) ;
else
if self.showPanelOnMouseOver then
Narci_OpenGroupPhoto ( ) ;
GameTooltip : Hide ( ) ;
self : Disable ( ) ;
After ( duration_Lock , function ( )
self : Enable ( )
end )
else
self : ShowPopup ( true ) ;
end
end
return ;
end
--"LeftButton"
if IsShiftKeyDown ( ) then
Narci_ShowDressingRoom ( ) ;
return ;
end
self : Disable ( ) ;
Narci_Open ( ) ;
After ( duration_Lock , function ( )
self : Enable ( ) ;
end )
end
function NarciMinimapButtonMixin : SetBackground ( index )
local useCovenantColor = false ;
local prefix = " Interface/AddOns/Narcissus/Art/Minimap/LOGO- " ;
local tex ;
local customStyleID = NarcissusDB.MinimapIconStyle ;
if not customStyleID then
if IsAddOnLoaded ( " AzeriteUI " ) then
customStyleID = 2 ;
elseif IsAddOnLoaded ( " SexyMap " ) then
customStyleID = 3 ;
else
customStyleID = 1 ;
end
--NarcissusDB.MinimapIconStyle = customStyleID;
end
if customStyleID == 2 then
tex = prefix .. " Thick " ; --AzeriteUI
elseif customStyleID == 3 then
tex = prefix .. " Hollow " ; --SexyMap
else
useCovenantColor = true ;
end
if useCovenantColor then
local id = index or C_Covenants.GetActiveCovenantID ( ) ;
if id == 2 then
tex = prefix .. " Brown " ; --Venthyr
elseif id == 4 then
tex = prefix .. " Green " ; --Necrolord
else
tex = prefix .. " Cyan " ;
end
end
self.Background : SetTexture ( tex ) ;
self.Color : SetTexture ( tex ) ;
end
function NarciMinimapButtonMixin : SetIconScale ( scale )
self.Background : SetScale ( scale ) ;
end
function NarciMinimapButtonMixin : OnEnter ( )
if IsMouseButtonDown ( ) then return ; end ;
self : ShowMouseMotionVisual ( true ) ;
if ( not IsShiftKeyDown ( ) ) then
if self.showPanelOnMouseOver then
self.onEnterDelay : Show ( ) ;
elseif not self.Panel : IsShown ( ) then
local tooltip = GameTooltip ;
tooltip : SetOwner ( self , " ANCHOR_NONE " ) ;
tooltip : SetPoint ( " TOPRIGHT " , self , " BOTTOM " , 0 , 0 ) ;
tooltip : SetText ( NARCI_GRADIENT ) ;
--Normal Tooltip
local HotKey1 , HotKey2 = GetBindingKey ( " TOGGLECHARACTER0 " ) ;
local KeyText ;
local LeftClickText = L [ " Minimap Tooltip Left Click " ] ;
if HotKey1 and NarcissusDB.EnableDoubleTap then
KeyText = " ( " .. HotKey1 .. " ) " ;
if HotKey2 then
KeyText = KeyText .. " |cffffffff or |r( " .. HotKey2 .. " ) " ;
end
LeftClickText = LeftClickText .. " |cffffffff " .. " / " .. " |r " .. L [ " Minimap Tooltip Double Click " ] .. " " .. KeyText .. " |r " ;
end
local bindAction = " CLICK MiniButton:LeftButton " ;
local keyBind = GetBindingKey ( bindAction ) ;
if keyBind and keyBind ~= " " then
LeftClickText = LeftClickText .. " |cffffffff " .. " /|r " .. keyBind ;
end
tooltip : AddLine ( LeftClickText .. " " .. L [ " Minimap Tooltip To Open " ] , nil , nil , nil , false ) ;
tooltip : AddLine ( L [ " Minimap Tooltip Right Click " ] .. " " .. L [ " Minimap Tooltip Module Panel " ] , nil , nil , nil , false ) ;
tooltip : AddLine ( L [ " Minimap Tooltip Shift Left Click " ] .. " " .. L [ " Toggle Dressing Room " ] , nil , nil , nil , true ) ;
tooltip : AddLine ( L [ " Minimap Tooltip Shift Right Click " ] .. " " .. L [ " Minimap Tooltip Hide Button " ] , nil , nil , nil , true ) ;
tooltip : AddLine ( L [ " Minimap Tooltip Middle Button " ] , nil , nil , nil , true ) ;
tooltip : AddLine ( " " , nil , nil , nil , true ) ;
tooltip : AddDoubleLine ( NARCI_VERSION_INFO , NARCI_DEVELOPER_INFO , 0.8 , 0.8 , 0.8 , 0.8 , 0.8 , 0.8 ) ;
tooltip : AddLine ( " https://wow.curseforge.com/projects/narcissus " , 0.5 , 0.5 , 0.5 , false ) ;
tooltip : Show ( ) ;
end
end
end
function NarciMinimapButtonMixin : ShowMouseMotionVisual ( visible )
if not self : IsShown ( ) then return end ;
if visible then
SetCursor ( " Interface/CURSOR/Item.blp " ) ;
self.Color : Show ( ) ;
self : SetIconScale ( 1.1 ) ;
FadeFrame ( self.Color , 0.2 , 1 ) ;
FadeFrame ( self , 0.2 , 1 ) ;
else
ResetCursor ( ) ;
FadeFrame ( self.Color , 0.2 , 0 ) ;
FadeFrame ( self , 0.2 , self.endAlpha ) ;
self : SetIconScale ( 1 ) ;
end
end
function NarciMinimapButtonMixin : PlayBling ( )
self.Bling : Show ( ) ;
self.Bling . animScale : Play ( ) ;
end
function NarciMinimapButtonMixin : OnLeave ( )
GameTooltip : Hide ( ) ;
if self.PositionUpdator : IsShown ( ) then
return ;
end
if self : IsShown ( ) then
if not ( self.Panel : IsMouseOver ( ) and self.Panel : IsShown ( ) ) then
self : ShowPopup ( false ) ;
end
else
self.Color : SetAlpha ( 0 ) ;
end
end
function NarciMinimapButtonMixin : OnHide ( )
self : ShowPopup ( false ) ;
self.Panel . ClipFrame : Hide ( ) ;
self : UnregisterEvent ( " MODIFIER_STATE_CHANGED " ) ;
end
function NarciMinimapButtonMixin : ShowPopup ( visible )
if visible then
self.Panel : Show ( ) ;
self : RegisterEvent ( " GLOBAL_MOUSE_DOWN " ) ;
else
FadeFrame ( self.Panel , 0.15 , 0 ) ;
self : ShowMouseMotionVisual ( false ) ;
self.onEnterDelay : Hide ( ) ;
self.panelEntrance : Hide ( ) ;
self : UnregisterEvent ( " GLOBAL_MOUSE_DOWN " ) ;
end
end
function NarciMinimapButtonMixin : OnEvent ( event )
if event == " GLOBAL_MOUSE_DOWN " then
if not self : IsInBound ( ) then
self : ShowPopup ( false ) ;
end
elseif event == " MODIFIER_STATE_CHANGED " then
if self : IsDragging ( ) then
self : StartRepositioning ( ) ;
end
end
end
---------------End of derivation---------------
local RunePlateTexture = {
[ 0 ] = " Interface/AddOns/Narcissus/Art/Runes/Bright/Black " , --Enchantable but unenchanted
[ 1 ] = " Interface/AddOns/Narcissus/Art/Runes/RunePlate-Black " ,
[ 2 ] = " Interface/AddOns/Narcissus/Art/Runes/RunePlate-Uncommon " ,
[ 3 ] = " Interface/AddOns/Narcissus/Art/Runes/RunePlate-Rare " ,
[ 4 ] = " Interface/AddOns/Narcissus/Art/Runes/RunePlate-Epic " ,
[ 5 ] = " Interface/AddOns/Narcissus/Art/Runes/RunePlate-Legendary " ,
[ 6 ] = " Interface/AddOns/Narcissus/Art/Runes/RunePlate-Artifact " ,
[ 7 ] = " Interface/AddOns/Narcissus/Art/Runes/RunePlate-Heirloom " ,
}
---Get Transmog Appearance---
--[[
== sourceInfo ==
sourceType TRANSMOG_SOURCE_1 = " Boss Drop " ;
invType TRANSMOG_SOURCE_2 = " Quest " ;
visualID TRANSMOG_SOURCE_3 = " Vendor " ;
isCollected TRANSMOG_SOURCE_4 = " World Drop " ;
sourceID TRANSMOG_SOURCE_5 = " Achievement " ;
isHideVisual TRANSMOG_SOURCE_6 = " Profession " ;
itemID
itemModID Normal 0 , Heroic 1 , Mythic 3 , LFG 4
categoryID
name
quality
--]]
local xmogTable = {
{ 1 , INVTYPE_HEAD } , { 3 , INVTYPE_SHOULDER } , { 15 , INVTYPE_CLOAK } , { 5 , INVTYPE_CHEST } , { 4 , INVTYPE_BODY } , { 19 , INVTYPE_TABARD } , { 9 , INVTYPE_WRIST } , --Left **slotID for TABARD is 19
{ 10 , INVTYPE_HAND } , { 6 , INVTYPE_WAIST } , { 7 , INVTYPE_LEGS } , { 8 , INVTYPE_FEET } , --Right
{ 16 , INVTYPE_WEAPONMAINHAND } , { 17 , INVTYPE_WEAPONOFFHAND } , --Weapon
} ;
--[[
local function ShareHyperLink ( ) --Send transmog hyperlink to chat
local delay = 0 ; --Keep message in order
print ( MYMOG_GRADIENT )
for i = 1 , # xmogTable do
local index = xmogTable [ i ] [ 1 ]
if slotTable [ index ] and slotTable [ index ] . hyperlink then
After ( delay , function ( )
SendChatMessage ( xmogTable [ i ] [ 2 ] .. " : " .. slotTable [ index ] . hyperlink , " GUILD " )
end )
delay = delay + 0.1 ;
end
end
end
--]]
local GetInventoryItemCooldown = GetInventoryItemCooldown ;
local function SetItemSocketingFramePosition ( self ) --Let ItemSocketingFrame appear on the side of the slot
if ItemSocketingFrame then
if self.GemSlot : IsShown ( ) then
ItemSocketingFrame : Show ( )
else
ItemSocketingFrame : Hide ( )
return ;
end
ItemSocketingFrame : ClearAllPoints ( ) ;
if self.isRight then
ItemSocketingFrame : SetPoint ( " TOPRIGHT " , self , " TOPLEFT " , 4 , 0 ) ;
else
ItemSocketingFrame : SetPoint ( " TOPLEFT " , self , " TOPRIGHT " , - 4 , 0 ) ;
end
DefaultTooltip : Hide ( ) ;
end
end
local IsItemEnchantable = {
[ 11 ] = true ,
[ 12 ] = true ,
[ 16 ] = true ,
[ 17 ] = true ,
[ 5 ] = true ,
[ 8 ] = true ,
[ 9 ] = true ,
[ 10 ] = true ,
[ 15 ] = true ,
} ;
local RunicLetters = {
[ " crit " ] = " ᚲ \n ᚱ \n ᛁ " , --CRI
[ " haste " ] = " ᚼ \n ᛆ \n ᛋ " , --HAS
[ " mastery " ] = " ᛘ \n ᛋ \n ᛐ " , --MST
[ " versatility " ] = " ᚡ \n ᚽ \n ᚱ " , --VER
[ " STR " ] = " ᛊ \n ᛏ \n ᚱ " , --STR
[ " AGI " ] = " ᛆ \n ᚵ \n ᛁ " , --AGI
[ " INT " ] = " ᛁ \n ᚾ \n ᛐ " , --INT
[ " speed " ] = " ᛋ \n ᛕ \n ᛑ " , --SPD
[ " armor " ] = " ᛆ \n ᚱ \n ᛘ " , --ARM
[ " heal " ] = " ᚺ \n ᛁ \n ᛚ " , --HIL
[ " leech " ] = " ᛒ \n ᛚ \n ᛑ " , --BLD
[ " spell " ] = " ᛗ \n ᚷ \n ᚲ " , --MGC
}
local function DisplayRuneSlot ( equipmentSlot , slotID , itemQuality , itemLink )
--! RuneSlot.Background is disabled
if not equipmentSlot.RuneSlot then
return ;
elseif ( itemQuality == 0 ) or ( not itemLink ) then
equipmentSlot.RuneSlot : Hide ( ) ;
return ;
end
if IsItemEnchantable [ slotID ] then
equipmentSlot.RuneSlot : Show ( ) ;
--equipmentSlot.RuneSlot.Background:SetTexture(RunePlateTexture[0]);
else
equipmentSlot.RuneSlot : Hide ( ) ;
return ;
end
local enchantID = GetItemEnchantID ( itemLink ) ;
if enchantID ~= 0 then
equipmentSlot.RuneSlot . RuneLetter : Show ( ) ;
if EnchantInfo [ enchantID ] then
equipmentSlot.RuneSlot . RuneLetter : SetText ( GetVerticalRunicLetters ( EnchantInfo [ enchantID ] [ 1 ] ) ) ;
equipmentSlot.RuneSlot . spellID = EnchantInfo [ enchantID ] [ 3 ]
end
else
--equipmentSlot.RuneSlot.Background:SetTexture(RunePlateTexture[0]) --if the item is enchantable but unenchanted, set its texture to black
equipmentSlot.RuneSlot . spellID = nil ;
equipmentSlot.RuneSlot . RuneLetter : Hide ( ) ;
end
end
function Narci_RuneButton_OnEnter ( self )
local spellID = self.spellID ;
if ( not spellID ) then
return ;
end
DefaultTooltip : SetOwner ( self , " ANCHOR_NONE " ) ;
if self : GetParent ( ) . isRight then
DefaultTooltip : SetPoint ( " TOPRIGHT " , self , " TOPLEFT " , 8 , 8 ) ;
else
DefaultTooltip : SetPoint ( " TOPLEFT " , self , " TOPRIGHT " , 0 , 8 ) ;
end
DefaultTooltip : SetSpellByID ( spellID ) ;
DefaultTooltip : Show ( ) ;
end
---------------------------------------------------
local USE_DELAY = true ;
local function AssignDelay ( id , forced )
if USE_DELAY or forced then
local time = 0 ;
if id == 1 then
time = 1 ;
elseif id == 2 then
time = 2 ;
elseif id == 3 then
time = 3 ;
elseif id == 15 then --back
time = 4 ;
elseif id == 5 then
time = 5 ;
elseif id == 9 then
time = 6 ;
elseif id == 16 then
time = 7 ;
elseif id == 17 then
time = 8 ;
elseif id == 4 then --shirt
time = 9 ;
elseif id == 10 then
time = 10 ;
elseif id == 6 then
time = 11 ;
elseif id == 7 then
time = 12 ;
elseif id == 8 then
time = 13 ;
elseif id == 11 then
time = 14 ;
elseif id == 12 then
time = 15 ;
elseif id == 13 then
time = 16 ;
elseif id == 14 then
time = 17 ;
elseif id == 19 then
time = 18 ;
end
time = time / 20 ;
return time ;
else
return 0 ;
end ;
end
local function GetTraitsIcon ( itemLocation )
if not itemLocation then return ; end
local TierInfos = C_AzeriteEmpoweredItem.GetAllTierInfo ( itemLocation ) ;
if not TierInfos then return ; end
local powerIDs , icon , _ ;
local isRightSpec = true ;
local traitIcons = { } ;
local specIndex = GetSpecialization ( ) or 1 ;
local specID = GetSpecializationInfo ( specIndex ) ;
local MAX_TIERS = 5 ;
for i = 1 , MAX_TIERS do
if ( not TierInfos [ i ] ) or ( not TierInfos [ i ] . azeritePowerIDs ) then
return traitIcons ;
end
powerIDs = TierInfos [ i ] . azeritePowerIDs ;
for k , powerID in pairs ( powerIDs ) do
if C_AzeriteEmpoweredItem.IsPowerSelected ( itemLocation , powerID ) then
local PowerInfo = C_AzeriteEmpoweredItem.GetPowerInfo ( powerID )
isRightSpec = isRightSpec and C_AzeriteEmpoweredItem.IsPowerAvailableForSpec ( powerID , specID ) ;
_ , _ , icon = GetSpellInfo ( PowerInfo and PowerInfo.spellID ) ;
traitIcons [ i ] = icon ;
break ;
else
traitIcons [ i ] = " " ;
end
end
end
return traitIcons , isRightSpec ;
end
local GetSlotVisualID = NarciAPI.GetSlotVisualID ;
local GetGemBorderTexture = NarciAPI.GetGemBorderTexture ;
local GetItemQualityColor = NarciAPI.GetItemQualityColor ;
local QueueFrame = NarciAPI.CreateProcessor ( nil , 0.5 ) ;
-----------------------------------------------------------------------
NarciItemButtonSharedMixin = { } ;
function NarciItemButtonSharedMixin : RegisterErrorEvent ( )
self : RegisterEvent ( " UI_ERROR_MESSAGE " ) ;
end
function NarciItemButtonSharedMixin : UnregisterErrorEvent ( )
self : UnregisterEvent ( " UI_ERROR_MESSAGE " ) ;
end
function NarciItemButtonSharedMixin : OnErrorMessage ( ... )
self : UnregisterErrorEvent ( ) ;
local _ , msg = ...
Narci_AlertFrame_Autohide : AddMessage ( msg , true ) ;
end
function NarciItemButtonSharedMixin : ResetAnimation ( )
self.Icon . scaleUp : Stop ( ) ;
self.Border . scaleUp : Stop ( ) ;
self.IconMask . scaleUp : Stop ( ) ;
self.Icon : SetScale ( 1 ) ;
self.Border : SetScale ( 1 ) ;
self.IconMask : SetScale ( 1 ) ;
end
function NarciItemButtonSharedMixin : SetBorderTexture ( border , texKey )
SetBorderTexture ( border , texKey , 2 ) ;
end
function NarciItemButtonSharedMixin : ShowAlphaChannel ( )
self.Icon : SetColorTexture ( 1 , 1 , 1 ) ;
self.Border : SetColorTexture ( 1 , 1 , 1 ) ;
self.Border . textureKey = - 1 ;
end
-----------------------------------------------------------------------
local validForTempEnchant = {
[ 16 ] = true ,
[ 17 ] = true ,
[ 5 ] = true ,
} ;
NarciEquipmentSlotMixin = CreateFromMixins { NarciItemButtonSharedMixin } ;
function NarciEquipmentSlotMixin : Refresh ( forceRefresh )
local _ ;
local slotID = self.slotID ;
local itemLocation = ItemLocation : CreateFromEquipmentSlot ( slotID )
--print(slotName..slotID)
--local texture = CharacterHeadSlot.popoutButton.icon:GetTexture()
local itemLink ;
local itemIcon , itemName , itemQuality , effectiveLvl , gemName , gemLink , gemID ;
local borderTexKey ;
local isAzeriteEmpoweredItem = false ; --3 Pieces **likely to be changed in patch 8.2
local isAzeriteItem = false ; --Heart of Azeroth
local isRuneforgeLegendary ; --Shadowlands
local isDominationItem ;
--local isCorruptedItem = false;
local bR , bG , bB ; --Item Name Color
if C_Item.DoesItemExist ( itemLocation ) then
if MOG_MODE then
self : UntrackCooldown ( ) ;
self : UntrackTempEnchant ( ) ;
self : HideVFX ( ) ;
self.isSlotHidden = false ; --Undress an item from player model
self.RuneSlot : Hide ( ) ;
self.GradientBackground : Show ( ) ;
local appliedSourceID , appliedVisualID , hasSecondaryAppearance = GetSlotVisualID ( slotID ) ;
if appliedVisualID > 0 then
--[[
local sourceInfo = { } ;
if appliedVisualID ~= self.appliedVisualID or ( not ( self.sourceInfo and self.sourceInfo . name ) ) then
self.appliedVisualID = appliedVisualID ;
sourceInfo = C_TransmogCollection.GetSourceInfo ( appliedSourceID ) ;
self.sourceInfo = sourceInfo ;
_ , self.sourceID = C_TransmogCollection.GetItemInfo ( sourceInfo.itemID , sourceInfo.itemModID ) ;
if sourceInfo.sourceType == 1 then
self.drops = C_TransmogCollection.GetAppearanceSourceDrops ( self.sourceID ) ;
end
else
sourceInfo = self.sourceInfo ;
end
--]]
local sourceInfo = C_TransmogCollection.GetSourceInfo ( appliedSourceID ) ;
itemName = sourceInfo and sourceInfo.name ;
if not itemName or itemName == " " then
QueueFrame : Add ( self , self.Refresh ) ;
return
end
self.itemID = sourceInfo.itemID ;
itemQuality = sourceInfo.quality ;
itemIcon = C_TransmogCollection.GetSourceIcon ( appliedSourceID ) ;
local _ , _ , _ , hex = GetItemQualityColor ( itemQuality ) ;
_ , self.hyperlink = GetItemInfo ( sourceInfo.itemID ) ;
self.itemModID = sourceInfo.itemModID ;
local sourceType = sourceInfo.sourceType ;
local difficulty ;
local bonusID ;
if sourceType == 1 then --TRANSMOG_SOURCE_BOSS_DROP = 1
local drops = C_TransmogCollection.GetAppearanceSourceDrops ( appliedSourceID ) ;
if drops and drops [ 1 ] then
effectiveLvl = drops [ 1 ] . encounter .. " " .. " |cFFFFD100 " .. drops [ 1 ] . instance .. " |r|CFFf8e694 " ;
self.sourcePlainText = drops [ 1 ] . encounter .. " " .. drops [ 1 ] . instance ;
if sourceInfo.itemModID == 0 then
difficulty = PLAYER_DIFFICULTY1 ;
bonusID = 3561 ;
self.hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 1 " .. " :1476:|h|r " ;
elseif sourceInfo.itemModID == 1 then
difficulty = PLAYER_DIFFICULTY2 ;
bonusID = 3562 ;
self.hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 2 " .. " :1476:|h|r " ;
elseif sourceInfo.itemModID == 3 then
difficulty = PLAYER_DIFFICULTY6 ;
bonusID = 3563 ;
self.hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 3 " .. " :1476:|h|r " ;
elseif sourceInfo.itemModID == 4 then
difficulty = PLAYER_DIFFICULTY3 ;
bonusID = 3564 ;
self.hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 4 " .. " :1476:|h|r " ;
end
if difficulty then
effectiveLvl = effectiveLvl .. " " .. difficulty ;
self.sourcePlainText = self.sourcePlainText .. " " .. difficulty ;
end
end
else
if sourceType == 2 then --quest
effectiveLvl = TRANSMOG_SOURCE_2
if sourceInfo.itemModID == 3 then
self.hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:512 " .. " 6 " .. " :1562:|h|r " ;
bonusID = 5126 ;
elseif sourceInfo.itemModID == 2 then
self.hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:512 " .. " 5 " .. " :1562:|h|r " ;
bonusID = 5125 ;
elseif sourceInfo.itemModID == 1 then
self.hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:512 " .. " 4 " .. " :1562:|h|r " ;
bonusID = 5124 ;
end
elseif sourceType == 3 then --vendor
effectiveLvl = TRANSMOG_SOURCE_3 ;
elseif sourceType == 4 then --world drop
effectiveLvl = TRANSMOG_SOURCE_4 ;
elseif sourceType == 5 then --achievement
effectiveLvl = TRANSMOG_SOURCE_5 ;
elseif sourceType == 6 then --profession
effectiveLvl = TRANSMOG_SOURCE_6 ;
else
if itemQuality == 6 then
effectiveLvl = ITEM_QUALITY6_DESC ;
elseif itemQuality == 5 then
effectiveLvl = ITEM_QUALITY5_DESC ;
end
end
self.sourcePlainText = effectiveLvl ;
end
if self.hyperlink then
_ , self.hyperlink = GetItemInfo ( self.hyperlink ) ; --original hyperlink cannot be printed (workaround)
end
if itemQuality == 6 then
if slotID == 16 then
bonusID = ( sourceInfo.itemModID or 0 ) ; --Artifact use itemModID "7V0" + modID - 1
else
bonusID = 0 ;
end
end
self.bonusID = bonusID ;
if effectiveLvl == nil then
local _ , sourceName = IsItemSourceSpecial ( self.itemID ) ;
effectiveLvl = sourceName or " " ;
end
else --irrelevant slot
itemName = " " ;
itemQuality = 0 ;
itemIcon = GetInventoryItemTexture ( " player " , slotID ) ;
self.Icon : SetDesaturated ( true ) ;
self.Name : Hide ( ) ;
self.ItemLevel : Hide ( ) ;
self.GradientBackground : Hide ( ) ;
self.bonusID = nil ;
end
self : DisplayDirectionMark ( hasSecondaryAppearance , itemQuality ) ;
else
self : TrackCooldown ( ) ;
self : DisplayDirectionMark ( false ) ;
self.Icon : SetDesaturated ( false )
self.Name : Show ( ) ;
self.ItemLevel : Show ( ) ;
self.GradientBackground : Show ( ) ;
--[[
local current , maximum = GetInventoryItemDurability ( slotID ) ;
if current and maximum then
self.durability = ( current / maximum ) ;
end
--]]
itemLink = C_Item.GetItemLink ( itemLocation ) ;
if validForTempEnchant [ slotID ] then
--[[
local buffText , durationText = GetTemporaryItemBuff ( slotID ) ;
if buffText and durationText then
buffText = " |cffa1cca4 " .. buffText .. " |r " ;
durationText = " |cffa8a8a8 " .. durationText .. " |r " ;
effectiveLvl = effectiveLvl .. " " .. buffText .. " " .. durationText ;
end
--]]
local hasTempEnchant = NarciTempEnchantIndicatorController : InitFromSlotButton ( self ) ;
if hasTempEnchant ~= self.hasTempEnchant then
self.hasTempEnchant = hasTempEnchant ;
else
if itemLink == self.itemLink then
return
end
end
else
if itemLink == self.itemLink then
return
end
end
local itemVFX ;
local itemID = GetItemInfoInstant ( itemLink ) ;
borderTexKey , itemVFX , bR , bG , bB = GetBorderArtByItemID ( itemID ) ;
itemIcon = GetInventoryItemTexture ( " player " , slotID ) ;
itemName = C_Item.GetItemName ( itemLocation ) ;
itemQuality = C_Item.GetItemQuality ( itemLocation ) ;
effectiveLvl = C_Item.GetCurrentItemLevel ( itemLocation ) ;
self.ItemLevelCenter . ItemLevel : SetText ( effectiveLvl ) ;
--Debug
--if effectiveLvl and effectiveLvl > 1 then
-- NarciDebug:CalculateAverage(effectiveLvl);
--end
isDominationItem = DoesItemHaveDomationSocket ( itemID ) ;
if slotID == 13 or slotID == 14 then
if itemID == 167555 then --Pocket-Sized Computation Device
gemName , gemLink = IsItemSocketable ( itemLink , 2 ) ;
else
gemName , gemLink = IsItemSocketable ( itemLink ) ;
end
else
if isDominationItem then
gemName , gemID = GetItemDominationGem ( itemLink ) ;
else
gemName , gemLink = IsItemSocketable ( itemLink ) ;
end
end
self.hyperlink = nil ;
self.GemSlot . ItemLevel = effectiveLvl ;
self.gemLink = gemLink ; --Later used in OnEnter func in NarciSocketing.lua
if slotID == 2 then
isAzeriteItem = C_AzeriteItem.IsAzeriteItem ( itemLocation ) ;
self.isAzeriteItem = isAzeriteItem ;
if isAzeriteItem then
itemVFX = " Heart " ;
end
elseif slotID == 1 or slotID == 3 or slotID == 5 then
isAzeriteEmpoweredItem = C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem ( itemLocation ) ;
else
--isCorruptedItem = IsCorruptedItem(itemLink);
end
if slotID == 15 then
--Backslot
if itemID == 169223 then --Ashjra'kamas, Shroud of Resolve Legendary Cloak
local rank , corruptionResistance = NarciAPI.GetItemRank ( itemLink , " ITEM_MOD_CORRUPTION_RESISTANCE " ) ;
effectiveLvl = effectiveLvl .. " " .. rank .. " |cFFFFD100 " .. corruptionResistance .. " |r " ;
borderTexKey = " BlackDragon " ;
itemVFX = " DragonFire " ;
end
end
if slotID ~= 13 and slotID ~= 14 then
isRuneforgeLegendary = C_LegendaryCrafting.IsRuneforgeLegendary ( itemLocation ) ;
if isRuneforgeLegendary then
itemVFX = " Runeforge " ;
borderTexKey = " Runeforge " ;
end
end
local enchantText = GetItemEnchantText ( itemLink , true ) ;
if enchantText then
if self.isRight then
effectiveLvl = enchantText .. " " .. effectiveLvl ;
else
effectiveLvl = effectiveLvl .. " " .. enchantText ;
end
end
--Enchant Frame--
if itemQuality then --and not isRuneforgeLegendary
DisplayRuneSlot ( self , slotID , itemQuality , itemLink ) ;
end
--Item Visual Effects
if itemVFX then
self : ShowVFX ( itemVFX ) ;
else
self : HideVFX ( ) ;
end
end
if not itemName or itemName == " " then
QueueFrame : Add ( self , self.Refresh ) ;
return
end
self.itemLink = itemLink ;
else
self : UntrackCooldown ( ) ;
self : UntrackTempEnchant ( ) ;
self : HideVFX ( ) ;
self : DisplayDirectionMark ( false ) ;
self.GradientBackground : Hide ( ) ;
self.Icon : SetDesaturated ( false ) ;
self.ItemLevelCenter . ItemLevel : SetText ( " " ) ;
self.itemID = nil ;
self.bonusID = nil ;
self.itemLink = nil ;
self.gemLink = nil ;
itemQuality = 0 ;
itemIcon = self.emptyTexture ;
itemName = " " ;
effectiveLvl = " " ;
DisplayRuneSlot ( self , slotID , 0 ) ;
end
self.isDominationItem = isDominationItem ;
self.itemQuality = itemQuality ;
if itemQuality and not bR then --itemQuality sometimes return nil. This is a temporary solution
bR , bG , bB = GetItemQualityColor ( itemQuality ) ;
if not borderTexKey then
borderTexKey = itemQuality ;
end
end
bR = bR or 1 ;
bG = bG or 1 ;
bB = bB or 1 ;
--Test
--[[
if isRuneforgeLegendary then
itemName = " |cff8cb7c7Banshee's Lament|r " ;
itemName = " Old Warrior \' s Soul " ;
itemName = " |cffeb5b50Decanter of Endless Howling|r " ;
end
--]]
if isAzeriteEmpoweredItem then
borderTexKey = " Azerite " ;
if not MOG_MODE then
local icons , isRightSpec = GetTraitsIcon ( itemLocation ) ;
for i = 1 , # icons do
effectiveLvl = effectiveLvl .. " |T " .. icons [ i ] .. " :12:12:0:0:64:64:4:60:4:60|t " ;
end
end
end
if isAzeriteItem then
local heartLevel = C_AzeriteItem.GetPowerLevel ( itemLocation ) ;
local xp_Current , xp_Needed = C_AzeriteItem.GetAzeriteItemXPInfo ( itemLocation ) ;
local GetEssenceInfo = C_AzeriteEssence.GetEssenceInfo ;
local GetMilestoneEssence = C_AzeriteEssence.GetMilestoneEssence ;
if not C_AzeriteItem.IsAzeriteItemAtMaxLevel ( ) then
heartLevel = heartLevel .. " |CFFf8e694 " .. floor ( ( xp_Current / xp_Needed ) * 100 + 0.5 ) .. " % " ;
end
effectiveLvl = effectiveLvl .. " |cFFFFD100 " .. heartLevel ;
local EssenceID = GetMilestoneEssence ( 115 ) ;
if EssenceID then
borderTexKey = " Heart " ;
local EssenceInfo = GetEssenceInfo ( EssenceID ) ;
bR , bG , bB = GetItemQualityColor ( EssenceInfo.rank + 1 ) ;
itemName = EssenceInfo.name ;
itemIcon = EssenceInfo.icon ;
end
for i = 116 , 119 do
--116, 117, 119 3 minor slots
if i ~= 118 then
EssenceID = GetMilestoneEssence ( i ) ;
if EssenceID then
local icon = GetEssenceInfo ( EssenceID ) . icon ;
effectiveLvl = effectiveLvl .. " |T " .. icon .. " :12:12:0:0:64:64:4:60:4:60|t " ;
end
end
end
end
--[[
if isCorruptedItem then
borderTexKey = " NZoth " ;
if not MOG_MODE then
local corruption = GetItemStats ( itemLink ) [ " ITEM_MOD_CORRUPTION " ] ;
if corruption then
local Affix = GetCorruptedItemAffix ( itemLink ) ;
if Affix then
if self.isRight then
effectiveLvl = Affix .. " |cff946dd1 " .. corruption .. " |r " .. effectiveLvl ;
else
effectiveLvl = effectiveLvl .. " " .. Affix .. " |cff946dd1 " .. corruption .. " |r " ;
end
else
if self.isRight then
effectiveLvl = " |cff946dd1 " .. corruption .. " |r " .. effectiveLvl ;
else
effectiveLvl = effectiveLvl .. " |cff946dd1 " .. corruption .. " |r " ;
end
end
end
itemQuality = " NZoth " ;
end
end
--]]
--Gem Slot--
if gemName ~= nil then
local gemBorder , gemIcon , itemSubClassID ;
if isDominationItem then
if gemID then
_ , _ , _ , _ , gemIcon = GetItemInfoInstant ( gemID ) ;
gemBorder = GetDominationBorderTexture ( gemID ) ;
else
gemBorder = GetDominationBorderTexture ( nil ) ;
end
self.GemSlot . GemBorder : SetTexture ( gemBorder ) ;
else
--regular gems
if gemLink then
gemID , _ , _ , _ , gemIcon , _ , itemSubClassID = GetItemInfoInstant ( gemLink ) ;
gemBorder = GetGemBorderTexture ( itemSubClassID , gemID ) ;
else
gemBorder = GetGemBorderTexture ( nil ) ;
end
end
self.GemSlot . GemBorder : SetTexture ( gemBorder ) ;
self.GemSlot . GemIcon : SetTexture ( gemIcon ) ;
self.GemSlot . GemIcon : Show ( ) ;
self.GemSlot . sockedGemItemID = gemID ;
self.GemSlot : Show ( ) ;
if self : IsVisible ( ) then
self.GemSlot . animIn : Play ( ) ;
end
self.GemSlot . isDomiationSocket = isDominationItem ;
else
if self : IsVisible ( ) then
self.GemSlot . animOut : Play ( ) ;
else
self.GemSlot : Hide ( ) ;
end
self.GemSlot . sockedGemItemID = nil ;
end
--------------------------------------------------
if self : IsVisible ( ) then
self : SetBorderTexture ( self.Border , borderTexKey ) ;
if itemIcon then
self.IconOverlay : SetTexture ( itemIcon ) ;
self.Icon . anim : Play ( ) ;
end
self.ItemLevel . anim1 : SetScript ( " OnFinished " , function ( )
self.ItemLevel : SetText ( effectiveLvl ) ;
self.ItemLevel . anim2 : Play ( ) ;
end )
self.Name . anim1 : SetScript ( " OnFinished " , function ( )
self.Name : SetText ( itemName ) ;
self.Name : SetTextColor ( bR , bG , bB ) ;
self.Name . anim2 : Play ( ) ;
After ( 0 , function ( )
self : UpdateGradientSize ( ) ;
end )
end )
self.ItemLevel . anim1 : Play ( ) ;
self.Name . anim1 : Play ( ) ;
else
self.ItemLevel : SetText ( effectiveLvl ) ;
self.Name : SetText ( itemName ) ;
self.Name : SetTextColor ( bR , bG , bB ) ;
self : SetBorderTexture ( self.Border , borderTexKey ) ;
if itemIcon then
self.Icon : SetTexture ( itemIcon ) ;
end
self : UpdateGradientSize ( ) ;
end
--self.GradientBackground:SetHeight(self.Name:GetHeight() + self.ItemLevel:GetHeight() + 18);
self.itemNameColor = { bR , bG , bB } ;
return true
end
function NarciEquipmentSlotMixin : UpdateGradientSize ( )
local text2Width = self.ItemLevel : GetWrappedWidth ( ) ;
local extraWidth ;
if self.TempEnchantIndicator then
extraWidth = 48 ;
self.TempEnchantIndicator : ClearAllPoints ( ) ;
if self.isRight then
self.TempEnchantIndicator : SetPoint ( " TOPRIGHT " , self.ItemLevel , " TOPRIGHT " , - text2Width - 6 , 0 ) ;
else
local extraOffset ;
if self.ItemLevel : IsTruncated ( ) then
text2Width = self.ItemLevel : GetWidth ( ) ;
end
self.TempEnchantIndicator : SetPoint ( " TOPLEFT " , self.ItemLevel , " TOPLEFT " , text2Width + 6 , 0 ) ;
end
else
extraWidth = 0 ;
end
self.GradientBackground : SetHeight ( self.Name : GetHeight ( ) + self.ItemLevel : GetHeight ( ) + 18 ) ;
self.GradientBackground : SetWidth ( max ( self.Name : GetWrappedWidth ( ) , text2Width + extraWidth ) + 48 ) ;
end
function NarciEquipmentSlotMixin : OnLoad ( )
local slotName = self.slotName ;
local slotID , textureName = GetInventorySlotInfo ( slotName ) ;
self.emptyTexture = textureName ;
self : SetID ( slotID ) ;
self.slotID = slotID ;
self : SetAttribute ( " type2 " , " item " ) ;
self : SetAttribute ( " item " , slotID ) ;
self : RegisterForDrag ( " LeftButton " ) ;
self : RegisterForClicks ( " LeftButtonUp " , " RightButtonUp " ) ;
if self : GetParent ( ) then
if not self : GetParent ( ) . slotTable then
self : GetParent ( ) . slotTable = { }
end
tinsert ( self : GetParent ( ) . slotTable , self ) ;
end
slotTable [ slotID ] = self ;
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciEquipmentSlotMixin : OnEvent ( event , ... )
if event == " MODIFIER_STATE_CHANGED " then
local key , state = ... ;
if ( key == " LALT " and self : IsMouseOver ( ) ) then
local flyout = EquipmentFlyoutFrame ;
if state == 1 then
if flyout : IsShown ( ) and flyout.slotID == self : GetID ( ) then
flyout : Hide ( ) ;
else
flyout : SetItemSlot ( self , true ) ;
end
else
end
end
elseif event == " UI_ERROR_MESSAGE " then
self : OnErrorMessage ( ... ) ;
end
end
function NarciEquipmentSlotMixin : UntrackCooldown ( )
if self.CooldownFrame then
self.CooldownFrame : Clear ( ) ;
self.CooldownFrame = nil ;
end
end
function NarciEquipmentSlotMixin : TrackCooldown ( )
local start , duration , enable = GetInventoryItemCooldown ( " player " , self : GetID ( ) ) ;
if enable and enable ~= 0 and start > 0 and duration > 0 then
if not self.CooldownFrame then
self.CooldownFrame = NarciItemCooldownUtil.AccquireFrame ( self ) ;
end
self.CooldownFrame : SetCooldown ( start , duration ) ;
return true
else
self : UntrackCooldown ( ) ;
end
return false
end
function NarciEquipmentSlotMixin : UntrackTempEnchant ( )
if self.TempEnchantIndicator then
self.TempEnchantIndicator : Hide ( ) ;
self.TempEnchantIndicator = nil ;
end
end
function NarciEquipmentSlotMixin : OnEnter ( motion , isGamepad )
self : RegisterEvent ( " MODIFIER_STATE_CHANGED " ) ;
if isGamepad then
self.Icon . scaleUp : Play ( ) ;
self.Border . scaleUp : Play ( ) ;
self.IconMask . scaleUp : Play ( ) ;
else
FadeFrame ( self.Highlight , 0.15 , 1 ) ;
end
if IsAltKeyDown ( ) and not MOG_MODE then
EquipmentFlyoutFrame : SetItemSlot ( self , true ) ;
end
if EquipmentFlyoutFrame : IsShown ( ) then
Narci_Comparison_SetComparison ( EquipmentFlyoutFrame.BaseItem , self ) ;
return ;
end
DefaultTooltip : SetOwner ( self , " ANCHOR_NONE " ) ;
if self.isRight then
DefaultTooltip : SetPoint ( " TOPRIGHT " , self , " TOPLEFT " , DefaultTooltip.offsetX , DefaultTooltip.offsetY ) ;
else
DefaultTooltip : SetPoint ( " TOPLEFT " , self , " TOPRIGHT " , - DefaultTooltip.offsetX , DefaultTooltip.offsetY ) ;
end
if ( self.hyperlink ) then
DefaultTooltip : SetHyperlink ( self.hyperlink ) ;
DefaultTooltip : Show ( ) ;
return ;
end
local hasItem , hasCooldown , repairCost = DefaultTooltip : SetInventoryItem ( " player " , self : GetID ( ) , nil , true ) ;
if isGamepad then
DefaultTooltip : SetAlpha ( 0 ) ;
if self.isRight then
NarciAPI_ShowDelayedTooltip ( " TOPRIGHT " , self , " TOPLEFT " , DefaultTooltip.offsetX , DefaultTooltip.offsetY ) ;
else
NarciAPI_ShowDelayedTooltip ( " TOPLEFT " , self , " TOPRIGHT " , - DefaultTooltip.offsetX , DefaultTooltip.offsetY ) ;
end
else
DefaultTooltip : Show ( ) ;
if hasItem then
DefaultTooltip.HotkeyFrame : FadeIn ( ) ;
end
end
end
function NarciEquipmentSlotMixin : OnLeave ( )
self : UnregisterEvent ( " MODIFIER_STATE_CHANGED " ) ;
self : UnregisterErrorEvent ( ) ;
FadeFrame ( self.Highlight , 0.25 , 0 ) ;
Narci : HideButtonTooltip ( ) ;
self : ResetAnimation ( ) ;
end
function NarciEquipmentSlotMixin : OnHide ( )
self.Highlight : Hide ( ) ;
self.Highlight : SetAlpha ( 0 ) ;
self : ResetAnimation ( ) ;
end
function NarciEquipmentSlotMixin : PostClick ( button )
if CursorHasItem ( ) then
EquipCursorItem ( self : GetID ( ) ) ;
return
end
ClearCursor ( ) ;
if ( IsModifiedClick ( ) ) then
if IsAltKeyDown ( ) and button == " LeftButton " then
local action = EquipmentManager_UnequipItemInSlot ( self : GetID ( ) )
if action then
EquipmentManager_RunAction ( action )
end
return ;
elseif IsShiftKeyDown ( ) and button == " LeftButton " then
if self.hyperlink then
SendChatMessage ( self.hyperlink )
end
--ShareHyperLink()
else
PaperDollItemSlotButton_OnModifiedClick ( self , button ) ;
TakeOutFrames ( true ) ;
SetItemSocketingFramePosition ( self ) ;
end
else
if button == " LeftButton " then
if not MOG_MODE then --Undress an item from player model while in Xmog Mode
--EquipmentFlyoutFrame:SetItemSlot(self);
Narci_EquipmentOption : SetFromSlotButton ( self , true )
end
elseif button == " RightButton " then
Narci_AlertFrame_Autohide : SetAnchor ( self , - 24 , true ) ;
end
end
end
function NarciEquipmentSlotMixin : OnDragStart ( )
local itemLocation = ItemLocation : CreateFromEquipmentSlot ( self : GetID ( ) )
if C_Item.DoesItemExist ( itemLocation ) then
C_Item.UnlockItem ( itemLocation ) ;
PickupInventoryItem ( self : GetID ( ) ) ;
end
end
function NarciEquipmentSlotMixin : OnReceiveDrag ( )
PickupInventoryItem ( self : GetID ( ) ) ; --In fact, attemp to equip cursor item
end
function NarciEquipmentSlotMixin : DisplayDirectionMark ( visible , itemQuality )
if self.slotID == 2 or self.slotID == 3 then
if visible then
if not self.DirectionMark then
self.DirectionMark = CreateFrame ( " Frame " , nil , self , " NarciTransmogSlotDirectionMarkTemplate " ) ;
self.DirectionMark : SetPoint ( " RIGHT " , self , " LEFT " , 9 , 0 ) ;
self.DirectionMark : SetDirection ( self.slotID - 1 ) ;
end
FadeFrame ( self.DirectionMark , 0.25 , 1 ) ;
if itemQuality then
self.DirectionMark : SetQualityColor ( itemQuality ) ;
end
else
if self.DirectionMark then
self.DirectionMark : Hide ( ) ;
self.DirectionMark : SetAlpha ( 0 ) ;
end
end
end
end
function NarciEquipmentSlotMixin : ShowVFX ( effectName )
if effectName then
if self.VFX then
self.VFX : SetUpByName ( effectName ) ;
else
self.VFX = NarciItemVFXContainer : AcquireAndSetModelScene ( self , effectName ) ;
end
else
self : HideVFX ( ) ;
end
end
function NarciEquipmentSlotMixin : HideVFX ( )
if self.VFX then
self.VFX : Remove ( ) ;
end
end
local function SetStatTooltipText ( self )
DefaultTooltip : ClearAllPoints ( ) ;
DefaultTooltip : SetOwner ( self , " ANCHOR_NONE " ) ;
DefaultTooltip : SetText ( self.tooltip ) ;
if ( self.tooltip2 ) then
DefaultTooltip : AddLine ( self.tooltip2 , NORMAL_FONT_COLOR.r , NORMAL_FONT_COLOR.g , NORMAL_FONT_COLOR.b , true ) ;
end
if ( self.tooltip3 ) then
DefaultTooltip : AddLine ( " " ) ;
DefaultTooltip : AddLine ( self.tooltip3 , RAID_CLASS_COLORS [ " MAGE " ] . r , RAID_CLASS_COLORS [ " MAGE " ] . g , RAID_CLASS_COLORS [ " MAGE " ] . b , true ) ;
end
if ( self.tooltip4 ) then
DefaultTooltip : AddLine ( " " ) ;
DefaultTooltip : AddDoubleLine ( self.tooltip4 [ 1 ] , self.tooltip4 [ 2 ] , NORMAL_FONT_COLOR.r , NORMAL_FONT_COLOR.g , NORMAL_FONT_COLOR.b , NORMAL_FONT_COLOR.r , NORMAL_FONT_COLOR.g , NORMAL_FONT_COLOR.b ) ;
end
end
function Narci_ShowStatTooltip ( self , direction )
if ( not self.tooltip ) then
return ;
end
SetStatTooltipText ( self )
if ( not direction ) then
DefaultTooltip : SetPoint ( " TOPRIGHT " , self , " TOPLEFT " , - 4 , 0 )
elseif direction == " RIGHT " then
DefaultTooltip : SetPoint ( " LEFT " , self , " RIGHT " , 0 , 0 )
elseif direction == " TOP " then
DefaultTooltip : SetPoint ( " BOTTOM " , self , " TOP " , 0 , - 4 )
elseif direction == " CURSOR " then
DefaultTooltip : SetOwner ( self , " ANCHOR_CURSOR " ) ;
end
DefaultTooltip : Show ( ) ;
end
function Narci_ShowStatTooltipDelayed ( self )
if ( not self.tooltip ) then
return ;
end
SetStatTooltipText ( self ) ;
DefaultTooltip : SetAlpha ( 0 ) ;
NarciAPI_ShowDelayedTooltip ( " BOTTOM " , self , " TOP " , 0 , - 4 ) ;
end
local function ShowDetailedIlvlInfo ( self )
if NarcissusDB.DetailedIlvlInfo then
FadeFrame ( Narci_DetailedStatFrame , 0 , 1 ) ;
FadeFrame ( RadarChart , 0 , 1 ) ;
FadeFrame ( Narci_ConciseStatFrame , 0 , 0 ) ;
else
FadeFrame ( Narci_DetailedStatFrame , 0 , 0 ) ;
FadeFrame ( RadarChart , 0 , 0 ) ;
FadeFrame ( Narci_ConciseStatFrame , 0 , 1 ) ;
end
end
--/dump GetItemStats(GetInventoryItemLink("player", 8))
--/script DEFAULT_CHAT_FRAME:AddMessage("\124cff0070dd\124Hitem:152783::::::::120::::1:1672:\124h[Mac'Aree Focusing Amethyst]\124h\124r");
--/script DEFAULT_CHAT_FRAME:AddMessage("\124cff0070dd\124Hitem:152783::::::::120::::1:1657:\124h[Mac'Aree Focusing Amethyst]\124h\124r");
--/script DEFAULT_CHAT_FRAME:AddMessage("\124cff0070dd\124Hitem:158362::::::::120::::2:1557:4778:\124h[Lord Waycrest's Signet]\124h\124r");
--[[ Stats sum ilvl ilvl+ from Gem
Ring 1.7626 * ilvl - 246.88 ( sum + 246.88 ) / 1.7626 40 / 1.7626 = 22.6937
--]]
NarciItemLevelFrameMixin = { } ;
function NarciItemLevelFrameMixin : OnLoad ( )
ItemLevelFrame = self ;
if NarciDominationIndicatorMixin then
local inhertMethods = {
" IsNarcissusUI " , " Update " , " CheckSetBonus " , " SetNodeLayout " , " ShowTooltip " ,
} ;
for k , v in pairs ( inhertMethods ) do
self.DominationOverlay [ v ] = NarciDominationIndicatorMixin [ v ] ;
end
self.checkDomination = true ;
end
local LeftButton = self.LeftButton ;
LeftButton : SetScript ( " OnEnter " , function ( f )
if f.isSameLevel then
f.tooltipHeadline = format ( f.tooltipFormat , f.Level : GetText ( ) ) ;
else
f.tooltipHeadline = format ( f.tooltipFormat , f.Level : GetText ( ) ) .. format ( " (max %s) " , f.avgItemLevel ) ;
end
if f.avgItemLevelPvp and f.avgItemLevelPvp ~= 0 then
f.tooltipSpecial = format ( STAT_AVERAGE_PVP_ITEM_LEVEL , f.avgItemLevelPvp ) ;
else
f.tooltipSpecial = nil ;
end
Narci_ShowButtonTooltip ( f ) ;
FadeFrame ( f.Highlight , 0.15 , 1 ) ;
end ) ;
end
function NarciItemLevelFrameMixin : Update ( playerLevel )
playerLevel = playerLevel or UnitLevel ( " player " ) ;
local avgItemLevel , avgItemLevelEquipped , avgItemLevelPvp = GetAverageItemLevel ( ) ;
local avgItemLevelBase = floor ( avgItemLevel ) ;
avgItemLevel = floor ( avgItemLevel * 100 + 0.5 ) / 100 ;
avgItemLevelEquipped = floor ( avgItemLevelEquipped * 100 + 0.5 ) / 100 ;
avgItemLevelPvp = floor ( avgItemLevelEquipped * 100 + 0.5 ) / 100 ;
self.LeftButton . avgItemLevel = avgItemLevel ;
self.LeftButton . avgItemLevelPvp = avgItemLevelPvp ;
self.LeftButton . isSameLevel = ( avgItemLevel == avgItemLevelEquipped ) ;
self.LeftButton . Level : SetText ( avgItemLevelEquipped ) ;
local r , g , b = 0.25 , 0.25 , 0.25 ;
local colorName , qualityIndex ;
local covenantID ;
if playerLevel >= 48 then
covenantID = C_Covenants.GetActiveCovenantID ( ) ;
end
if covenantID and covenantID ~= 0 then
self : UpdateRenownLevel ( ) ;
if covenantID == 1 then
colorName = " CovenantKyrian " ;
r , g , b = 0.76 , 0.89 , 0.94 ;
elseif covenantID == 2 then
colorName = " CovenantVenthyr " ;
r , g , b = 0.55 , 0 , 0.19 ;
elseif covenantID == 3 then
colorName = " CovenantNightFae " ;
r , g , b = 0.11 , 0.42 , 0.80 ;
elseif covenantID == 4 then
colorName = " CovenantNecrolord " ;
r , g , b = 0 , 0.63 , 0.43 ;
end
else
self : UpdateRenownLevel ( 0 ) ;
if playerLevel <= 15 then
colorName = " Grey " ;
qualityIndex = 0 ;
elseif playerLevel <= 30 then
colorName = " Green " ;
qualityIndex = 2 ;
elseif playerLevel <= 45 then
colorName = " Blue " ;
qualityIndex = 3 ;
elseif playerLevel > 45 then
if avgItemLevel < 85 then
colorName = " Blue " ;
qualityIndex = 3 ;
else
colorName = " Purple " ;
qualityIndex = 4 ;
end
elseif playerLevel > 50 then
if avgItemLevel < 158 then
colorName = " Green " ;
qualityIndex = 2 ;
elseif avgItemLevel < 183 then
colorName = " Blue " ;
qualityIndex = 3 ;
else
colorName = " Purple " ;
qualityIndex = 4 ;
end
end
r , g , b = GetItemQualityColor ( qualityIndex ) ;
end
local frame = self.CenterButton ;
frame.Background : SetTexture ( " Interface \\ AddOns \\ Narcissus \\ ART \\ Solid \\ " .. colorName ) ;
frame.Background : SetTexCoord ( 0 , 1 , 0 , 1 ) ;
frame.Fluid : SetColorTexture ( r , g , b ) ;
local percentage = avgItemLevel - avgItemLevelBase ;
local height ; --Set the bar(Fluid) height in the Tube
if percentage < 0.10 then
height = 0.1 ;
elseif percentage > 0.90 then
height = 84 ;
else
height = 84 * percentage ;
end
frame.Fluid : SetHeight ( height ) ;
frame.Level : SetText ( avgItemLevelBase ) ;
frame.tooltip = STAT_AVERAGE_ITEM_LEVEL .. " " .. avgItemLevel ;
end
function NarciItemLevelFrameMixin : UpdateRenownLevel ( newLevel )
local renownLevel = newLevel or C_CovenantSanctumUI.GetRenownLevel ( ) or 0 ;
local headerText = string.format ( COVENANT_SANCTUM_LEVEL , renownLevel ) ;
if C_CovenantSanctumUI.HasMaximumRenown ( ) then
headerText = headerText .. " (maxed) " ;
else
--to-do: get max level: C_CovenantSanctumUI.GetRenownLevels is too much
end
local frame = self.RightButton ;
frame.Header : SetText ( " RN " ) ;
frame.tooltipHeadline = headerText ;
frame.Number : SetText ( renownLevel ) ;
if renownLevel == 0 then
frame.tooltipLineOpen = " You will be able to join a Covenant and progress Renown level once you reach 60. " ;
else
frame.tooltipLineOpen = COVENANT_RENOWN_TUTORIAL_PROGRESS ;
end
end
function NarciItemLevelFrameMixin : SetTheme ( isDomination )
local file ;
if isDomination then
file = " Interface \\ AddOns \\ Narcissus \\ Art \\ Widgets \\ Domination \\ ItemLevelHexagon " ;
self.CenterButton : ShowMaxLevel ( false ) ;
self.CenterButton . Highlight : SetTexture ( " Interface \\ AddOns \\ Narcissus \\ Art \\ Widgets \\ Domination \\ ItemLevelHexagonHighlight " ) ;
self.CenterButton . Highlight : SetSize ( 128 , 128 ) ;
self.CenterButton . Highlight : SetBlendMode ( " BLEND " ) ;
else
file = " Interface \\ AddOns \\ Narcissus \\ Art \\ Widgets \\ ItemLevel \\ HexagonTube " ;
self.CenterButton : ShowMaxLevel ( true ) ;
self.CenterButton . Highlight : SetTexture ( " Interface \\ AddOns \\ Narcissus \\ Art \\ Solid \\ HexagonSolid-Highlight " ) ;
self.CenterButton . Highlight : SetSize ( 100 , 100 ) ;
self.CenterButton . Highlight : SetBlendMode ( " ADD " ) ;
end
local textures = {
self.CenterButton . FluidBackground , self.CenterButton . TubeBorder ,
self.LeftButton . Background , self.LeftButton . Highlight ,
self.RightButton . Background , self.RightButton . Highlight ,
} ;
for k , tex in pairs ( textures ) do
tex : SetTexture ( file ) ;
end
end
function NarciItemLevelFrameMixin : UpdateDomination ( )
if not self.checkDomination then return end ;
if not self.pauseUpdate then
self.pauseUpdate = true ;
After ( 0 , function ( )
local isDomination = self.DominationOverlay : Update ( ) ;
self.CenterButton . isDomination = isDomination ;
if self.isDomination ~= isDomination then
self.isDomination = isDomination ;
self : SetTheme ( isDomination ) ;
end
self.pauseUpdate = nil ;
end )
end
end
function NarciItemLevelFrameMixin : ToggleExtraInfo ( state , replayAnimation )
if not self.animFrame then
self.animFrame = CreateFrame ( " Frame " ) ;
self.animFrame : Hide ( ) ;
self.animFrame : SetScript ( " OnUpdate " , function ( f , elapsed )
f.t = f.t + elapsed ;
local offsetX = outSine ( f.t , f.fromX , f.toX , 0.4 ) ;
if f.t >= 0.4 then
offsetX = f.toX ;
f : Hide ( ) ;
if f.hideButton then
self.LeftButton : Hide ( ) ;
self.RightButton : Hide ( ) ;
end
end
self.LeftButton : SetPoint ( " RIGHT " , self , " CENTER " , - offsetX , 0 ) ;
self.RightButton : SetPoint ( " LEFT " , self , " CENTER " , offsetX , 0 ) ;
end ) ;
end
self.animFrame : Hide ( ) ;
self.animFrame . t = 0 ;
local _ , _ , _ , fromX = self.RightButton : GetPoint ( ) ;
self.animFrame . fromX = fromX ;
if state then
self.animFrame . toX = 28 ;
self.LeftButton : Show ( ) ;
self.RightButton : Show ( ) ;
self.animFrame . hideButton = false ;
else
self.animFrame . toX = - 32 ;
self.animFrame . hideButton = true ;
end
if fromX ~= self.animFrame . toX or replayAnimation then
self.animFrame : Show ( ) ;
end
end
NarciItemLevelCenterButtonMixin = { } ;
function NarciItemLevelCenterButtonMixin : OnLoad ( )
self.tooltip2 = HIGHLIGHT_FONT_COLOR_CODE .. STAT_AVERAGE_ITEM_LEVEL_TOOLTIP .. FONT_COLOR_CODE_CLOSE ;
--self.tooltip3 = L["Toggle Equipment Set Manager"];
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciItemLevelCenterButtonMixin : OnEnter ( )
FadeFrame ( self.Highlight , 0.2 , 1 ) ;
--EquipmentSetManager
--corruption or not
--[[
if self.isCorrupted then
NarciAPI_RunDelayedFunction ( self , 0.2 , function ( )
local frame = Narci_CorruptionTooltip ;
if not frame : IsVisible ( ) and not self.isSetManagerOpen and not IsMouseButtonDown ( ) then
frame : ClearAllPoints ( ) ;
frame.ModelScene . Background : SetGradientAlpha ( " VERTICAL " , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ) ;
frame : SetScale ( self : GetScale ( ) ) ;
frame : SetParent ( self ) ;
frame : SetPoint ( " TOP " , self , " BOTTOM " , 0 , - 12 ) ;
frame : SetHitRectInsets ( - 32 , - 32 , - 32 , - 32 ) ;
FadeFrame ( frame , 0.25 , 1 ) ;
end
end ) ;
end
--]]
if self.isDomination then
NarciAPI_RunDelayedFunction ( self , 0.2 , function ( )
self : GetParent ( ) . DominationOverlay : ShowTooltip ( DefaultTooltip , " TOP " , self , " BOTTOM " , 0 , - 12 ) ;
DefaultTooltip : SetAlpha ( 0 ) ;
FadeFrame ( DefaultTooltip , 0.2 , 1 ) ;
end ) ;
else
Narci_ShowStatTooltipDelayed ( self ) ;
end
end
function NarciItemLevelCenterButtonMixin : OnMouseDown ( )
self.Background : SetPoint ( " CENTER " , 0 , - 4 ) ;
if self.isCorrupted then
NarciAPI_FadeFrame ( Narci_CorruptionTooltip , 0.2 , 0 ) ;
end
end
function NarciItemLevelCenterButtonMixin : OnMouseUp ( )
self.Background : SetPoint ( " CENTER " , 0 , 0 ) ;
end
function NarciItemLevelCenterButtonMixin : OnLeave ( )
FadeFrame ( self.Highlight , 0.2 , 0 ) ;
Narci : HideButtonTooltip ( ) ;
end
function NarciItemLevelCenterButtonMixin : OnClick ( )
Narci_NavBar : ToggleView ( 2 ) ;
end
function NarciItemLevelCenterButtonMixin : OnHide ( )
if self.onHideFunc then
self.onHideFunc ( self ) ;
end
end
function NarciItemLevelCenterButtonMixin : ShowItemLevel ( )
ItemLevelFrame : Update ( ) ;
end
function NarciItemLevelCenterButtonMixin : ShowMaxLevel ( state )
self.Header : SetShown ( state ) ;
self.Level : SetShown ( state ) ;
self.Surface : SetShown ( state ) ;
self.Fluid : SetShown ( state ) ;
self.Background : SetShown ( state ) ;
end
local function UpdateCharacterInfoFrame ( newLevel )
local level = newLevel or UnitLevel ( " player " ) ;
local _ , currentSpecName ;
local currentSpec = GetSpecialization ( ) ;
if currentSpec then
_ , currentSpecName = GetSpecializationInfo ( currentSpec ) ;
else
currentSpecName = " " ;
end
local className , englishClass = UnitClass ( " player " ) ;
local _ , _ , _ , rgbHex = GetClassColor ( englishClass ) ;
local frame = Narci_PlayerInfoFrame ;
if currentSpecName then
local titleID = GetCurrentTitle ( ) ;
local titleName = GetTitleName ( titleID ) ;
if titleName then
titleName = strtrim ( titleName ) ; --delete the space in Title
frame.Miscellaneous : SetText ( titleName .. " | " .. " |cFFFFD100 " .. level .. " |r " .. " " .. " |c " .. rgbHex .. currentSpecName .. " " .. className .. " |r " ) ;
else
frame.Miscellaneous : SetText ( " Level " .. " |cFFFFD100 " .. level .. " |r " .. " |c " .. rgbHex .. currentSpecName .. " " .. className .. " |r " ) ;
end
end
ItemLevelFrame : Update ( level ) ;
end
local SlotController = { } ;
SlotController.updateFrame = CreateFrame ( " Frame " ) ;
SlotController.updateFrame : Hide ( ) ;
SlotController.updateFrame : SetScript ( " OnUpdate " , function ( f , elapsed )
f.t = f.t + elapsed ;
if f.t >= 0.05 then
f.t = 0 ;
if SlotController : Refresh ( f.sequence [ f.i ] , f.forceRefresh ) then
f.i = f.i + 1 ;
else
f : Hide ( ) ;
end
end
end ) ;
SlotController.refreshSequence = {
1 , 2 , 3 , 15 , 5 , 9 , 16 , 17 , 4 ,
10 , 6 , 7 , 8 , 11 , 12 , 13 , 14 , 19 ,
} ;
SlotController.tempEnchantSequence = { } ;
for slotID in pairs ( validForTempEnchant ) do
tinsert ( SlotController.tempEnchantSequence , slotID ) ;
end
function SlotController : Refresh ( slotID , forceRefresh )
if slotTable [ slotID ] then
slotTable [ slotID ] : Refresh ( forceRefresh ) ;
return true ;
end
end
function SlotController : RefreshAll ( )
for slotID , slotButton in pairs ( slotTable ) do
slotButton : Refresh ( ) ;
end
end
function SlotController : StopRefresh ( )
if self.updateFrame then
self.updateFrame : Hide ( ) ;
end
end
function SlotController : LazyRefresh ( sequenceName )
local f = self.updateFrame ;
f : Hide ( ) ;
f.t = 0 ;
f.i = 1 ;
if sequenceName == " temp " then
f.sequence = self.tempEnchantSequence ;
f.forceRefresh = true ;
else
f.sequence = self.refreshSequence ;
f.forceRefresh = false ;
end
f : Show ( ) ;
end
function SlotController : PlayAnimOut ( )
if not InCombatLockdown ( ) and Narci_Character : IsShown ( ) then
for slotID , slotButton in pairs ( slotTable ) do
slotButton.animOut : Play ( ) ;
end
Narci_Character.animOut : Play ( ) ;
end
end
function SlotController : IsMouseOver ( )
for slotID , slotButton in pairs ( slotTable ) do
if slotButton : IsMouseOver ( ) then
return true
end
end
return false
end
local function CacheSourceInfo ( slotID )
local appliedSourceID , appliedVisualID ;
if slotID then
After ( AssignDelay ( slotID , true ) , function ( )
appliedSourceID , appliedVisualID = GetSlotVisualID ( slotID ) ;
if appliedVisualID > 0 then
local sourceInfo = C_TransmogCollection.GetSourceInfo ( appliedSourceID ) ;
local sources = C_TransmogCollection.GetAppearanceSources ( appliedVisualID ) ;
if slotTable [ slotID ] then
local slot = slotTable [ slotID ] ;
slot.sourceInfo = sourceInfo ;
slot.appliedVisualID = appliedVisualID ;
local _ , sourceID = C_TransmogCollection.GetItemInfo ( sourceInfo.itemID , sourceInfo.itemModID ) ;
if sourceInfo and sourceInfo.sourceType == 1 then
slot.drops = C_TransmogCollection.GetAppearanceSourceDrops ( sourceID ) ;
end
end
--print("Caching Slot... #"..slotID)
end
end )
else
for id , slotButton in pairs ( slotTable ) do
appliedSourceID , appliedVisualID = GetSlotVisualID ( id ) ;
if appliedVisualID > 0 then
local sourceInfo = C_TransmogCollection.GetSourceInfo ( appliedSourceID ) ;
local sources = C_TransmogCollection.GetAppearanceSources ( appliedVisualID ) ;
end
end
end
end
------------------------------------------------------------------
-----Some of the codes are derivated from EquipmentFlyout.lua-----
------------------------------------------------------------------
NarciEquipmentFlyoutButtonMixin = CreateFromMixins { NarciItemButtonSharedMixin } ;
function NarciEquipmentFlyoutButtonMixin : OnClick ( button , down , isGamepad )
if button == " LeftButton " then
local action = EquipmentManager_EquipItemByLocation ( self.location , self.slotID )
if action then
self : RegisterErrorEvent ( ) ;
Narci_AlertFrame_Autohide : SetAnchor ( self , - 24 , true ) ;
EquipmentManager_RunAction ( action )
end
self : Disable ( ) ;
if isGamepad then
EquipmentFlyoutFrame.gamepadButton = self ;
end
end
end
function NarciEquipmentFlyoutButtonMixin : OnLeave ( )
FadeFrame ( self.Highlight , 0.25 , 0 ) ;
Narci : HideButtonTooltip ( ) ;
self : ResetAnimation ( ) ;
end
function NarciEquipmentFlyoutButtonMixin : OnEnter ( motion , isGamepad )
FadeFrame ( self.Highlight , 0.15 , 1 ) ;
Narci_Comparison_SetComparison ( self.itemLocation , self ) ;
if isGamepad then
self.Icon . scaleUp : Play ( ) ;
self.Border . scaleUp : Play ( ) ;
self.IconMask . scaleUp : Play ( ) ;
end
end
function NarciEquipmentFlyoutButtonMixin : OnEvent ( event , ... )
if event == " UI_ERROR_MESSAGE " then
self : OnErrorMessage ( ... ) ;
end
end
function NarciEquipmentFlyoutButtonMixin : SetUp ( maxItemLevel )
self.FlyUp : Stop ( ) ;
local itemLocation = self.itemLocation ;
self.hyperlink = C_Item.GetItemLink ( itemLocation )
if ( not itemLocation ) then
return ;
end
local itemID = C_Item.GetItemID ( itemLocation ) ;
local itemQuality = C_Item.GetItemQuality ( itemLocation ) ;
local itemLevel = C_Item.GetCurrentItemLevel ( itemLocation ) ;
local itemIcon = C_Item.GetItemIcon ( itemLocation ) ;
local itemLink = C_Item.GetItemLink ( itemLocation )
if C_AzeriteEmpoweredItem.IsAzeriteEmpoweredItem ( itemLocation ) then
itemQuality = " Azerite " ; --AzeriteEmpoweredItem
elseif C_AzeriteItem.IsAzeriteItem ( itemLocation ) then
itemQuality = " Heart " ;
elseif IsCorruptedItem ( itemLink ) then
itemQuality = " NZoth " ;
elseif C_LegendaryCrafting.IsRuneforgeLegendary ( itemLocation ) then
itemQuality = " Runeforge " ;
end
itemQuality = GetBorderArtByItemID ( itemID ) or itemQuality ;
if maxItemLevel and itemLevel < maxItemLevel then
itemQuality = 0 ;
self.Icon : SetDesaturated ( true ) ;
else
self.Icon : SetDesaturated ( false ) ;
end
self.Icon : SetTexture ( itemIcon )
--self.Border:SetTexture(BorderTexture[itemQuality])
self : SetBorderTexture ( self.Border , itemQuality ) ;
self.ItemLevelCenter . ItemLevel : SetText ( itemLevel ) ;
self.ItemLevelCenter : Show ( ) ;
if itemLink then
DisplayRuneSlot ( self , self.slotID , itemQuality , itemLink ) ;
end
end
function NarciEquipmentFlyoutButtonMixin : HideButton ( )
self : Hide ( ) ;
self.location = nil ;
self.hyperlink = nil ;
end
local function ShowLessItemInfo ( self , bool )
if bool then
self.Name : Hide ( ) ;
self.ItemLevel : Hide ( ) ;
self.ItemLevelCenter : Show ( ) ;
else
self.Name : Show ( ) ;
self.ItemLevel : Show ( ) ;
self.ItemLevelCenter : Hide ( ) ;
end
end
local function ShowAllItemInfo ( )
if xmogMode ~= 0 then
return ;
end
local level = Narci_FlyoutBlack : GetFrameLevel ( ) - 1 ;
for slotID , slotButton in pairs ( slotTable ) do
ShowLessItemInfo ( slotButton , false ) ;
slotButton : SetFrameLevel ( level - 1 )
slotButton.RuneSlot : SetFrameLevel ( level )
end
end
NarciEquipmentFlyoutFrameMixin = { } ;
function NarciEquipmentFlyoutFrameMixin : OnLoad ( )
EquipmentFlyoutFrame = self ;
self.buttons = { } ;
self.slotID = - 1 ;
self.itemSortFunc = function ( a , b )
return tonumber ( a.level ) > tonumber ( b.level )
end
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciEquipmentFlyoutFrameMixin : OnHide ( )
ShowAllItemInfo ( ) ;
self.slotID = - 1 ;
self : UnregisterEvent ( " MODIFIER_STATE_CHANGED " ) ;
self : UnregisterEvent ( " GLOBAL_MOUSE_DOWN " ) ;
self.Arrow : Hide ( ) ;
self : StopAnimating ( ) ;
if Narci_Character.animOut : IsPlaying ( ) then return ; end
Narci_FlyoutBlack : Out ( ) ;
end
function NarciEquipmentFlyoutFrameMixin : OnShow ( )
self : RegisterEvent ( " MODIFIER_STATE_CHANGED " ) ;
self : RegisterEvent ( " GLOBAL_MOUSE_DOWN " ) ;
self.Arrow . anim : Play ( ) ;
end
function NarciEquipmentFlyoutFrameMixin : OnEvent ( event , ... ) --Hide Flyout if Left-Alt is released
if ( event == " MODIFIER_STATE_CHANGED " ) then
local key , state = ... ;
if ( key == " LALT " ) then
local flyout = EquipmentFlyoutFrame
if state == 0 and flyout : IsShown ( ) then
flyout : Hide ( )
end
end
elseif ( event == " GLOBAL_MOUSE_DOWN " ) then
if not self : IsMouseOverButtons ( ) then
self : Hide ( ) ;
end
end
end
function NarciEquipmentFlyoutFrameMixin : SetItemSlot ( slotButton , showArrow )
if MOG_MODE then
return ;
end
local slotID = slotButton.slotID ;
if ( slotID == - 1 or ( self : IsShown ( ) and self.parentButton and self.parentButton . slotID == slotID ) ) and ( not IsAltKeyDown ( ) ) then
self : Hide ( ) ;
return ;
end
if self.parentButton then
local level = Narci_FlyoutBlack : GetFrameLevel ( ) - 1
self.parentButton : SetFrameLevel ( level - 1 ) ;
self.parentButton . RuneSlot : SetFrameLevel ( level ) ;
ShowLessItemInfo ( self.parentButton , false ) ;
end
self.parentButton = slotButton ;
self : DisplayItemsBySlotID ( slotID , self.slotID ~= slotID ) ;
self.slotID = slotID ;
self : SetParent ( slotButton ) ;
self : ClearAllPoints ( ) ;
if slotButton.isRight then
self : SetPoint ( " TOPRIGHT " , slotButton , " TOPLEFT " , 0 , 0 ) ; --EquipmentFlyout's Position
else
self : SetPoint ( " TOPLEFT " , slotButton , " TOPRIGHT " , 0 , 0 ) ;
end
--Unequip Arrow
self.Arrow : ClearAllPoints ( ) ;
self.Arrow : SetPoint ( " TOP " , slotButton , " TOP " , 0 , 8 ) ;
if showArrow then
self.Arrow : Show ( ) ;
end
Narci_FlyoutBlack : In ( ) ;
slotButton : SetFrameLevel ( Narci_FlyoutBlack : GetFrameLevel ( ) + 1 )
self : SetFrameLevel ( 20 ) ;
Narci : HideButtonTooltip ( ) ;
ShowLessItemInfo ( slotButton , true )
--Reposition Comparison Tooltip if it reaches the top of the screen--
local Tooltip = Narci_Comparison ;
Tooltip : ClearAllPoints ( ) ;
Tooltip : SetPoint ( " BOTTOMLEFT " , self , " TOPLEFT " , 8 , 12 ) ;
if slotButton : GetTop ( ) > Tooltip : GetBottom ( ) then
Tooltip : ClearAllPoints ( ) ;
Tooltip : SetPoint ( " TOPLEFT " , self , " BOTTOMLEFT " , 8 , - 12 ) ;
end
Narci_Comparison_SetComparison ( self.BaseItem , slotButton ) ;
Tooltip : Show ( ) ;
end
function NarciEquipmentFlyoutFrameMixin : CreateItemButton ( )
local perRow = 5 ; --EQUIPMENTFLYOUT_ITEMS_PER_ROW
local buttons = self.buttons ;
local numButtons = # buttons ;
local button = CreateFrame ( " Button " , nil , self.ButtonFrame , " NarciEquipmentFlyoutButtonTemplate " ) ;
button : SetFrameStrata ( " DIALOG " ) ;
local row = floor ( numButtons / perRow ) ;
local col = numButtons - row * perRow ;
button : SetPoint ( " TOPLEFT " , self , " TOPLEFT " , 70 * col , - 74 * row ) ;
tinsert ( buttons , button ) ;
button.FlyUp . Move : SetStartDelay ( numButtons / 25 ) ;
button.FlyUp . Fade : SetStartDelay ( numButtons / 25 ) ;
return button
end
function NarciEquipmentFlyoutFrameMixin : DisplayItemsBySlotID ( slotID , playFlyUpAnimation )
local LoadItemData = C_Item.RequestLoadItemData ; --Cache Item Info
local id = slotID or self.slotID ;
if not id or id <= 0 then
return
end
self : Show ( ) ;
local baseItemLevel ;
local bastItemLocation = ItemLocation : CreateFromEquipmentSlot ( id ) ;
if C_Item.DoesItemExist ( bastItemLocation ) then
baseItemLevel = C_Item.GetCurrentItemLevel ( bastItemLocation ) ;
else
baseItemLevel = 0 ;
end
self.BaseItem = bastItemLocation ;
local buttons = self.buttons ;
--Get the items from bags;
local itemTable = { } ;
local sortedItems = { } ;
GetInventoryItemsForSlot ( id , itemTable ) ;
local itemLocation , itemLevel , itemInfo ;
local invLocationPlayer = ITEM_INVENTORY_LOCATION_PLAYER ;
for location , hyperlink in pairs ( itemTable ) do
if ( location - id == invLocationPlayer ) then -- Remove the currently equipped item from the list
itemTable [ location ] = nil ;
else
local _ , _ , bags , _ , slot , bag = EquipmentManager_UnpackLocation ( location ) ;
if bags then
itemLocation = ItemLocation : CreateFromBagAndSlot ( bag , slot ) ;
itemLevel = C_Item.GetCurrentItemLevel ( itemLocation ) ;
NarciCacheTooltip : SetHyperlink ( hyperlink ) ;
LoadItemData ( itemLocation ) ;
itemInfo = { level = itemLevel , itemLocation = itemLocation , location = location } ;
tinsert ( sortedItems , itemInfo ) ;
end
end
end
table.sort ( sortedItems , self.itemSortFunc ) ; --Sorted by item level
local numTotalItems = # sortedItems ;
local buttonWidth , buttonHeight = self.parentButton : GetWidth ( ) , self.parentButton : GetHeight ( ) ;
buttonWidth , buttonHeight = floor ( buttonWidth + 0.5 ) , floor ( buttonHeight + 0.5 ) ;
local borderSize = self.parentButton . Border : GetSize ( ) ;
borderSize = floor ( borderSize + 0.5 ) ;
self : SetWidth ( max ( buttonWidth , math.min ( numTotalItems , 5 ) * buttonWidth ) ) ;
local numDisplayedItems = math.min ( numTotalItems , 20 ) ; --EQUIPMENTFLYOUT_ITEMS_PER_PAGE
self : SetHeight ( max ( floor ( ( numDisplayedItems - 1 ) / 5 + 1 ) * buttonHeight , buttonHeight ) ) ;
local gamepadButton = self.gamepadButton ;
self.gamepadButton = nil ;
baseItemLevel = baseItemLevel - 14 ; --darken button if the item level is lower than the base
local button ;
for i = 1 , numDisplayedItems do
button = buttons [ i ] ;
if not button then
button = self : CreateItemButton ( ) ;
end
button.itemLocation = sortedItems [ i ] . itemLocation ;
button.location = sortedItems [ i ] . location ;
button.slotID = id ;
button : SetUp ( baseItemLevel ) ;
button : Show ( ) ;
button : SetSize ( buttonWidth , buttonHeight ) ;
button.Border : SetSize ( borderSize , borderSize ) ;
button : Enable ( ) ;
if button == gamepadButton then
Narci_Comparison_SetComparison ( gamepadButton.itemLocation , gamepadButton ) ;
Narci_GamepadOverlayContainer.SlotBorder : UpdateQualityColor ( gamepadButton ) ;
end
end
for i = numDisplayedItems + 1 , # buttons do
buttons [ i ] : HideButton ( ) ;
end
if playFlyUpAnimation then
for i = 1 , numDisplayedItems do
buttons [ i ] . FlyUp : Play ( ) ;
end
end
self.numDisplayedItems = numDisplayedItems ; --For gamepad to cycle
end
function NarciEquipmentFlyoutFrameMixin : IsMouseOverButtons ( )
for i = 1 , # self.buttons do
if self.buttons [ i ] : IsShown ( ) and self.buttons [ i ] : IsMouseOver ( ) then
return true ;
end
end
if self.parentButton : IsMouseOver ( ) then
return true
end
if SlotController : IsMouseOver ( ) then
return true
end
return false
end
-----------------------------------------------------------
------------------------Color Theme------------------------
-----------------------------------------------------------
local ColorUtil = { } ;
ColorUtil.themeColor = NarciThemeUtil : GetColorTable ( ) ;
function ColorUtil : UpdateByMapID ( )
local mapID = C_Map.GetBestMapForUnit ( " player " ) ;
--print("mapID:".. mapID)
if mapID then --and NarcissusDB.AutoColorTheme
if mapID == self.mapID then
self.requireUpdate = false ;
else
self.mapID = mapID ;
self.requireUpdate = true ;
self.themeColor = NarciThemeUtil : SetColorIndex ( mapID ) ;
RadarChart : UpdateColor ( ) ;
Narci_NavBar : SetThemeColor ( self.themeColor ) ;
end
else
self.requireUpdate = false ;
end
end
function ColorUtil : SetWidgetColor ( frame )
if not self.requireUpdate then return end ;
local r , g , b = self.themeColor [ 1 ] , self.themeColor [ 2 ] , self.themeColor [ 3 ] ;
local type = frame : GetObjectType ( ) ;
if type == " FontString " then
local sqrt = math.sqrt ;
r , g , b = sqrt ( r ) , sqrt ( g ) , sqrt ( b ) ;
frame : SetTextColor ( r , g , b ) ;
else
frame : SetColorTexture ( r , g , b ) ;
end
end
---------------------------------------------
NarciRadarChartMixin = { }
function NarciRadarChartMixin : OnLoad ( )
RadarChart = self ;
local circleTex = " Interface \\ AddOns \\ Narcissus \\ Art \\ Widgets \\ RadarChart \\ Radar-Vertice " ;
local filter = " TRILINEAR " ;
local tex ;
local texs = { } ;
for i = 1 , 4 do
tex = self : CreateTexture ( nil , " OVERLAY " , nil , 2 ) ;
tinsert ( texs , tex ) ;
tex : SetSize ( 12 , 12 ) ;
tex : SetTexture ( circleTex , nil , nil , filter ) ;
end
self.vertices = texs ;
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciRadarChartMixin : OnShow ( )
self.MaskedBackground : SetAlpha ( 0.4 ) ;
self.MaskedBackground2 : SetAlpha ( 0.4 ) ;
end
function NarciRadarChartMixin : OnHide ( )
self : StopAnimating ( ) ;
end
function NarciRadarChartMixin : SetVerticeSize ( attributeFrame , size )
local name = attributeFrame.token ;
local vertice ;
if name == " Crit " then
vertice = self.vertices [ 1 ] ;
elseif name == " Haste " then
vertice = self.vertices [ 2 ] ;
elseif name == " Mastery " then
vertice = self.vertices [ 3 ] ;
elseif name == " Versatility " then
vertice = self.vertices [ 4 ] ;
end
vertice : SetSize ( size , size ) ;
end
function NarciRadarChartMixin : UpdateColor ( )
ColorUtil : SetWidgetColor ( self.MaskedBackground )
ColorUtil : SetWidgetColor ( self.MaskedBackground2 )
ColorUtil : SetWidgetColor ( self.MaskedLine1 )
ColorUtil : SetWidgetColor ( self.MaskedLine2 )
ColorUtil : SetWidgetColor ( self.MaskedLine3 )
ColorUtil : SetWidgetColor ( self.MaskedLine4 )
end
local GetEffectiveCrit = Narci.GetEffectiveCrit ;
function NarciRadarChartMixin : SetValue ( c , h , m , v , manuallyInPutSum )
--c, h, m, v: Input manually or use combat ratings
local deg = math.deg ;
local rad = math.rad ;
local atan2 = math.atan2 ;
local sqrt = math.sqrt ;
local Radar = self ;
local chartWidth = 96 / 2 ; --In half
local crit , haste , mastery , versatility ;
if c then
crit = c ;
else
local _ , rating = GetEffectiveCrit ( ) ;
crit = GetCombatRating ( rating ) or 0 ;
end
if h then
haste = h ;
else
h = GetCombatRating ( CR_HASTE_MELEE ) or 0 ;
end
if m then
mastery = m ;
else
m = GetCombatRating ( CR_MASTERY ) or 0 ;
end
if v then
versatility = v ;
else
versatility = GetCombatRating ( CR_VERSATILITY_DAMAGE_DONE ) or 0 ;
end
-- | p1(x1,y1) Line4 p3(x3,y3)
-- | * *
-- | * *
-- | Line1 * Line3
-- | * *
-- | * *
-- | p2(x2,y2) Line2 p4(x4,y4)
local v1 , v2 , v3 , v4 , v5 , v6 = true , true , true , true , true , true ;
if crit == 0 and haste == 0 and mastery == 0 and versatility == 0 then
v1 , v2 , v3 , v4 , v5 , v6 = false , false , false , false , false , false ;
else
if crit == 0 and haste == 0 then v1 = false ; end ;
if haste == 0 and versatility == 0 then v2 = false ; end ;
if mastery == 0 and versatility == 0 then v3 = false ; end ;
if crit == 0 and mastery == 0 then v4 = false ; end ;
crit , haste , mastery = crit + 0.03 , haste + 0.02 , mastery + 0.01 ; --Avoid some mathematical issues
end
Radar.MaskedLine1 : SetShown ( v1 ) ;
Radar.MaskedLine2 : SetShown ( v2 ) ;
Radar.MaskedLine3 : SetShown ( v3 ) ;
Radar.MaskedLine4 : SetShown ( v4 ) ;
Radar.MaskedBackground : SetShown ( v5 ) ;
Radar.MaskedBackground2 : SetShown ( v6 ) ;
--[[
--4500 9.0 Stats Sum Level 50
Enchancements on ilvl 445 ( Mythic Eternal Palace ) Player Lvl 120
Neck 159 Weapon 25 Back 51 Wrist 28 Hands 37 Waist 36 Legs 50 Feet 37 Ring 89 Trinket 35 Max : 696 + 12 * 7 ~= 800
Player Lvl 60 iLvl 233 ( Mythic Castle Nathria ) : Back 82 Leg 141 Chest 141 Neck 214 Waist 105 Hand 105 Feet 105 Wrist 79 Ring 226 Shoulder 109 Head 146 Trinket 200 ~= 1900
Player Lvl 60 iLvl 259 ( Mythic Sanctum of Domination ) : Back 90 Leg 165 Chest 165 Neck 268 Waist 124 Hand 130 Feet 124 Wrist 91 Ring 268 Shoulder 124 Head 146 Trinket 200 weapon 162 ~= 2500 ( + 8 sockets )
ilvl 240 ( Mythic Antorus ) Player Lvl 110
Head 87 Shoulder 64 Chest 88 Weapon 152 Back 49 Wrist 49 Hands 64 Waist 64 Legs 87 Feet 63 Ring 165 Trinket 62 Max ~= 1100
ilvl 149 ( Mythic HFC ) Player Lvl 100
Head 48 Shoulder 36 Chest 48 Weapon 24 Back 28 Wrist 27 Hands 36 Waist 36 Legs 48 Feet 35 Ring 27 Trinket 32 Max ~= 510
Heirlooms Player Lvl 20
Weapon 4 Back 4 Wrist 4 Hands 6 Waist 6 Legs 8 Feet 6 Ring 5 Trinket 6 ~= 60
--]]
local Sum = manuallyInPutSum or 0 ;
local maxNum = max ( crit + haste + mastery + versatility , 1 ) ;
if maxNum > 0.95 * Sum then
Sum = maxNum ;
end
local d1 , d2 , d3 , d4 = ( crit / Sum ) , ( haste / Sum ) , ( mastery / Sum ) , ( versatility / Sum ) ;
local a ;
if ( d1 + d4 ) ~= 0 and ( d2 + d3 ) ~= 0 then
--a = chartWidth * math.sqrt(0.618/(d1 + d4)/(d2 + d3)/2)* 96;
a = 1.414 * chartWidth ;
else
a = 0 ;
end
local x1 , x2 , x3 , x4 = - d1 * a , - d2 * a , d3 * a , d4 * a ;
local y1 , y2 , y3 , y4 = d1 * a , - d2 * a , d3 * a , - d4 * a ;
local mx1 , mx2 , mx3 , mx4 = ( x1 + x2 ) / 2 , ( x2 + x4 ) / 2 , ( x3 + x4 ) / 2 , ( x1 + x3 ) / 2 ;
local my1 , my2 , my3 , my4 = ( y1 + y2 ) / 2 , ( y2 + y4 ) / 2 , ( y3 + y4 ) / 2 , ( y1 + y3 ) / 2 ;
local ma1 = atan2 ( ( y1 - y2 ) , ( x1 - x2 ) ) ;
local ma2 = atan2 ( ( y2 - y4 ) , ( x2 - x4 ) ) ;
local ma3 = atan2 ( ( y4 - y3 ) , ( x4 - x3 ) ) ;
local ma4 = atan2 ( ( y3 - y1 ) , ( x3 - x1 ) ) ;
if my1 == 0 then
my1 = 0.01 ;
end
if my3 == 0 then
my1 = - 0.01 ;
end
if deg ( ma1 ) == 90 then
ma1 = rad ( 89 ) ;
end
if deg ( ma3 ) == - 90 then
ma1 = rad ( - 89 ) ;
end
Radar.vertices [ 1 ] : SetPoint ( " CENTER " , x1 , y1 ) ;
Radar.vertices [ 2 ] : SetPoint ( " CENTER " , x2 , y2 ) ;
Radar.vertices [ 3 ] : SetPoint ( " CENTER " , x3 , y3 ) ;
Radar.vertices [ 4 ] : SetPoint ( " CENTER " , x4 , y4 ) ;
Radar.Mask1 : SetRotation ( ma1 ) ;
Radar.Mask2 : SetRotation ( ma2 ) ;
Radar.Mask3 : SetRotation ( ma3 ) ;
Radar.Mask4 : SetRotation ( ma4 ) ;
local hypo1 = sqrt ( 2 * x1 ^ 2 + 2 * x2 ^ 2 ) ;
local hypo2 = sqrt ( 2 * x2 ^ 2 + 2 * x4 ^ 2 ) ;
local hypo3 = sqrt ( 2 * x4 ^ 2 + 2 * x3 ^ 2 ) ;
local hypo4 = sqrt ( 2 * x3 ^ 2 + 2 * x1 ^ 2 ) ;
if ( hypo1 - 4 ) > 0 then
Radar.MaskLine1 : SetWidth ( hypo1 - 4 ) ; --Line length
else
Radar.MaskLine1 : SetWidth ( 0.1 ) ;
end
if ( hypo2 - 4 ) > 0 then
Radar.MaskLine2 : SetWidth ( hypo2 - 4 ) ;
else
Radar.MaskLine2 : SetWidth ( 0.1 ) ;
end
if ( hypo3 - 4 ) > 0 then
Radar.MaskLine3 : SetWidth ( hypo3 - 4 ) ;
else
Radar.MaskLine3 : SetWidth ( 0.1 ) ;
end
if ( hypo4 - 4 ) > 0 then
Radar.MaskLine4 : SetWidth ( hypo4 - 4 ) ;
else
Radar.MaskLine4 : SetWidth ( 0.1 ) ;
end
Radar.MaskLine1 : ClearAllPoints ( ) ;
Radar.MaskLine1 : SetRotation ( 0 ) ;
Radar.MaskLine1 : SetRotation ( ma1 ) ;
Radar.MaskLine1 : SetPoint ( " CENTER " , Radar , " CENTER " , mx1 , my1 ) ;
Radar.MaskLine2 : ClearAllPoints ( ) ;
Radar.MaskLine2 : SetRotation ( 0 ) ;
Radar.MaskLine2 : SetRotation ( ma2 ) ;
Radar.MaskLine2 : SetPoint ( " CENTER " , Radar , " CENTER " , mx2 , my2 ) ;
Radar.MaskLine3 : ClearAllPoints ( ) ;
Radar.MaskLine3 : SetRotation ( 0 ) ;
Radar.MaskLine3 : SetRotation ( ma3 ) ;
Radar.MaskLine3 : SetPoint ( " CENTER " , Radar , " CENTER " , mx3 , my3 ) ;
Radar.MaskLine4 : ClearAllPoints ( ) ;
Radar.MaskLine4 : SetRotation ( 0 ) ;
Radar.MaskLine4 : SetRotation ( ma4 ) ;
Radar.MaskLine4 : SetPoint ( " CENTER " , Radar , " CENTER " , mx4 , my4 ) ;
Radar.Mask1 : SetPoint ( " CENTER " , mx1 , my1 ) ;
Radar.Mask2 : SetPoint ( " CENTER " , mx2 , my2 ) ;
Radar.Mask3 : SetPoint ( " CENTER " , mx3 , my3 ) ;
Radar.Mask4 : SetPoint ( " CENTER " , mx4 , my4 ) ;
Radar.MaskedBackground : SetAlpha ( 0.4 ) ;
Radar.MaskedBackground2 : SetAlpha ( 0.4 ) ;
Radar.n1 , Radar.n2 , Radar.n3 , Radar.n4 = crit , haste , mastery , versatility ;
end
function NarciRadarChartMixin : AnimateValue ( c , h , m , v )
--Update the radar chart using animation
local Radar = self ;
local UpdateFrame = Radar.UpdateFrame ;
if not UpdateFrame then
UpdateFrame = CreateFrame ( " Frame " , nil , Radar , " NarciUpdateFrameTemplate " ) ;
Radar.UpdateFrame = UpdateFrame ;
Radar.n1 , Radar.n2 , Radar.n3 , Radar.n4 = 0 , 0 , 0 , 0 ;
end
local s1 , s2 , s3 , s4 = Radar.n1 , Radar.n2 , Radar.n3 , Radar.n4 ; --start/end point
local critChance , critRating = GetEffectiveCrit ( ) ;
local e1 = c or GetCombatRating ( critRating ) or 0 ;
local e2 = h or GetCombatRating ( CR_HASTE_MELEE ) or 0 ;
local e3 = m or GetCombatRating ( CR_MASTERY ) or 0 ;
local e4 = v or GetCombatRating ( CR_VERSATILITY_DAMAGE_DONE ) or 0 ;
local duration = 0.2 ;
local playerLevel = UnitLevel ( " player " ) ;
local sum ;
if playerLevel == 50 then
sum = max ( e1 + e2 + e3 + e4 , 800 ) ; --Status Sum for 8.3 Raid
elseif playerLevel == 60 then
sum = max ( e1 + e2 + e3 + e4 , 2500 ) ; --Status Sum for 9.1 Raid
else
--sum = 31 * math.exp( 0.04 * UnitLevel("player")) + 40;
sum = ( e1 + e2 + e3 + e4 ) * 1.5 ;
end
local function UpdateFunc ( frame , elapsed )
local t = frame.t ;
frame.t = t + elapsed ;
local v1 = outSine ( t , s1 , e1 , duration ) ;
local v2 = outSine ( t , s2 , e2 , duration ) ;
local v3 = outSine ( t , s3 , e3 , duration ) ;
local v4 = outSine ( t , s4 , e4 , duration ) ;
if t >= duration then
v1 , v2 , v3 , v4 = e1 , e2 , e3 , e4 ;
frame : Hide ( ) ;
end
Radar : SetValue ( v1 , v2 , v3 , v4 , sum ) ;
end
UpdateFrame : Hide ( ) ;
UpdateFrame : SetScript ( " OnUpdate " , UpdateFunc ) ;
UpdateFrame : Show ( ) ;
if self.Primary : IsShown ( ) then
self.Primary : Update ( ) ;
self.Health : Update ( ) ;
end
end
function NarciRadarChartMixin : TogglePrimaryStats ( state )
state = false ;
if state then
self.Primary . Color : SetColorTexture ( 0.24 , 0.24 , 0.24 , 0.75 ) ;
self.Health . Color : SetColorTexture ( 0.15 , 0.15 , 0.15 , 0.75 ) ;
FadeFrame ( self.Primary , 0.15 , 1 ) ;
FadeFrame ( self.Health , 0.15 , 1 ) ;
self.Primary : Update ( ) ;
self.Health : Update ( ) ;
else
FadeFrame ( self.Primary , 0.25 , 0 ) ;
FadeFrame ( self.Health , 0.25 , 0 ) ;
end
end
function Narci_AttributeFrame_UpdateBackgroundColor ( self )
local frameID = self : GetID ( ) or 0 ;
local themeColor = ColorUtil.themeColor ;
local r , g , b = themeColor [ 1 ] , themeColor [ 2 ] , themeColor [ 3 ] ;
if frameID % 2 == 0 then
if self.Color then
self.Color : SetColorTexture ( r , g , b , 0.75 ) ;
return ;
elseif self.Color1 and self.Color2 then
self.Color1 : SetColorTexture ( r , g , b , 0.75 ) ;
self.Color2 : SetColorTexture ( r , g , b , 0.75 ) ;
end
else
if self.Color then
self.Color : SetColorTexture ( 0.1 , 0.1 , 0.1 , 0.75 ) ;
return ;
elseif self.Color1 and self.Color2 then
self.Color1 : SetColorTexture ( 0.1 , 0.1 , 0.1 , 0.75 ) ;
self.Color2 : SetColorTexture ( 0.1 , 0.1 , 0.1 , 0.75 ) ;
end
end
end
function Narci_AttributeFrame_OnLoad ( self )
Narci_AttributeFrame_UpdateBackgroundColor ( self ) ;
end
function XmogList_OnLoad ( self )
Narci_AttributeFrame_UpdateBackgroundColor ( self ) ;
end
local function RefreshStats ( id , frame )
frame = frame or " Detailed " ;
if frame == " Detailed " then
if statTable [ id ] then
statTable [ id ] : Update ( ) ;
end
elseif frame == " Concise " then
if statTable_Short [ id ] then
statTable_Short [ id ] : Update ( ) ;
end
end
end
local StatsUpdator = CreateFrame ( " Frame " ) ;
StatsUpdator : Hide ( ) ;
StatsUpdator.t = 0 ;
StatsUpdator.index = 1 ;
StatsUpdator : SetScript ( " OnUpdate " , function ( self , elapsed )
self.t = self.t + elapsed ;
if self.t > 0.05 then
self.t = 0 ;
local i = self.index ;
if statTable [ i ] then
statTable [ i ] : Update ( ) ;
end
if statTable_Short [ i ] then
statTable_Short [ i ] : Update ( ) ;
end
if i >= 20 then
self : Hide ( ) ;
self.index = 1 ;
else
self.index = i + 1 ;
end
end
end ) ;
function StatsUpdator : Gradual ( )
ItemLevelFrame : Update ( ) ;
ItemLevelFrame : UpdateDomination ( ) ;
self.index = 1 ;
self.t = 0 ;
self : Show ( ) ;
end
function StatsUpdator : Instant ( )
if not StatsUpdator.pauseUpdate then
StatsUpdator.pauseUpdate = true ;
After ( 0 , function ( )
for i = 1 , 20 do
RefreshStats ( i ) ;
end
for i = 1 , 12 do
RefreshStats ( i , " Concise " ) ;
end
StatsUpdator.pauseUpdate = nil ;
end ) ;
end
end
function StatsUpdator : UpdateCooldown ( )
for slotID , slotButton in pairs ( slotTable ) do
slotButton : TrackCooldown ( ) ;
end
end
local function PlayAttributeAnimation ( )
if not NarcissusDB.DetailedIlvlInfo then
RadarChart : AnimateValue ( ) ;
return
end
if not RadarChart : IsShown ( ) then
return --Attributes is not the active tab
end
local anim ;
for i = 1 , 20 do
anim = statTable [ i ] . animIn ;
if anim then
anim.A2 : SetToAlpha ( statTable [ i ] : GetAlpha ( ) ) ;
anim : Play ( ) ;
end
end
RadarChart.animIn : Play ( ) ;
end
local function ShowAttributeButton ( bool )
if NarcissusDB.DetailedIlvlInfo then
Narci_DetailedStatFrame : SetShown ( true ) ;
Narci_ConciseStatFrame : SetShown ( false ) ;
RadarChart : SetShown ( true ) ;
else
Narci_DetailedStatFrame : SetShown ( false ) ;
Narci_ConciseStatFrame : SetShown ( true ) ;
RadarChart : SetShown ( false ) ;
end
ItemLevelFrame : SetShown ( true ) ;
end
local function AssignFrame ( )
Narci.slotTable = slotTable ;
local statFrame = Narci_DetailedStatFrame ;
local radar = RadarChart ;
statTable [ 1 ] = statFrame.Primary ;
statTable [ 2 ] = statFrame.Stamina ;
statTable [ 3 ] = statFrame.Damage ;
statTable [ 4 ] = statFrame.AttackSpeed ;
statTable [ 5 ] = statFrame.Power ;
statTable [ 6 ] = statFrame.Regen ;
statTable [ 7 ] = statFrame.Health ;
statTable [ 8 ] = statFrame.Armor ;
statTable [ 9 ] = statFrame.Reduction ;
statTable [ 10 ] = statFrame.Dodge ;
statTable [ 11 ] = statFrame.Parry ;
statTable [ 12 ] = statFrame.Block ;
statTable [ 13 ] = radar.Crit ;
statTable [ 14 ] = radar.Haste ;
statTable [ 15 ] = radar.Mastery ;
statTable [ 16 ] = radar.Versatility ;
statTable [ 17 ] = statFrame.Leech ;
statTable [ 18 ] = statFrame.Avoidance ;
statTable [ 19 ] = statFrame.MovementSpeed ;
statTable [ 20 ] = statFrame.Speed ;
local statFrame_Short = Narci_ConciseStatFrame ;
statTable_Short [ 1 ] = statFrame_Short.Primary ;
statTable_Short [ 2 ] = statFrame_Short.Stamina ;
statTable_Short [ 3 ] = statFrame_Short.Health ;
statTable_Short [ 4 ] = statFrame_Short.Power ;
statTable_Short [ 5 ] = statFrame_Short.Regen ;
statTable_Short [ 6 ] = statFrame_Short.Crit ;
statTable_Short [ 7 ] = statFrame_Short.Haste ;
statTable_Short [ 8 ] = statFrame_Short.Mastery ;
statTable_Short [ 9 ] = statFrame_Short.Versatility ;
statTable_Short [ 10 ] = statFrame_Short.Leech ;
statTable_Short [ 11 ] = statFrame_Short.Avoidance ;
statTable_Short [ 12 ] = statFrame_Short.Speed ;
end
function Narci_SetPlayerName ( self )
local playerName = UnitName ( " player " ) ;
self.PlayerName : SetShadowColor ( 0 , 0 , 0 ) ;
self.PlayerName : SetShadowOffset ( 2 , - 2 ) ;
self.PlayerName : SetText ( playerName ) ;
SmartFontType ( self.PlayerName ) ;
end
function Narci_AliasButton_SetState ( )
local editBox = Narci_PlayerInfoFrame.PlayerName ;
local button = Narci_AliasButton ;
if NarcissusDB_PC.UseAlias then
editBox : Enable ( ) ;
editBox : SetText ( ( NarcissusDB_PC.PlayerAlias or UnitName ( " player " ) ) ) ;
button.Label : SetText ( L [ " Use Player Name " ] ) ;
else
editBox : Disable ( ) ;
editBox : SetText ( UnitName ( " player " ) ) ;
button.Label : SetText ( L [ " Use Alias " ] ) ;
end
local LetterNum = editBox : GetNumLetters ( ) ;
local w = max ( LetterNum * 16 , 160 ) ;
editBox : SetWidth ( w ) ;
button : SetWidth ( button.Label : GetWidth ( ) + 12 ) ;
end
function Narci_AliasButton_OnClick ( self )
local editBox = Narci_PlayerInfoFrame.PlayerName ;
NarcissusDB_PC.UseAlias = not NarcissusDB_PC.UseAlias ;
if NarcissusDB_PC.UseAlias then
self.Label : SetText ( L [ " Use Player Name " ] ) ;
editBox : Enable ( ) ;
editBox : SetFocus ( ) ;
editBox : SetText ( NarcissusDB_PC.PlayerAlias or UnitName ( " player " ) ) ;
editBox : HighlightText ( ) ;
else
self.Label : SetText ( L [ " Use Alias " ] ) ;
local text = strtrim ( editBox : GetText ( ) ) ;
editBox : SetText ( text ) ;
NarcissusDB_PC.PlayerAlias = text ;
editBox : Disable ( ) ;
editBox : HighlightText ( 0 , 0 )
editBox : SetText ( UnitName ( " player " ) ) ;
end
self : SetWidth ( self.Label : GetWidth ( ) + 12 ) ;
local LetterNum = editBox : GetNumLetters ( ) ;
local w = max ( LetterNum * 16 , 160 ) ;
editBox : SetWidth ( w ) ;
end
--Music Fade In/Out
local MusicIO = CreateFrame ( " Frame " , " Narci_MusicInOut " ) ;
MusicIO.t = 0 ;
MusicIO : Hide ( )
local function MusicIO_Update ( self , elapsed )
self.t = self.t + elapsed
local volume ;
if self.state then
volume = max ( ( self.t / 2 ) , CVarTemp.MusicVolume )
else
volume = max ( ( self.fromVolume - self.t / 2 ) , CVarTemp.MusicVolume )
end
SetCVar ( " Sound_MusicVolume " , volume )
if ( self.state and volume >= 1 ) or ( ( not self.state ) and volume <= tonumber ( CVarTemp.MusicVolume ) ) then
self : Hide ( )
self.t = 0 ;
end
end
MusicIO : SetScript ( " OnShow " , function ( self )
self.fromVolume = GetCVar ( " Sound_MusicVolume " ) or 1 ;
end )
MusicIO : SetScript ( " OnUpdate " , MusicIO_Update )
MusicIO : SetScript ( " OnHide " , function ( self )
self.t = 0 ;
end )
function MusicIO : In ( )
if not NarcissusDB.FadeMusic then
return ;
end
self : Hide ( ) ;
self.state = true ;
self : Show ( ) ;
end
function MusicIO : Out ( )
self : Hide ( ) ;
self.state = false ;
self : Show ( ) ;
end
function Narci_Open ( )
if not IS_OPENED then
if InCombatLockdown ( ) then
--[[
--Can't open the default character pane either
ShowUIPanel ( CharacterFrame ) ;
local subFrame = _G [ " PaperDollFrame " ] ;
if not subFrame : IsShown ( ) then
ToggleCharacter ( " PaperDollFrame " ) ;
end
--]]
return ;
end
IS_OPENED = true ;
CVarTemp : BackUp ( ) ;
ViewProfile : SaveView ( 5 ) ;
ModifyCameraForShapeshifter ( ) ;
xmogMode = 0 ;
MogModeOffset = 0 ;
NarciPlayerModelFrame1.xmogMode = 0 ;
local speedFactor = 180 / ( GetCVar ( " cameraYawMoveSpeed " ) or 180 ) ;
ZoomFactor.toSpeed = speedFactor * ZoomFactor.toSpeedBasic ;
ZoomFactor.fromSpeed = speedFactor * ZoomFactor.fromSpeedBasic ;
MusicIO : In ( ) ;
EL : Show ( ) ;
Toolbar : FlyIn ( ) ;
Narci_XmogButton : Enable ( ) ;
DefaultTooltip : SetScale ( UIParent : GetEffectiveScale ( ) or 1 ) ;
After ( 0 , function ( )
CameraMover : Enter ( ) ;
RadarChart : SetValue ( 0 , 0 , 0 , 0 , 1 ) ;
Narci_LetterboxAnimation ( ) ;
local Vignette = Narci_Vignette ;
Vignette.VignetteLeft : SetAlpha ( VIGNETTE_ALPHA ) ;
Vignette.VignetteRight : SetAlpha ( VIGNETTE_ALPHA ) ;
Vignette.VignetteRightSmall : SetAlpha ( 0 ) ;
FadeFrame ( Vignette , 0.5 , 1 ) ;
Vignette.VignetteRight . animIn : Play ( ) ;
Vignette.VignetteLeft . animIn : Play ( ) ;
After ( 0 , function ( )
SlotController : LazyRefresh ( ) ;
StatsUpdator : Gradual ( ) ;
end ) ;
end ) ;
Narci.refreshCombatRatings = true ;
Narci.isActive = true ;
else
if Narci.showExitConfirm and not InCombatLockdown ( ) then
local ExitConfirm = Narci_ExitConfirmationDialog ;
if not ExitConfirm : IsShown ( ) then
FadeFrame ( ExitConfirm , 0.25 , 1 ) ;
--"Nullify" ShowUI
UIParent : SetAlpha ( 0 ) ;
Minimap : Hide ( ) ;
After ( 0 , function ( )
SetUIVisibility ( false ) ;
MiniButton : Enable ( ) ;
UIParent : SetAlpha ( 1 ) ;
Minimap : Show ( )
end ) ;
return ;
else
FadeFrame ( ExitConfirm , 0.15 , 0 ) ;
end
end
SlotController : PlayAnimOut ( ) ;
ExitFunc ( ) ;
MusicIO : Out ( ) ;
Narci_LetterboxAnimation ( " OUT " ) ;
if Narci_TitleManager_Switch.IsOn then
Narci_TitleManager_Switch : Click ( ) ;
end
EquipmentFlyoutFrame : Hide ( ) ;
Narci_TitleManager_TitleTooltip : Hide ( ) ; --TitleManager
Narci_ModelSettings : Hide ( ) ;
Toolbar : FlyOut ( ) ;
TakeOutFrames ( false ) ;
Narci.showExitConfirm = false ;
end
NarciAPI.UpdateSessionTime ( ) ;
end
function Narci_OpenGroupPhoto ( )
if not IS_OPENED then
if InCombatLockdown ( ) then
return ;
end
IS_OPENED = true ;
CVarTemp : BackUp ( ) ;
ViewProfile : SaveView ( 5 ) ;
ModifyCameraForShapeshifter ( ) ;
SetCVar ( " test_cameraDynamicPitch " , 1 )
local xmogMode_Temp = NarcissusDB.DefaultLayout ;
NarcissusDB.DefaultLayout = 2 ;
Narci_XmogButton : Enable ( ) ;
Narci_XmogButton : Click ( ) ;
After ( 0.4 , function ( )
NarcissusDB.DefaultLayout = xmogMode_Temp ;
end )
local speedFactor = 180 / ( GetCVar ( " cameraYawMoveSpeed " ) or 180 ) ;
ZoomFactor.toSpeed = speedFactor * ZoomFactor.toSpeedBasic ;
ZoomFactor.fromSpeed = speedFactor * ZoomFactor.fromSpeedBasic ;
EL : Show ( ) ;
CameraMover : Pitch ( ) ;
DefaultTooltip : SetScale ( UIParent : GetEffectiveScale ( ) or 1 ) ;
After ( 0 , function ( )
SlotController : LazyRefresh ( ) ;
local Vignette = Narci_Vignette ;
Vignette.VignetteLeft : SetAlpha ( VIGNETTE_ALPHA ) ;
Vignette.VignetteRight : SetAlpha ( VIGNETTE_ALPHA ) ;
Vignette.VignetteRightSmall : SetAlpha ( 0 ) ;
FadeFrame ( Vignette , 0.8 , 1 ) ;
Vignette.VignetteRight . animIn : Play ( ) ;
Vignette.VignetteLeft . animIn : Play ( ) ;
if UIParent : IsShown ( ) then
UIPA.endAlpha = 0 ;
UIPA : Show ( ) ;
end
After ( 0 , function ( )
if not Narci_PhotoModeButton.IsOn then
Narci_PhotoModeButton : Click ( ) ;
end
Toolbar : FlyIn ( ) ;
After ( 0.5 , function ( )
SetUIVisibility ( false ) ; --Same as pressing Alt + Z
After ( 0.3 , function ( )
UIParent : SetAlpha ( 1 ) ;
end )
end )
end )
end )
Narci.isActive = true ;
MsgAlertContainer : Display ( ) ;
end
NarciAPI.UpdateSessionTime ( ) ;
end
---Widgets---
function CameraControllerThumb_OnLoad ( self )
self : RegisterForClicks ( " RightButtonUp " ) ;
self : RegisterForDrag ( " LeftButton " ) ;
self.Reading : SetText ( string.format ( " %.2f " , 0 ) ) ;
end
local function CameraControlBarThumb_Reposition ( self , ofsx )
self : GetParent ( ) . Thumb : SetPoint ( " CENTER " , ofsx , 0 ) ;
NarciCameraOffsetControlBar.PosX = ofsx ;
SetCVar ( " test_cameraOverShoulder " , 0 - ofsx / 20 ) --Ajust the zoom - Shoulder factor
local currentShoulder = GetCVar ( " test_cameraOverShoulder " ) ;
local zoom = GetCameraZoom ( ) ;
end
function CameraControlBar_DraggingFrame_OnUpdate ( self )
local scale = self : GetParent ( ) : GetEffectiveScale ( ) ;
local xpos = GetCursorPosition ( ) / scale ;
local xmin , xmax = self : GetParent ( ) : GetLeft ( ) + 18 , self : GetParent ( ) : GetRight ( ) - 18 ;
NarciCameraOffsetControlBar.Range = xmax - xmin ;
local xcenter = self : GetParent ( ) : GetCenter ( ) ;
local ofsx ;
if xpos < xmin then
ofsx = xmin - xcenter ;
elseif xpos > xmax then
ofsx = xmax - xcenter ;
else
ofsx = xpos - xcenter ;
end
CameraControlBarThumb_Reposition ( self , ofsx ) ;
end
function CameraControlBarThumb_OnClick ( self , button , down )
--self:GetParent().Thumb:SetPoint("CENTER", 0, 0);
self : Disable ( )
CameraControlBar_ResetPosition_AnimFrame.OppoDirection = true
CameraControlBar_ResetPosition_AnimFrame : Show ( ) ;
After ( 0.6 , function ( )
self : Enable ( ) ;
NarciCameraOffsetControlBar.PosX = 0 ;
NarciCameraOffsetControlBar.PosRadian = 0 ;
end )
local zoom = GetCameraZoom ( )
SmoothShoulderCVar ( Shoulder_Factor1 * zoom + Shoulder_Factor2 ) ;
self : GetParent ( ) . Thumb.Reading : SetText ( string.format ( 0 ) ) ;
end
local shaftDiameter = 53 ;
local lastDegree = 0 ;
local tinyIncre = 1000 ;
local function TinyZoom ( degree , lastDegree )
if ( degree >= 0 and lastDegree >= 0 ) or ( degree <= 0 and lastDegree <= 0 ) then
if degree < lastDegree then
CameraZoomIn ( ( lastDegree - degree ) / tinyIncre ) ;
elseif degree > lastDegree then
CameraZoomOut ( ( degree - lastDegree ) / tinyIncre ) ;
end
elseif degree >= 0 and lastDegree < 0 then
if degree >= 90 then
CameraZoomIn ( ( 180 - degree ) / tinyIncre ) ;
else
CameraZoomOut ( ( 0 + degree ) / tinyIncre ) ;
end
elseif degree <= 0 and lastDegree > 0 then
if degree <= - 90 then
CameraZoomOut ( ( 180 + degree ) / tinyIncre ) ;
else
CameraZoomIn ( ( 0 - degree ) / tinyIncre ) ;
end
end
end
local function RotateShaftNode ( radian )
local ofsx = shaftDiameter * math.cos ( radian )
local ofsy = shaftDiameter * math.sin ( radian )
CameraControllerNode : SetPoint ( " CENTER " , " CameraControllerThumb " , " CENTER " , ofsx , ofsy ) ;
CameraControllerThumb.Shaft : SetRotation ( radian )
end
function CameraZoomController_DraggingFrame_OnUpdate ( self )
local scale = self : GetParent ( ) : GetEffectiveScale ( )
local xpos , ypos = GetCursorPosition ( )
xpos , ypos = xpos / scale , ypos / scale
local radian = math.atan2 ( ( ypos - self.cy ) , ( xpos - self.cx ) )
RotateShaftNode ( radian ) ;
NarciCameraOffsetControlBar.PosRadian = radian ;
local degree = math.deg ( radian )
if not self.isPressed then
TinyZoom ( degree , lastDegree )
else
if degree < 0 then
CameraZoomIn ( ( - degree ) / tinyIncre )
elseif degree > 0 then
CameraZoomOut ( ( degree ) / tinyIncre )
end
end
lastDegree = degree ;
end
------------------------------------------------------
------------------Photo Mode Controller---------------
------------------------------------------------------
function Narci_KeyListener_OnEscapePressed ( )
if IS_OPENED then
MiniButton : Click ( ) ;
end
end
function Narci_ExitButton_OnClick ( self )
if IS_OPENED then
Narci_Open ( ) ;
SetUIVisibility ( true ) ;
end
end
local function TokenButton_ClearMarker ( self )
local parent = self : GetParent ( ) ;
if parent.buttons then
for i = 1 , # parent.buttons do
parent.buttons [ i ] . HighlightColor : Hide ( ) ;
end
end
end
---Set Graphics Settings to Ultra---
local PhotoMode_Cvar_GraphicsBackup = { } ;
local PhotoMode_Cvar_GraphicsList = {
[ " ffxAntiAliasingMode " ] = 2 ,
[ " graphicsTextureResolution " ] = 3 ,
[ " graphicsTextureFiltering " ] = 6 ,
[ " graphicsProjectedTextures " ] = 2 ,
[ " graphicsViewDistance " ] = 10 ,
[ " graphicsEnvironmentDetail " ] = 10 ,
[ " graphicsGroundClutter " ] = 10 ,
[ " graphicsShadowQuality " ] = 6 ,
[ " graphicsLiquidDetail " ] = 4 ,
[ " graphicsSunshafts " ] = 3 ,
[ " graphicsParticleDensity " ] = 5 ,
[ " graphicsSSAO " ] = 5 ,
[ " graphicsDepthEffects " ] = 4 ,
--["graphicsLightingQuality"] = 3,
[ " lightMode " ] = 2 ,
[ " MSAAQuality " ] = 4 , --4 is invalid. But used for backup
[ " shadowrt " ] = - 1 , --invalid
}
---Hide Names and Bubbles---
--local PhotoMode_Cvar_TrackingList = 1 --Track Battle Pet
local PhotoMode_Cvar_TrackingBAK = true ;
local PhotoMode_Cvar_NamesBackup = { } ;
local PhotoMode_Cvar_NamesList = { --Unit Name CVars
[ " UnitNameOwn " ] = 0 ,
[ " UnitNameNonCombatCreatureName " ] = 0 ,
[ " UnitNameFriendlyPlayerName " ] = 0 ,
[ " UnitNameFriendlyPetName " ] = 0 ,
[ " UnitNameFriendlyMinionName " ] = 0 ,
[ " UnitNameFriendlyGuardianName " ] = 0 ,
[ " UnitNameFriendlySpecialNPCName " ] = 0 ,
[ " UnitNameEnemyPlayerName " ] = 0 ,
[ " UnitNameEnemyPetName " ] = 0 ,
[ " UnitNameEnemyGuardianName " ] = 0 ,
[ " UnitNameNPC " ] = 0 ,
[ " UnitNameInteractiveNPC " ] = 0 ,
[ " UnitNameHostleNPC " ] = 0 ,
[ " chatBubbles " ] = 0 ,
[ " floatingCombatTextCombatDamage " ] = 0 ,
[ " floatingCombatTextCombatHealing " ] = 0 ,
} ;
local function PhotoMode_BackupCvar ( BackupTable , OriginalTable )
if OriginalTable then
for k , v in pairs ( OriginalTable ) do
BackupTable [ k ] = GetCVar ( k ) or 0 ;
end
end
end
local function PhotoMode_RestoreCvar ( BackupTable ) --it can also be used to set CVars to pre-defined values
if BackupTable then
for k , v in pairs ( BackupTable ) do
SetCVar ( k , v )
--print(k.." "..v)
end
end
end
local function PhotoMode_ZeroCvar ( BackupTable )
if BackupTable then
for k , v in pairs ( BackupTable ) do
SetCVar ( k , 0 )
end
end
end
local function PhotoMode_GetTrackingInfo ( id )
local id = 1 ;
local _ , _ , active = GetTrackingInfo ( id )
PhotoMode_Cvar_TrackingBAK = active ;
end
local ControllerButtonTooltip = {
-- [ Name ] = { HeadLine, Line, Special, Guide Pic Index }
[ " Narci_PhotoModeButton " ] = {
L [ " Photo Mode " ] ,
L [ " Photo Mode Tooltip Open " ] ,
L [ " Photo Mode Tooltip Special " ] ,
} ,
[ " Narci_XmogButton " ] = {
L [ " Xmog Button " ] ,
L [ " Xmog Button Tooltip Open " ] ,
L [ " Xmog Button Tooltip Special " ] ,
} ,
[ " Narci_EmoteButton " ] = {
L [ " Emote Button " ] ,
L [ " Emote Button Tooltip Open " ] ,
L [ " Emote Button Tooltip Special " ] ,
} ,
[ " Narci_HideTextsButton " ] = {
L [ " HideTexts Button " ] ,
L [ " HideTexts Button Tooltip Open " ] ,
L [ " HideTexts Button Tooltip Special " ] ,
1 ,
} ,
[ " Narci_TopQualityButton " ] = {
L [ " TopQuality Button " ] ,
L [ " TopQuality Button Tooltip Open " ] ,
L [ " HideTexts Button Tooltip Special " ] ,
2 ,
} ,
}
function Narci_PhotoModeButton_OnLoad ( self )
self.IsOn = false ;
local name = self : GetName ( ) ;
if ControllerButtonTooltip [ name ] then
if ControllerButtonTooltip [ name ] [ 3 ] then --special notes
self.tooltip = { ControllerButtonTooltip [ name ] [ 1 ] , ControllerButtonTooltip [ name ] [ 2 ] .. " \n |cff6b6b6b " .. ControllerButtonTooltip [ name ] [ 3 ] } ; --42% Grey
else
self.tooltip = { ControllerButtonTooltip [ name ] [ 1 ] , ControllerButtonTooltip [ name ] [ 2 ] } ;
end
if ControllerButtonTooltip [ name ] [ 4 ] then
self.guideIndex = ControllerButtonTooltip [ name ] [ 4 ] ;
end
wipe ( ControllerButtonTooltip [ name ] ) ;
end
if self.Pushed and self.Icon then
self.Pushed : SetTexture ( self.Icon : GetTexture ( ) )
end
end
local function TemporarilyHidePopUp ( frame )
if frame : IsShown ( ) then
frame.AnimFrame : Hide ( ) ;
frame.AnimFrame . OppoDirection = true ;
frame.AnimFrame : Show ( ) ;
frame.AnimFrame . toY = - 20 ;
end
end
function NarciXmogButtonPopUp_OnShow ( self )
ColorUtil : SetWidgetColor ( self.Color ) ;
ColorUtil : SetWidgetColor ( self.Option ) ;
end
function XmogButtonPopUp_OnLoad ( self )
self.CopyButton . Label : SetText ( L [ " Copy Texts " ] ) ;
self.ModeButton . Background : SetColorTexture ( 0.06 , 0.06 , 0.06 , 0.8 ) ;
self.ModeButton . Label : SetText ( L [ " Layout " ] ) ;
self.ModeButton . Option : SetText ( L [ " Symmetry " ] ) ;
self.ModelToggle . Label : SetText ( L [ " 3D Model " ] ) ;
ColorUtil : SetWidgetColor ( self.ModeButton . Option ) ;
local SyntaxButton = self.CopyButton . GearTexts ;
SyntaxButton.PlainText . Background : SetColorTexture ( 0.06 , 0.06 , 0.06 , 0.8 ) ;
SyntaxButton.BBSCode . Background : SetColorTexture ( 0.06 , 0.06 , 0.06 , 0.8 ) ;
SyntaxButton.Markdown . Background : SetColorTexture ( 0.06 , 0.06 , 0.06 , 0.8 ) ;
SyntaxButton.PlainText . Label : SetText ( L [ " Plain Text " ] ) ;
SyntaxButton.BBSCode . Label : SetText ( L [ " BB Code " ] ) ;
SyntaxButton.Markdown . Label : SetText ( L [ " Markdown " ] ) ;
end
local function HidePlayerModel ( )
if ( not Narci_ModelContainer : IsVisible ( ) ) or ( NarcissusDB.AlwaysShowModel ) then return ; end
Narci_PlayerModelAnimOut : Show ( )
After ( 0.4 , function ( )
FadeFrame ( NarciPlayerModelFrame1 , 0.5 , 0 )
end )
end
local function UseXmogLayout ( index )
if index == 1 then
xmogMode = 1 ;
NarciPlayerModelFrame1.xmogMode = 1 ;
Narci_XmogButtonPopUp_ModeButton.Option : SetText ( L [ " Asymmetry " ] ) ;
CameraMover : Pitch ( ) ;
HidePlayerModel ( ) ;
SmoothShoulder.toPoint = 0.01 ;
SmoothShoulder : Show ( ) ;
Narci_GuideLineFrame.VirtualLineRight . AnimFrame.toX = - 80 ;
Narci_GuideLineFrame.VirtualLineRight . AnimFrame : Show ( ) ;
SmoothShoulderCVar ( 0.01 ) ;
Narci_XmogButtonPopUp_ModeButton.ShowModel = false ;
if NarcissusDB.AlwaysShowModel then
NarciModel_RightGradient : Hide ( ) ;
Narci_PlayerModelGuideFrame.VignetteRightSmall : Hide ( ) ;
if not NarciPlayerModelFrame1 : IsVisible ( ) then
Narci_PlayerModelAnimIn : Show ( ) ;
end
end
elseif index == 2 then
xmogMode = 2 ;
MogModeOffset = 0.2 ;
NarciPlayerModelFrame1.xmogMode = 2 ;
if Narci_Character : IsVisible ( ) then
FadeFrame ( NarciModel_RightGradient , 0.5 , 1 ) ;
end
Narci_XmogButtonPopUp_ModeButton.Option : SetText ( L [ " Symmetry " ] ) ;
if not NarciPlayerModelFrame1 : IsVisible ( ) then
Narci_PlayerModelAnimIn : Show ( ) ;
end
Narci_PlayerModelGuideFrame.VignetteRightSmall : Show ( ) ;
Narci_GuideLineFrame.VirtualLineRight . AnimFrame.toX = - 600 ;
Narci_GuideLineFrame.VirtualLineRight . AnimFrame : Show ( ) ;
Narci_XmogButtonPopUp_ModeButton.ShowModel = true ;
After ( 0 , function ( )
if not IsMounted ( ) then
CameraMover : Pitch ( ) ;
CameraMover : ZoomIn ( ZoomInValue_XmogMode ) ; --ajust by raceID
else
CameraMover : ZoomIn ( 8 ) ; --ajust by raceID
end
end )
end
end
local function PlayCheckSound ( self , state )
if not self.enableSFX then return ;
elseif state then
PlaySound ( SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON ) ;
else
PlaySound ( SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF ) ;
end
end
local function ActivateMogMode ( )
Narci_GuideLineFrame.VirtualLineRight . AnimFrame : Hide ( ) ;
if MOG_MODE then
FadeFrame ( Narci_Attribute , 0.5 , 0 )
FadeFrame ( Narci_XmogNameFrame , 0.2 , 1 , 0 )
local DefaultLayout = NarcissusDB.DefaultLayout ;
if DefaultLayout == 1 then
xmogMode = 1 ;
elseif DefaultLayout == 2 then
xmogMode = 2 ;
MogModeOffset = 0.2 ;
elseif DefaultLayout == 3 then
xmogMode = 2 ;
MogModeOffset = 0.2 ;
end
UseXmogLayout ( xmogMode ) ;
NarciPlayerModelFrame1.xmogMode = xmogMode ;
MsgAlertContainer : Display ( ) ;
else
Narci_GuideLineFrame.VirtualLineRight . AnimFrame.toX = Narci_GuideLineFrame.VirtualLineRight . AnimFrame.defaultX
if Toolbar : IsShown ( ) then
Narci_GuideLineFrame.VirtualLineRight . AnimFrame : Show ( )
FadeFrame ( Narci_Attribute , 0.5 , 1 )
local zoom = GetCameraZoom ( )
SmoothShoulderCVar ( Shoulder_Factor1 * zoom + Shoulder_Factor2 )
end
FadeFrame ( Narci_XmogNameFrame , 0.2 , 0 )
ShowAttributeButton ( ) ;
xmogMode = 0 ;
MogModeOffset = 0 ;
NarciPlayerModelFrame1.xmogMode = 0 ;
MsgAlertContainer : Hide ( ) ;
end
end
function Narci_XmogButton_OnClick ( self )
self.IsOn = not self.IsOn
MoveViewRightStop ( ) ;
EquipmentFlyoutFrame : Hide ( ) ;
MOG_MODE = not MOG_MODE ;
local PopUp = Narci_XmogButtonPopUp ;
if not self.IsOn then
--Exit Xmog mode
FadeFrame ( Narci_VignetteRightSmall , 0.5 , 0 ) ;
FadeFrame ( Narci_VignetteRightLarge , 0.5 , NarcissusDB.VignetteStrength ) ;
Narci_SnowEffect ( true ) ;
Narci_LetterboxAnimation ( ) ;
PlayCheckSound ( self , false )
self.Icon : SetTexCoord ( 0 , 0.5 , 0 , 1 ) ;
PopUp.AnimFrame : Hide ( ) ;
PopUp.AnimFrame . OppoDirection = true
PopUp.AnimFrame : Show ( ) ;
PopUp.AnimFrame . toY = - 20 ;
if Narci_ModelContainer : IsVisible ( ) then
if IS_OPENED then
CameraMover : Pitch ( ) ;
else
--SmoothShoulderCVar(0);
end
Narci_PlayerModelAnimOut : Show ( )
After ( 0.4 , function ( )
FadeFrame ( NarciPlayerModelFrame1 , 0.5 , 0 ) ;
end )
end
Narci_ModelSettings : Hide ( ) ;
self.tooltip = { L [ " Xmog Button " ] , L [ " Xmog Button Tooltip Open " ] .. " \n |cff6b6b6b " .. L [ " Xmog Button Tooltip Special " ] } ;
if not Narci_ExitConfirmationDialog : IsShown ( ) then
Narci.showExitConfirm = false ;
end
else
FadeFrame ( Narci_VignetteRightSmall , 0.5 , NarcissusDB.VignetteStrength ) ;
FadeFrame ( Narci_VignetteRightLarge , 0.5 , 0 ) ;
Narci_SnowEffect ( false ) ;
Narci_LetterboxAnimation ( " OUT " ) ;
PlayCheckSound ( self , true )
self.Icon : SetTexCoord ( 0.5 , 1 , 0 , 1 ) ;
PopUp : Show ( ) ;
PopUp.AnimFrame : Hide ( ) ;
PopUp.AnimFrame . OppoDirection = false ;
PopUp.AnimFrame : Show ( ) ;
PopUp.AnimFrame . toY = 8 ;
Narci_XmogNameFrame.PlayerName : SetText ( Narci_PlayerInfoFrame.PlayerName : GetText ( ) )
self.tooltip = { L [ " Xmog Button " ] , L [ " Xmog Button Tooltip Close " ] } ;
end
SlotController : LazyRefresh ( ) ;
After ( 0.1 , function ( )
ActivateMogMode ( ) ;
end )
NarciTooltip : FadeOut ( ) ;
TemporarilyHidePopUp ( Narci_EmoteButtonPopUp ) ;
end
local function UpdateXmogName ( SpecOnly )
local frame = Narci_XmogNameFrame ;
local currentSpec = GetSpecialization ( ) ;
if not currentSpec then
return ;
end
local IsSpellKnown = IsSpellKnown ;
local token = 159243 ;
local ArmorType ;
if not SpecOnly then
Narci_SetPlayerName ( frame ) ;
if IsSpellKnown ( 76273 ) or IsSpellKnown ( 106904 ) or IsSpellKnown ( 202782 ) or IsSpellKnown ( 76275 ) then
--ArmorType = "Leather"
token = 159300 ;
elseif IsSpellKnown ( 76250 ) or IsSpellKnown ( 76272 ) then
--ArmorType = "Mail"
token = 159371 ;
elseif IsSpellKnown ( 76276 ) or IsSpellKnown ( 76277 ) or IsSpellKnown ( 76279 ) then
--ArmorType = "Cloth"
token = 159243 ;
elseif IsSpellKnown ( 76271 ) or IsSpellKnown ( 76282 ) or IsSpellKnown ( 76268 ) then
--ArmorType = "Plate"
token = 159418 ;
end
local _ ;
_ , _ , ArmorType = GetItemInfoInstant ( token ) ;
frame.armorType = ArmorType ;
end
--Leather 76273 Mail 76250 Cloth 76276 76279 Plate 76271 76282
ArmorType = frame.armorType or ArmorType or " ArmorType " ;
local _ , currentSpecName = GetSpecializationInfo ( currentSpec ) ;
currentSpecName = currentSpecName or " " ;
local className , englishClass , _ = UnitClass ( " player " ) ;
local _ , _ , _ , rgbHex = GetClassColor ( englishClass ) ;
frame.ArmorString : SetText ( " |cFFFFD100 " .. ArmorType .. " |r " .. " | " .. " |c " .. rgbHex .. currentSpecName .. " " .. className .. " |r " ) ;
end
local function GetWowHeadDressingRoomURL ( )
local slot ;
local ItemList = { } ;
for i = 1 , # xmogTable do
slot = xmogTable [ i ] [ 1 ] ;
if slotTable [ slot ] and slotTable [ slot ] . itemID then
ItemList [ slot ] = { slotTable [ slot ] . itemID , slotTable [ slot ] . bonusID } ;
end
end
return NarciAPI.EncodeItemlist ( ItemList ) ;
end
local function CopyTexts ( type , subType )
local texts = Narci_XmogNameFrame.PlayerName : GetText ( ) or " My Transmog " ;
type = type or " TEXT " ;
subType = subType or " Wowhead " ;
local showItemID = Narci_XmogButtonPopUp.CopyButton . showItemID or false ;
local source ;
if type == " TEXT " then
texts = texts .. " \n "
for i = 1 , # xmogTable do
local index = xmogTable [ i ] [ 1 ]
if slotTable [ index ] and slotTable [ index ] . Name : GetText ( ) then
local text = " |cFFFFD100 " .. xmogTable [ i ] [ 2 ] .. " :|r " .. ( slotTable [ index ] . Name : GetText ( ) or " " ) ;
if showItemID and slotTable [ index ] . itemID then
text = text .. " |cFFacacac " .. slotTable [ index ] . itemID .. " |r " ;
end
source = slotTable [ index ] . ItemLevel : GetText ( ) ;
if source and source ~= " " then
text = text .. " |cFF40C7EB( " .. source .. " )|r "
end
if text then
texts = texts .. " \n " .. text ;
end
end
end
elseif type == " BBS " then
if subType == " Wowhead " then
texts = " |cFF959595[table border=2 cellpadding=4] \n [tr][td colspan=3 align=center][b]|r " .. texts .. " |r|cFF959595[/b][/td][/tr] \n [tr][td align=center]Slot[/td][td align=center]Name[/td][td align=center]Source[/td][/tr]|r "
elseif subType == " NGA " then
texts = " |cFF959595[table] \n [tr][td colspan=3][align=center][b]|r " .. texts .. " |r|cFF959595[/b][/align][/td][/tr] \n [tr][td][align=center]部位[/align][/td][td][align=center]装备名称[/align][/td][td][align=center]来源[/align][/td][/tr]|r "
elseif subType == " mmo-champion " then
texts = " |cFF959595[table= \" width: 640, class: grid \" ] \n [tr][td= \" colspan: 3 \" ][center][b]|r " .. texts .. " |r|cFF959595[/b][/center][/td][/tr] \n [tr][td][center]Slot[/center][/td][td][center]Name[/center][/td][td][center]Source[/center][/td][/tr]|r "
end
for i = 1 , # xmogTable do
local index = xmogTable [ i ] [ 1 ]
if slotTable [ index ] and slotTable [ index ] . Name : GetText ( ) then
local text = " |cFF959595[tr][td]|r " .. " |cFFFFD100 " .. xmogTable [ i ] [ 2 ] .. " |r|cFF959595[/td][td]|r "
if showItemID and slotTable [ index ] . itemID then
if subType == " Wowhead " then
text = text .. " [item= " .. slotTable [ index ] . itemID .. " |r|cFF959595][/td]|r "
elseif subType == " NGA " then
text = text .. " |cFF959595[url=https://www.wowhead.com/item= " .. slotTable [ index ] . itemID .. " ]|r " .. ( slotTable [ index ] . Name : GetText ( ) or " " ) .. " |cFF959595[/url][/td]|r "
elseif subType == " mmo-champion " then
text = text .. " |cFF959595[url=https://www.wowdb.com/items/ " .. slotTable [ index ] . itemID .. " ]|r " .. ( slotTable [ index ] . Name : GetText ( ) or " " ) .. " |cFF959595[/url][/td]|r "
end
else
text = text .. ( slotTable [ index ] . Name : GetText ( ) or " " ) .. " |r|cFF959595[/td]|r "
end
source = slotTable [ index ] . ItemLevel : GetText ( )
if source then
text = text .. " |cFF959595[td]|r|cFF40C7EB " .. source .. " |r|cFF959595[/td]|r "
else
text = text .. " |cFF959595[td] [/td]|r "
end
if text then
texts = texts .. " \n " .. text .. " |cFF959595[/tr]|r "
end
end
end
texts = texts .. " \n |cFF959595[/table]|r "
-----
if subType == " Wowhead " then
texts = GetWowHeadDressingRoomURL ( ) ;
end
elseif type == " MARKDOWN " then
texts = " |cFF959595**|r " .. texts .. " |cFF959595** \n \n | Slot | Name | Source | " .. " \n " .. " |:--|:--|:--| "
for i = 1 , # xmogTable do
local index = xmogTable [ i ] [ 1 ]
if slotTable [ index ] and slotTable [ index ] . Name : GetText ( ) then
local text = " |cFF959595| |r|cFFFFD100 " .. xmogTable [ i ] [ 2 ] .. " |r |cFF959595| |r "
if showItemID and slotTable [ index ] . itemID then
text = text .. " |cFF959595[|r " .. ( slotTable [ index ] . Name : GetText ( ) or " " ) .. " |cFF959595](https://www.wowhead.com/item=|r " .. slotTable [ index ] . itemID .. " )|r "
else
text = text .. ( slotTable [ index ] . Name : GetText ( ) or " " )
end
source = slotTable [ index ] . ItemLevel : GetText ( )
if source then
text = text .. " |cFF959595| |r|cFF40C7EB " .. source .. " |r |cFF959595| |r "
else
text = text .. " |cFF959595| |r "
end
if text then
texts = texts .. " \n " .. text ;
end
end
end
texts = texts .. " \n "
end
return texts ;
end
local websites = {
[ 0 ] = { " reddit " , " Interface/AddOns/Narcissus/Art/Logos/reddit " } ,
[ 1 ] = { " Wowhead " , " Interface/AddOns/Narcissus/Art/Logos/Wowhead " } ,
[ 2 ] = { " NGA " , " Interface/AddOns/Narcissus/Art/Logos/NGA " } ,
[ 3 ] = { " mmo-champion " , " Interface/AddOns/Narcissus/Art/Logos/mmo-champion " } ,
--[4] = {"Vanion", "Interface/AddOns/Narcissus/Art/Logos/Vanion"},
}
function Narci_WebsiteButton_OnLoad ( self )
local index = self : GetID ( ) or 2 ;
if websites [ index ] then
self.NormalTex : SetTexture ( websites [ index ] [ 2 ] ) ;
self.PushedTex : SetTexture ( websites [ index ] [ 2 ] ) ;
if not self : GetParent ( ) . buttons then
self : GetParent ( ) . buttons = { } ;
end
tinsert ( self : GetParent ( ) . buttons , self ) ;
else
self : Hide ( )
end
end
local function WebsiteButton_DesatureLogo ( self )
local parent = self : GetParent ( ) ;
if parent.buttons then
for i = 1 , # parent.buttons do
parent.buttons [ i ] . NormalTex : SetTexCoord ( 0 , 0.5 , 0 , 1 ) ;
parent.buttons [ i ] . PushedTex : SetTexCoord ( 0 , 0.5 , 0 , 1 ) ;
parent.buttons [ i ] . IsOn = false ;
end
end
end
function WebsiteButton_OnClick ( self )
WebsiteButton_DesatureLogo ( self )
self.NormalTex : SetTexCoord ( 0.5 , 1 , 0 , 1 ) ;
self.PushedTex : SetTexCoord ( 0.5 , 1 , 0 , 1 ) ;
self.IsOn = true ;
self : GetParent ( ) . subType = websites [ self : GetID ( ) ] [ 1 ] ;
self : GetParent ( ) : Click ( ) ;
end
local function SetClipboard ( self , type , subType )
local frame = self or Narci_XmogButtonPopUp.CopyButton ;
local type = type or frame.CodeType or " TEXT " ;
local subType = subType or frame.GearTexts . BBSCode.subType or " Wowhead " ;
local texts = CopyTexts ( type , subType ) ;
frame.GearTexts : SetText ( texts ) ;
if frame.GearTexts then
frame.GearTexts : SetFocus ( ) ;
frame.GearTexts : HighlightText ( ) ;
end
end
local codeTokens = {
[ 1 ] = " TEXT " , [ 2 ] = " BBS " , [ 3 ] = " MARKDOWN " ,
}
function Narci_CodeTokenButton_OnClick ( self )
self : GetParent ( ) : GetParent ( ) . CodeType = codeTokens [ self : GetID ( ) ] ;
SetClipboard ( ) ;
TokenButton_ClearMarker ( self ) ;
self.HighlightColor : Show ( ) ;
self.AnimFrame . Anim : SetScale ( 1.8 ) ;
self.AnimFrame . Anim.Bling : Play ( ) ;
end
function IncludeIDButton_OnClick ( self )
self.IsOn = not self.IsOn
if self.IsOn then
self.Tick : Show ( ) ;
Narci_XmogButtonPopUp.CopyButton . showItemID = true ;
else
self.Tick : Hide ( ) ;
Narci_XmogButtonPopUp.CopyButton . showItemID = false ;
end
SetClipboard ( )
end
function Narci_CopyButton_OnClick ( self )
self.IsOn = not self.IsOn ;
if self.IsOn then
SetClipboard ( self ) ;
FadeFrame ( self.GearTexts , 0.25 , 1 ) ;
else
FadeFrame ( self.GearTexts , 0.25 , 0 ) ;
end
self.AnimFrame . Anim : SetScale ( 1.5 ) ;
self.AnimFrame . Anim.Bling : Play ( ) ;
end
--Narci_EmoteButton
local EmoteTokenList = {
[ 1 ] = { { " Talk " , EMOTE94_CMD1 } , { " TALKEX " , EMOTE95_CMD1 } , { " TALKQ " , EMOTE96_CMD2 } , { " Flee " , YELL } } ,
[ 2 ] = { { " Kiss " , EMOTE59_CMD1 } , { " Salute " , EMOTE79_CMD1 } , { " Bye " , EMOTE102_CMD1 } , { " Bow " , EMOTE17_CMD1 } } ,
[ 3 ] = { { " Dance " , EMOTE35_CMD1 } , { " Read " , EMOTE453_CMD2 } , { " Train " , EMOTE155_CMD1 } , { " Chicken " , EMOTE22_CMD1 } } ,
[ 4 ] = { { " Clap " , EMOTE24_CMD1 } , { " Cheer " , EMOTE21_CMD1 } , { " Cackle " , EMOTE61_CMD1 } } ,
[ 5 ] = { { " Nod " , EMOTE68_CMD1 } , { " Doubt " , EMOTE67_CMD1 } , { " Point " , EMOTE73_CMD1 } } ,
[ 6 ] = { { " Rude " , EMOTE78_CMD1 } , { " Flex " , EMOTE42_CMD1 } , { " ROAR " , EMOTE76_CMD1 } } ,
[ 7 ] = { { " Cower " , EMOTE29_CMD1 } , { " Beg " , EMOTE8_CMD1 } , { " Cry " , EMOTE32_CMD1 } } ,
[ 8 ] = { { " Laydown " , EMOTE62_CMD1 } , { " Stand " , EMOTE143_CMD1 } , { " Sit " , EMOTE87_CMD1 } , { " Kneel " , EMOTE60_CMD1 } } ,
}
local function EmoteButton_CreateList ( self , buttonTemplate , List )
local ltrim = string.trim ;
local PopUp = self ;
local button , buttonWidth , buttonHeight ;
local buttons = { } ;
local initialPoint = " TOPLEFT " ;
local initialRelative = " TOPLEFT " ;
local point = " TOPLEFT " ;
local relativePoint = " TOPRIGHT " ;
local offsetX = 0 ;
local subListNum , subListNum_Max = 1 , 1 ;
if List and List [ 1 ] then
for i = 1 , # List do
subListNum = # List [ i ] ;
subListNum_Max = max ( subListNum , subListNum_Max ) ;
end
end
for i = 1 , # List do
for j = 1 , subListNum_Max do
button = CreateFrame ( " Button " , nil , PopUp , buttonTemplate ) ;
if List [ i ] [ j ] then
local text = ltrim ( List [ i ] [ j ] [ 2 ] , " / " ) ; --remove the slash
if LanguageDetector ( text ) == " RM " then
text = strupper ( string.sub ( text , 1 , 1 ) ) .. string.sub ( text , 2 ) ; --upper initial
end
button.Label : SetText ( text ) ;
button.Token = List [ i ] [ j ] [ 1 ] ;
else
button.Label : SetText ( " " )
button.Token = nil ;
button : Disable ( ) ;
end
if i % 2 == 0 then
button.Background : SetColorTexture ( 0.06 , 0.06 , 0.06 , 0.8 )
end
buttonWidth = button : GetWidth ( ) ;
buttonHeight = button : GetHeight ( ) ;
local offsetY = ( 1 - i ) * buttonHeight ;
if not buttons then
button : SetPoint ( initialPoint , PopUp , initialRelative , 0 , offsetY ) ;
elseif j == 1 then
button : SetPoint ( initialPoint , PopUp , initialRelative , 0 , offsetY ) ;
else
local index = # buttons
button : SetPoint ( point , buttons [ index ] , relativePoint , 0 , 0 ) ;
end
tinsert ( buttons , button ) ;
end
end
self.buttons = buttons ;
local popUpHeight = # List * buttonHeight ;
local popUpWidth = 4 * buttonWidth ;
PopUp : SetHeight ( popUpHeight ) ;
PopUp : SetWidth ( popUpWidth + 2 + 150 ) ;
EmoteTokenList = nil ;
end
function Narci_EmoteButtonPopUp_OnLoad ( self )
EmoteButton_CreateList ( self , " NarciEmoteTokenButtonTemplate " , EmoteTokenList ) ;
self.autoCapture = false ;
self : SetScript ( " OnEnter " , function ( )
Toolbar.OnEnter ( ) ;
end ) ;
self : SetScript ( " OnLeave " , function ( )
if not self : IsMouseOver ( ) then
Toolbar.OnLeave ( ) ;
end
end ) ;
self.AutoCaptureButton : SetScript ( " OnEnter " , function ( f )
f.Color : Show ( ) ;
Toolbar.OnEnter ( ) ;
end ) ;
self.AutoCaptureButton : SetScript ( " OnLeave " , function ( f )
f.Color : Hide ( ) ;
if not self : IsMouseOver ( ) then
Toolbar.OnLeave ( ) ;
end
end ) ;
end
function Narci_EmoteButton_OnClick ( self )
self.IsOn = not self.IsOn
local popupFrame = Narci_EmoteButtonPopUp ;
if not self.IsOn then
PlayCheckSound ( self , false )
self.Icon : SetTexCoord ( 0 , 0.5 , 0 , 1 ) ;
self.UpdateFrame : Hide ( ) ;
popupFrame.AnimFrame : Hide ( ) ;
popupFrame.AnimFrame : Show ( ) ;
popupFrame.AnimFrame . toY = - 40 ;
else
PlayCheckSound ( self , true )
self.Icon : SetTexCoord ( 0.5 , 1 , 0 , 1 ) ;
popupFrame : Show ( ) ;
popupFrame.AnimFrame : Hide ( ) ;
popupFrame.AnimFrame : Show ( ) ;
popupFrame.AnimFrame . toY = 8 ;
end
NarciTooltip : FadeOut ( ) ;
if Narci_XmogButton.IsOn then
Narci_XmogButtonPopUp.AnimFrame : Hide ( ) ;
Narci_XmogButtonPopUp.AnimFrame : Show ( ) ;
Narci_XmogButtonPopUp.AnimFrame . toY = - 20 ;
end
end
NarciEmoteTokenButtonMixin = { } ;
function NarciEmoteTokenButtonMixin : OnClick ( )
Narci_EmoteButton.UpdateFrame . Emote = self.Token ;
if Narci_EmoteButton.IsOn then
Narci_EmoteButton.UpdateFrame : Hide ( ) ;
Narci_EmoteButton.UpdateFrame : Show ( ) ;
end
self.AnimFrame . Anim.Bling : Play ( ) ;
end
function NarciEmoteTokenButtonMixin : OnEnter ( )
if self : IsEnabled ( ) then
local highlight = self : GetParent ( ) . HighlightColorFrame ;
highlight : SetParent ( self ) ;
highlight : ClearAllPoints ( ) ;
highlight : SetPoint ( " TOPLEFT " , self , " TOPLEFT " , 0 , 0 ) ;
highlight : SetPoint ( " BOTTOMRIGHT " , self , " BOTTOMRIGHT " , 0 , 0 ) ;
highlight : Show ( ) ;
end
Toolbar.OnEnter ( ) ;
end
function NarciEmoteTokenButtonMixin : OnLeave ( )
self : GetParent ( ) . HighlightColorFrame : Hide ( ) ;
Toolbar.OnLeave ( ) ;
end
function EmoteButtonPopUp_AnimFrame_OnUpdate ( self , elapsed )
local duration = 0.35 ;
local t = self.TimeSinceLastUpdate ;
local frame = self : GetParent ( ) ;
local offsetY = outSine ( t , self.fromY , self.toY , duration )
if not self.OppoDirection then
frame : SetAlpha ( 2 * t / duration ) ;
else
frame : SetAlpha ( 1 - 1.5 * t / duration ) ;
end
if t >= duration then
offsetY = self.toY ;
if not self.OppoDirection then
frame : SetAlpha ( 1 )
frame : Show ( )
else
frame : SetAlpha ( 0 )
frame : Hide ( )
end
self : Hide ( )
return ;
end
frame : SetPoint ( self.anchorPoint , self.relativeTo , self.relativePoint , self.toX , offsetY ) ;
self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed ;
end
function EmoteButton_UpdateFrame_OnShow ( self )
self.TimeSinceLastUpdate = 0 ;
self.duration = self.duration or 0 ;
DoEmote ( self.Emote , " none " ) ;
if self.duration == 0 then
self : Hide ( ) ;
end
if Narci_EmoteButtonPopUp.autoCapture then
After ( 0.8 , function ( )
Screenshot ( )
end )
end
end
function EmoteButton_UpdateFrame_OnUpdate ( self , elapsed )
self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed ;
if self.TimeSinceLastUpdate >= self.duration then
DoEmote ( self.Emote , " none " ) ;
self.TimeSinceLastUpdate = 0 ;
end
end
function Narci_AutoCaptureButton_OnClick ( self )
self.IsOn = not self.IsOn
if self.IsOn then
self.Tick : Show ( ) ;
self : GetParent ( ) . autoCapture = true ;
else
self.Tick : Hide ( ) ;
self : GetParent ( ) . autoCapture = false ;
end
end
function Narci_SetButtonColor ( self )
ColorUtil : SetWidgetColor ( self.Color ) ;
ColorUtil : SetWidgetColor ( self.HighlightColor ) ;
end
function Narci_HideTextsButton_OnClick ( self )
self.IsOn = not self.IsOn
NarcissusDB.PhotoModeButton . HideTexts = self.IsOn
if not self.IsOn then
PlayCheckSound ( self , false )
PhotoMode_RestoreCvar ( PhotoMode_Cvar_NamesBackup ) ;
SetTracking ( 1 , PhotoMode_Cvar_TrackingBAK ) ; --Track Battle Pet
self.Icon : SetTexCoord ( 0 , 0.5 , 0 , 1 ) ;
self.tooltip = { L [ " HideTexts Button " ] , L [ " HideTexts Button Tooltip Open " ] .. " \n |cff6b6b6b " .. L [ " HideTexts Button Tooltip Special " ] } ;
else
PlayCheckSound ( self , true )
PhotoMode_BackupCvar ( PhotoMode_Cvar_NamesBackup , PhotoMode_Cvar_NamesList ) ;
PhotoMode_ZeroCvar ( PhotoMode_Cvar_NamesBackup ) ;
PhotoMode_GetTrackingInfo ( ) ;
SetTracking ( 1 , false ) ;
self.Icon : SetTexCoord ( 0.5 , 1 , 0 , 1 ) ;
self.tooltip = { L [ " HideTexts Button " ] , L [ " HideTexts Button Tooltip Close " ] .. " \n |cff6b6b6b " .. L [ " HideTexts Button Tooltip Special " ] } ;
end
NarciTooltip : FadeOut ( ) ;
end
function TopQualityButton_OnClick ( self )
self.IsOn = not self.IsOn
if not self.IsOn then
PlayCheckSound ( self , false )
PhotoMode_RestoreCvar ( PhotoMode_Cvar_GraphicsBackup ) ;
self.Icon : SetTexCoord ( 0 , 0.5 , 0 , 1 ) ;
FadeFrame ( TopQualityButton_MSAASlider , 0.25 , 0 ) ;
TopQualityButton_RayTracingToggle : FadeOut ( ) ;
self.tooltip = { L [ " TopQuality Button " ] , L [ " TopQuality Button Tooltip Open " ] .. " \n |cff6b6b6b " .. L [ " HideTexts Button Tooltip Special " ] } ;
else
PlayCheckSound ( self , true )
PhotoMode_BackupCvar ( PhotoMode_Cvar_GraphicsBackup , PhotoMode_Cvar_GraphicsList ) ;
PhotoMode_RestoreCvar ( PhotoMode_Cvar_GraphicsList ) ;
self.Icon : SetTexCoord ( 0.5 , 1 , 0 , 1 ) ;
FadeFrame ( TopQualityButton_MSAASlider , 0.25 , 1 ) ;
TopQualityButton_RayTracingToggle : FadeIn ( ) ;
self.tooltip = { L [ " TopQuality Button " ] , L [ " TopQuality Button Tooltip Close " ] .. " \n |cff6b6b6b " .. L [ " HideTexts Button Tooltip Special " ] } ;
end
NarciTooltip : FadeOut ( ) ;
end
function TopQualityButton_MSAASlider_OnValueChanged ( self , value , userInput )
if not self : IsShown ( ) then
return ;
end
self.VirtualThumb : SetPoint ( " CENTER " , self.Thumb , " CENTER " , 0 , 0 )
if value ~= self.oldValue then
self.oldValue = value ;
local valueText ;
value , valueText = tonumber ( value ) , " " ;
if value ~= 0 then
if value == 1 then
valueText = " 2x " ;
elseif value == 2 then
valueText = " 4x " ;
elseif value == 3 then
valueText = " 8x " ;
end
valueText = " |cfffced00 " .. valueText ;
else
valueText = " |cffee3224 " .. " OFF " ;
end
self.KeyLabel2 : SetText ( MULTISAMPLE_ANTI_ALIASING .. " " .. valueText )
if userInput then
if value ~= 0 then
ConsoleExec ( " MSAAQuality " .. value .. " ,0 " )
else
ConsoleExec ( " MSAAQuality 0 " )
end
end
end
end
function CameraMover : ShowFrame ( )
local GuideLineFrame = Narci_GuideLineFrame ;
local VirtualLineRight = GuideLineFrame.VirtualLineRight ;
VirtualLineRight.AnimFrame : Hide ( ) ;
local offsetX = GuideLineFrame.VirtualLineRight . AnimFrame.defaultX or - 496 ;
VirtualLineRight : SetPoint ( " RIGHT " , offsetX + 120 , 0 ) ;
if MOG_MODE then
FadeFrame ( Narci_Attribute , 0.4 , 0 )
else
VirtualLineRight.AnimFrame . toX = offsetX ;
FadeFrame ( Narci_Attribute , 0.4 , 1 , 0 ) ;
end
VirtualLineRight.AnimFrame : Show ( ) ;
GuideLineFrame.VirtualLineLeft . AnimFrame : Show ( ) ;
PlayAttributeAnimation ( ) ;
After ( 0 , function ( )
FadeFrame ( Narci_Character , 0.6 , 1 ) ;
end )
Narci_SnowEffect ( true ) ;
end
----------------------------
--[[
Set Graphics Settings to Ultra
ffxAntiAliasingMode 2 - 3
MSAAQuality = not advanced
graphicsTextureResolution 3
graphicsTextureFiltering 6
graphicsProjectedTextures 2
graphicsViewDistance 10
graphicsEnvironmentDetail 10
graphicsGroundClutter 10
graphicsShadowQuality 6
graphicsLiquidDetail 6
graphicsSunshafts 3
graphicsParticleDensity 5
graphicsSSAO 5
graphicsDepthEffects 4
graphicsLightingQuality 3
--]]
------Photo Mode Toolbar------
NarciPhotoModeToolbarMixin = { } ;
function NarciPhotoModeToolbarMixin : OnLoad ( )
Toolbar = self ;
local animRotation = NarciAPI_CreateAnimationFrame ( 0.6 ) ;
self.animRotation = animRotation ;
animRotation : SetScript ( " OnUpdate " , function ( frame , elapsed )
local t = frame.total + elapsed ;
frame.total = t ;
local radian = outSine ( t , frame.fromRadian , frame.toRadian , frame.duration ) ;
local width = outSine ( t , frame.fromWidth , frame.toWidth , frame.duration ) ;
if t >= frame.duration then
radian = frame.toRadian ;
width = frame.toWidth ;
frame : Hide ( ) ;
if self.Switch . IsOn then
self.Bar : SetClipsChildren ( false ) ;
else
self.Bar : SetClipsChildren ( true ) ;
end
end
self.Switch . Ring : SetRotation ( radian ) ;
self.Bar : SetWidth ( width ) ;
end )
animRotation : SetScript ( " OnShow " , function ( frame )
frame.fromRadian = self.Switch . Ring : GetRotation ( ) ;
frame.fromWidth = self.Bar : GetWidth ( ) ;
end )
self.Switch . Ring : SetRotation ( 2 * pi ) ;
local animFly = NarciAPI_CreateAnimationFrame ( 0.4 ) ;
self.animFly = animFly ;
animFly : SetScript ( " OnUpdate " , function ( frame , elapsed )
local t = frame.total + elapsed ;
frame.total = t ;
local offsetY = outSine ( t , frame.fromY , frame.toY , frame.duration ) ;
if t >= frame.duration then
offsetY = frame.toY ;
frame : Hide ( ) ;
if self.shouldHide then
self : Hide ( ) ;
end
end
self : SetPoint ( " BOTTOMLEFT " , 10 , offsetY ) ;
end ) ;
local animFade = NarciAPI_CreateAnimationFrame ( 0.4 ) ;
self.animFade = animFade ;
animFade.defaultAlpha = 1 ; --visible the first time user enters Narcissus
animFade : SetScript ( " OnUpdate " , function ( frame , elapsed )
local t = frame.total + elapsed ;
frame.total = t ;
local alpha = frame.fromAlpha + frame.speed * elapsed ;
if alpha > 1 then
alpha = 1 ;
elseif alpha < 0 then
alpha = 0 ;
end
frame.fromAlpha = alpha
if t >= frame.duration then
alpha = frame.toAlpha ;
frame : Hide ( ) ;
end
self : SetAlpha ( alpha ) ;
end )
local function AutoHideContainer_OnEnter ( )
self : FadeTo ( 1 , 0.2 ) ;
end
local function AutoHideContainer_OnLeave ( )
if self : ShouldBeVisible ( ) then return end ;
self : FadeTo ( 0 , 0.2 ) ;
if not self.Switch . IsOn then
self.Bar : SetAlpha ( 0 ) ;
end
Narci_GearTexts : ClearFocus ( ) ;
Narci_GearTexts : HighlightText ( 0 , 0 ) ;
NarciTooltip : FadeOut ( ) ;
return true
end
Toolbar.OnEnter = AutoHideContainer_OnEnter ;
Toolbar.OnLeave = AutoHideContainer_OnLeave ;
local function AutoHideTimer_OnFinished ( animationGroup )
if not AutoHideContainer_OnLeave ( ) then
animationGroup : Play ( ) ;
end
end
self.AutoHideContainer : SetScript ( " OnEnter " , AutoHideContainer_OnEnter ) ;
self.AutoHideContainer : SetScript ( " OnLeave " , AutoHideContainer_OnLeave ) ;
self.AutoHideContainer . AutoHideTimer : SetScript ( " OnFinished " , AutoHideTimer_OnFinished ) ;
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciPhotoModeToolbarMixin : ShouldBeVisible ( )
return ( self.AutoHideContainer : IsMouseOver ( ) ) and not ( Narci_EquipmentOption : HasMouseFocus ( ) )
end
function NarciPhotoModeToolbarMixin : DisableAll ( )
local Bar = self.Bar ;
if Bar.Emote . IsOn then
Bar.Emote : Click ( ) ;
end
if Bar.HideTexts . IsOn then
Bar.HideTexts : Click ( ) ;
NarcissusDB.PhotoModeButton . HideTexts = true ;
end
if Bar.Xmog . IsOn then
Bar.Xmog : Click ( ) --Quit Xmog Mode
end
if Bar.TopQuality . IsOn then
Bar.TopQuality : Click ( ) ;
end
end
function NarciPhotoModeToolbarMixin : OnHide ( )
self : DisableAll ( ) ;
self : UnregisterEvent ( " PLAYER_LOGOUT " ) ;
self.animFly : Hide ( ) ;
self.animFade : Hide ( ) ;
self.AutoHideContainer . AutoHideTimer : Stop ( ) ;
end
function NarciPhotoModeToolbarMixin : OnShow ( )
self : RegisterEvent ( " PLAYER_LOGOUT " ) ;
ColorUtil : UpdateByMapID ( ) ;
self.AutoHideContainer : Show ( ) ;
end
function NarciPhotoModeToolbarMixin : OnEvent ( event )
self : DisableAll ( ) ;
SetCVar ( " Sound_MusicVolume " , CVarTemp.MusicVolume ) ;
if CVarTemp.DynamicPitch ~= 1 then --Restore the acioncam state
SetCVar ( " test_cameraDynamicPitch " , 0 ) ;
ConsoleExec ( " actioncam off " ) ;
end
ViewProfile : ResetView ( 5 ) ;
end
function NarciPhotoModeToolbarMixin : FadeTo ( toAlpha , duration )
--Only changes alpha not show/hide status
local f = self.animFade ;
f : Hide ( ) ;
f.total = 0 ;
f.fromAlpha = self : GetAlpha ( ) ;
duration = duration or 0.4 ;
f.duration = duration ;
local delta = toAlpha - f.fromAlpha ;
if delta > 0 then
f.speed = 1 / duration ;
elseif delta < 0 then
f.speed = - 1 / duration ;
else
return
end
if self : ShouldBeVisible ( ) then
f.toAlpha = 1 ;
else
f.toAlpha = toAlpha or f.defaultAlpha ;
end
if f.defaultAlpha == 1 then
if NarcissusDB.LetterboxEffect then
f.toAlpha = 0 ;
end
f.defaultAlpha = 0 ;
end
f : Show ( ) ;
end
function NarciPhotoModeToolbarMixin : FlyIn ( toAlpha )
local f = self.animFly ;
f : Hide ( ) ;
f.total = 0 ;
f.fromY = - 80 ;
f.toY = 10 ;
f : Show ( ) ;
self.shouldHide = nil ;
self : Show ( ) ;
self : FadeTo ( toAlpha or self.animFade . defaultAlpha or 1 ) ;
self.AutoHideContainer . AutoHideTimer : Play ( ) ;
end
function NarciPhotoModeToolbarMixin : FlyOut ( )
local f = self.animFly ;
if f.toY == - 80 then
return
end
f : Hide ( ) ;
f.total = 0 ;
f.fromY = 10 ;
f.toY = - 80 ;
self.shouldHide = true ;
f : Show ( ) ;
self : FadeTo ( 0 ) ;
end
function NarciPhotoModeToolbarMixin : UseLowerLevel ( state )
local strata ;
if state then
strata = " BACKGROUND " ;
self : DisableMotion ( ) ;
else
strata = " HIGH " ;
self : EnableMotion ( ) ;
end
self : SetFrameStrata ( strata ) ;
self.PreferenceToggle : SetFrameStrata ( strata ) ;
self.AutoHideContainer : SetFrameStrata ( " LOW " ) ;
self.MotionBlock : SetFrameStrata ( " BACKGROUND " ) ;
self.MotionBlock : SetFrameLevel ( self : GetFrameLevel ( ) + 3 ) ;
self.MotionBlock : SetShown ( state ) ;
end
function NarciPhotoModeToolbarMixin : DisableMotion ( )
self.AutoHideContainer : Hide ( ) ;
self : SetAlpha ( 0 ) ;
end
function NarciPhotoModeToolbarMixin : EnableMotion ( )
self.AutoHideContainer : Show ( ) ;
end
function Narci_PhotoModeButton_OnClick ( self , key )
self.IsOn = not self.IsOn ;
local updateFrame = self : GetParent ( ) . animRotation ;
updateFrame : Hide ( ) ;
local barWidth = self : GetParent ( ) . Bar : GetWidth ( ) ;
if self.IsOn then
updateFrame.duration = math.min ( 0.6 , math.sqrt ( 0.4 * ( 220 - barWidth ) / 180 ) ) ;
updateFrame.toRadian = 1.25 * pi ;
updateFrame.toWidth = 220 ;
else
updateFrame.duration = math.min ( 0.6 , math.sqrt ( 0.4 * ( barWidth - 40 ) / 180 ) ) ;
updateFrame.toRadian = 2 * pi ;
updateFrame.toWidth = 40 ;
end
updateFrame : Show ( ) ;
if self.IsOn then
self.Icon : SetTexCoord ( 0.25 , 0.5 , 0.75 , 1 ) ;
Toolbar.Bar : SetAlpha ( 1 )
else
self.Icon : SetTexCoord ( 0 , 0.25 , 0.75 , 1 ) ;
Toolbar.Bar : SetClipsChildren ( true ) ;
end
NarciTooltip : FadeOut ( ) ;
TemporarilyHidePopUp ( Narci_XmogButtonPopUp ) ;
TemporarilyHidePopUp ( Narci_EmoteButtonPopUp ) ;
end
hooksecurefunc ( " SetUIVisibility " , function ( state )
if IS_OPENED then --when Narcissus hide the UI
if state then
MsgAlertContainer : SetDND ( true ) ;
Toolbar : UseLowerLevel ( true ) ;
else
if NarcissusDB.PhotoModeButton . HideTexts and ( not Narci_HideTextsButton.IsOn ) then
Narci_HideTextsButton : Click ( ) ;
end
local bar = Toolbar ;
Toolbar.ExitButton : Show ( ) ;
if not bar : IsShown ( ) then
bar : Show ( ) ;
end
MsgAlertContainer : SetDND ( false ) ;
bar : UseLowerLevel ( false ) ;
end
else --when user hide the UI manually
if state then
--When player closes the full-screen world map, SetUIVisibility(true) fires twice, and WorldMapFrame:IsShown() returns true and false.
--Thus, use this VisibilityTracker instead to check if WorldMapFrame has been closed recently.
--WorldMapFrame.VisibilityTracker.state
MsgAlertContainer : Hide ( ) ;
if Narci_Character : IsShown ( ) then return ; end
SmoothShoulderCVar ( CVarTemp.OverShoulder ) ;
if not GetKeepActionCam ( ) then
After ( 0.6 , function ( )
ConsoleExec ( " actioncam off " ) ;
end )
end
if Toolbar : IsShown ( ) then
Toolbar : FlyOut ( ) ;
NarciCameraOffsetControlBar.Thumb : SetPoint ( " CENTER " , 0 , 0 ) ;
end
else
local bar = Toolbar ;
if not bar : IsShown ( ) then
CVarTemp.OverShoulder = GetCVar ( " test_cameraOverShoulder " ) ;
end
bar : FlyIn ( 0 ) ;
bar.ExitButton : Hide ( ) ;
if NarcissusDB.PhotoModeButton . HideTexts and ( not Narci_HideTextsButton.IsOn ) then
Narci_HideTextsButton : Click ( ) ;
end
Narci_XmogButton : Disable ( ) ;
end
end
end )
SLASH_NARCI1 = " /narci " ;
SLASH_NARCI2 = " /narcissus " ;
SlashCmdList [ " NARCI " ] = function ( msg )
msg = string.lower ( msg ) ;
if msg == " " then
MiniButton : Click ( ) ;
elseif msg == " minimap " then
MiniButton : EnableButton ( ) ;
print ( " Minimap button has been re-enabled. " ) ;
elseif msg == " itemlist " then
DressUpFrame_Show ( DressUpFrame ) ;
elseif msg == " parser " then
FadeFrame ( Narci_ItemParser , 0.25 , 1 ) ;
elseif msg == " resetposition " then
MiniButton : ResetPosition ( ) ;
else
local color = " |cff40C7EB " ;
print ( color .. " Show Minimap Button:|r /narci minimap " ) ;
print ( color .. " Reset Minimap Button Position:|r /narci resetposition " ) ;
print ( color .. " Copy Item List:|r /narci itemlist " ) ;
print ( color .. " Corruption Item Parser:|r /narci parser " ) ;
end
end
function Narci_ModelToggle_OnClick ( self )
self : Disable ( )
After ( 1 , function ( )
self : Enable ( )
end )
self.AnimFrame . Anim : SetScale ( 1.5 )
self.AnimFrame . Anim.Bling : Play ( ) ;
NarcissusDB.AlwaysShowModel = not NarcissusDB.AlwaysShowModel ;
self.IsOn = NarcissusDB.AlwaysShowModel ;
self.Tick : SetShown ( self.IsOn ) ;
Narci_AlwaysShowModelToggle.Tick : SetShown ( self.IsOn ) ;
if self.IsOn and xmogMode == 1 then
if not NarciPlayerModelFrame1 : IsVisible ( ) then
if xmogMode == 1 then
NarciModel_RightGradient : Hide ( ) ;
end
Narci_PlayerModelAnimIn : Show ( )
end
elseif xmogMode ~= 2 then
HidePlayerModel ( )
end
end
function Narci_XmogLayoutButton_OnClick ( self )
self : Disable ( )
After ( 0.8 , function ( )
self : Enable ( )
end )
self.ShowModel = not self.ShowModel ;
if self.ShowModel then
UseXmogLayout ( 2 )
else
UseXmogLayout ( 1 )
end
self.AnimFrame . Anim : SetScale ( 1.5 )
self.AnimFrame . Anim.Bling : Play ( )
end
local function HideContollerButton ( state )
if state then
Narci_XmogButton : Hide ( )
Narci_EmoteButton : Hide ( )
Narci_HideTextsButton : Hide ( )
Narci_TopQualityButton : Hide ( )
else
Narci_XmogButton : Show ( )
Narci_EmoteButton : Show ( )
Narci_HideTextsButton : Show ( )
Narci_TopQualityButton : Show ( )
end
end
function PhotoMode_WheelEventContrainer_OnMouseWheel ( self , delta )
if Narci_PhotoModeButton.IsOn then
if NarciCameraOffsetControlBar : IsShown ( ) then
CameraControlBar_ResetPosition ( true )
end
TemporarilyHidePopUp ( Narci_XmogButtonPopUp ) ;
TemporarilyHidePopUp ( Narci_EmoteButtonPopUp ) ;
AnimationSequenceContainer_Controller : Hide ( )
AnimationSequenceContainer_Controller : Show ( )
end
end
local function TemporarilyDisableWheel ( frame )
frame : SetScript ( " OnMouseWheel " , function ( self , delta )
end )
After ( 0.2 , function ( )
frame : SetScript ( " OnMouseWheel " , PhotoMode_WheelEventContrainer_OnMouseWheel )
end )
end
----------------
--3D Animation--
local ASC = CreateFrame ( " Frame " , " AnimationSequenceContainer_Controller " ) ;
ASC : Hide ( ) ;
local function InitializeAnimationContainer ( frame , SequenceInfo , TargetFrame )
frame.OppoDirection = false ;
frame.t = 0
frame.totalTime = 0 ;
frame.Index = 1 ;
frame.Pending = false ;
frame.IsPlaying = false ;
frame.SequenceInfo = SequenceInfo ;
frame.Target = TargetFrame
end
local function AnimationContainer_OnHide ( self )
self.totalTime = 0 ;
self.TimeSinceLastUpdate = 0 ;
self.OppoDirection = not self.OppoDirection
if self.Index <= 0 then
self.Index = 0 ;
end
end
local PlayAnimationSequence = NarciAPI_PlayAnimationSequence ;
local function Controller_AnimationSequence_OnUpdate ( self , elapsed )
if self.Pending then
return ;
end
self.t = self.t + elapsed ;
self.totalTime = self.totalTime + elapsed ;
if self.t >= 0.01666 then
self.t = 0 ;
if self.OppoDirection then
self.Index = self.Index - 1 ;
else
self.Index = self.Index + 1 ;
end
if not PlayAnimationSequence ( self.Index , self.SequenceInfo , self.Target ) then
Narci_PhotoModeButton : SetAlpha ( 1 ) ;
Toolbar.Bar : SetAlpha ( 1 ) ;
if self.OppoDirection then
FadeFrame ( PhotoModeControllerTransition.Sequence , 0.2 , 0 )
HideContollerButton ( false )
Narci_PhotoModeButton : SetAlpha ( 1 ) ;
Toolbar.Bar : SetAlpha ( 1 ) ;
NarciCameraOffsetControlBar : Hide ( )
else
HideContollerButton ( true )
NarciCameraOffsetControlBar : Show ( )
NarciCameraOffsetControlBar : SetAlpha ( 1 ) ;
FadeFrame ( PhotoModeControllerTransition.Sequence , 0.2 , 0 )
After ( 0.25 , function ( )
CameraControlBar_ResetPosition ( false )
end )
end
TemporarilyDisableWheel ( PhotoMode_WheelEventContrainer ) ;
self : Hide ( )
self.IsPlaying = false ;
return ;
end
--NarciCameraOffsetControlBar:SetAlpha(0);
Narci_PhotoModeButton : SetAlpha ( 0 ) ;
Toolbar.Bar : SetAlpha ( 0 ) ;
end
end
ASC : SetScript ( " OnUpdate " , Controller_AnimationSequence_OnUpdate )
ASC : SetScript ( " OnHide " , AnimationContainer_OnHide )
ASC : SetScript ( " OnShow " , function ( self )
self.IsPlaying = true ;
end )
local ASC2 = CreateFrame ( " Frame " , " AnimationSequenceContainer_Heart " ) ;
ASC2.Delay = 5 ;
ASC2.IsPlaying = false ;
ASC2 : Hide ( ) ;
local function Generic_AnimationSequence_OnUpdate ( self , elapsed )
if self.Pending then
return ;
end
self.totalTime = self.totalTime + elapsed ;
if ( not self.OppoDirection and self.totalTime < self.Delay ) and ( not self.IsPlaying ) then
return ;
elseif not self.IsPlaying then
if not self.OppoDirection then --box closing
FadeFrame ( Narci_HeartofAzeroth_AnimFrame , 0.25 , 1 )
After ( 0.3 , function ( )
Narci_HeartofAzeroth_AnimFrame.Background : SetAlpha ( 1 ) ;
Narci_HeartofAzeroth_AnimFrame.Quote : SetAlpha ( 1 ) ;
Narci_HeartofAzeroth_AnimFrame.SN : SetAlpha ( 1 ) ;
end )
end
self.IsPlaying = true ;
end
self.t = self.t + elapsed ;
if self.t >= 0.01666 then
self.t = 0 ;
if self.OppoDirection then
self.Index = self.Index - 1 ;
else
self.Index = self.Index + 1 ;
end
if not PlayAnimationSequence ( self.Index , self.SequenceInfo , self.Target ) then
self : Hide ( )
self.IsPlaying = false ;
if not self.OppoDirection then
Narci_HeartofAzeroth_AnimFrame.Background : SetAlpha ( 0 ) ;
Narci_HeartofAzeroth_AnimFrame.Quote : SetAlpha ( 0 ) ;
Narci_HeartofAzeroth_AnimFrame.SN : SetAlpha ( 0 ) ;
FadeFrame ( Narci_HeartofAzeroth_AnimFrame , 0.25 , 0 )
end
return ;
end
end
end
ASC2 : SetScript ( " OnUpdate " , Generic_AnimationSequence_OnUpdate ) ;
ASC2 : SetScript ( " OnHide " , AnimationContainer_OnHide ) ;
function CameraControlBar_ResetPosition_AnimFrame_OnShow ( self )
local StartX = NarciCameraOffsetControlBar.PosX or 0 ;
local StartAngle = NarciCameraOffsetControlBar.PosRadian or 0 ;
self.tOut = max ( math.abs ( StartX ) / NarciCameraOffsetControlBar.Range , math.abs ( StartAngle ) / ( 2 * pi ) , 0.2 )
end
function CameraControlBar_ResetPosition_AnimFrame_OnUpdate ( self , elapsed )
AnimationSequenceContainer_Controller.Pending = true ;
self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed
local StartX , EndX , StartAngle , EndAngle , t ;
if self.OppoDirection then
StartX = NarciCameraOffsetControlBar.PosX or 0 ;
EndX = 0 ;
StartAngle = NarciCameraOffsetControlBar.PosRadian or 0 ;
EndAngle = 0 ;
t = self.tOut
else
StartX = 0 ;
EndX = NarciCameraOffsetControlBar.PosX or 0 ;
StartAngle = 0 ;
EndAngle = NarciCameraOffsetControlBar.PosRadian or 0 ; --NarciCameraOffsetControlBar.PosRadian or
t = 0.5
end
local Value_Angle = outSine ( self.TimeSinceLastUpdate , StartAngle , EndAngle , t )
local Value_X = outSine ( self.TimeSinceLastUpdate , StartX , EndX , t )
RotateShaftNode ( Value_Angle )
CameraControllerThumb : SetPoint ( " CENTER " , Value_X , 0 ) ;
if self.TimeSinceLastUpdate >= t then
RotateShaftNode ( EndAngle )
CameraControllerThumb : SetPoint ( " CENTER " , EndX , 0 ) ;
self : Hide ( ) ;
AnimationSequenceContainer_Controller.Pending = false ;
NarciCameraOffsetControlBar.PosRadian = 0 ;
end
end
function CameraControlBar_ResetPosition ( bool )
if NarciCameraOffsetControlBar : IsShown ( ) and ( not AnimationSequenceContainer_Controller.IsPlaying ) then
CameraControlBar_ResetPosition_AnimFrame.OppoDirection = bool
AnimationSequenceContainer_Controller.Pending = true ;
CameraControlBar_ResetPosition_AnimFrame : Show ( ) ;
end
end
local raceList = { --For 3D Portait on the top-left
--[RaceID] = {[GenderID] = {offsetX, offsetY, distance, angle, CameraIndex, {animation} }}
[ 1 ] = { [ 2 ] = { 10 , - 10 , 0.75 , false , 0 } , --Human Male √
[ 3 ] = { 12 , - 10 , 0.71 , false , 1 , 2 } , -- Female √
} ,
[ 2 ] = { [ 2 ] = { 12 , - 16 , 1.3 , 1.1 , 0 } , --Orcs Male √
[ 3 ] = { 18 , - 16 , 0.72 , 1.1 , 0 , 1 } , -- Female √
} ,
[ 3 ] = { [ 2 ] = { 14 , - 20 , 0.88 , 0.9 , 1 } , --Dwarf Male
[ 3 ] = { 2 , - 12 , 0.75 , false , 0 } , -- Female √
} ,
[ 4 ] = { [ 2 ] = { 16 , - 5 , 1 , 1.5 , 0 } , --NE Male
[ 3 ] = { 8 , - 10 , 0.75 , false , 0 } , -- Female
} ,
[ 5 ] = { [ 2 ] = { 16 , - 6 , 0.6 , 0.8 , 1 } , --UD Male
[ 3 ] = { 10 , - 6 , 0.68 , 1.0 , 1 , 3 } , -- Female
} ,
[ 6 ] = { [ 2 ] = { 24 , - 15 , 3 , 0.6 , 1 } , --Tauren Male √
[ 3 ] = { 24 , - 8 , 1.8 , false , 1 } , -- Female
} ,
[ 7 ] = { [ 2 ] = { 10 , - 14 , 1 , 0.5 , 1 } , --Gnome Male
[ 3 ] = { 14 , - 14 , 0.8 , 0.55 , 0 } , -- Female
} ,
[ 8 ] = { [ 2 ] = { 16 , - 4 , 1.15 , 1.3 , 0 } , --Troll Male √
[ 3 ] = { 18 , - 10 , 0.75 , 1.3 , 0 } , -- Female √
} ,
[ 9 ] = { [ 2 ] = { 8 , 0 , 0.8 , 0.6 , 0 } , --Goblin Male √
[ 3 ] = { 20 , - 14 , 0.85 , 0.8 , 0 } , -- Female √
} ,
[ 10 ] = { [ 2 ] = { 8 , - 5 , 0.75 , 1.2 , 0 } , -- BE Male
[ 3 ] = { 0 , - 4 , 0.53 , 1.1 , 0 } , -- Female
} ,
[ 11 ] = { [ 2 ] = { 15 , - 12 , 1 , 1.4 , 0 } , -- Goat Male
[ 3 ] = { 10 , - 10 , 0.66 , 1.4 , 0 } , -- Female
} ,
[ 22 ] = { [ 2 ] = { 10 , - 10 , 0.75 , false , 0 } , --Worgen Male Human Form
[ 3 ] = { 12 , - 12 , 0.72 , 1.1 , 1 } , --Female √
} ,
[ 24 ] = { [ 2 ] = { 14 , 0 , 1.1 , 1.15 , 0 } , --Pandaren Male √
[ 3 ] = { 12 , 4 , 1.0 , 1.1 , 0 } , --Female
} ,
[ 27 ] = { [ 2 ] = { 24 , - 10 , 0.72 , false , 0 } , --Highborne Male √
[ 3 ] = { 16 , - 4 , 0.70 , false , 0 } , --Female
} ,
[ 28 ] = { [ 2 ] = { 24 , - 15 , 2.4 , 0.6 , 0 } , --Tauren Male √
[ 3 ] = { 4 , - 10 , 0.62 , false , 0 } , -- Female
} ,
[ 128 ] = { [ 2 ] = { 18 , - 18 , 1.4 , 0.85 , 0 } , --Worgen Male Wolf Form
[ 3 ] = { 18 , - 15 , 1.1 , 1.25 , 0 } , --Female √
} ,
[ 31 ] = { [ 2 ] = { 4 , 0 , 1.2 , 1.6 , 0 } , --Zandalari Male √
[ 3 ] = { 18 , - 12 , 0.95 , 1.6 , 0 } , -- Female √
} ,
[ 32 ] = { [ 2 ] = { 10 , - 16 , 1.25 , 1.15 , 1 } , --Kul'tiran Male √
[ 3 ] = { 12 , - 10 , 0.9 , 1.5 , 0 } , --Female
} ,
[ 36 ] = { [ 2 ] = { 14 , - 10 , 1.2 , 1.2 , 0 , 2 } , --Mag'har Male
[ 3 ] = { 20 , - 20 , 0.75 , false , 0 , 1 } , -- Female √
} ,
[ 35 ] = { [ 2 ] = { 18 , - 8 , 0.7 , false , 1 , 2 } , --Vulpera Male
[ 3 ] = { 18 , - 8 , 0.7 , false , 1 , 2 } , -- Female √
} ,
}
function Narci_PortraitPieces_OnLoad ( self )
local unit = " player " ;
local a1 , a2 , a3 ;
local ModelPieces = self.Pieces ;
local _ , _ , raceID = UnitRace ( unit ) ;
local GenderID = UnitSex ( unit ) ;
--print("raceID: "..raceID)
if raceID == 34 then --DarkIron
raceID = 3 ;
elseif raceID == 29 then --VE
raceID = 10
elseif raceID == 28 then --Highmountain
raceID = 6
elseif raceID == 30 then --LightForged
raceID = 11
elseif raceID == 25 or raceID == 26 then --Pandaren A|H
raceID = 24
elseif raceID == 37 then --Mechagnome
raceID = 7 ;
elseif raceID == 22 then --Worgen
local _ , inAlternateForm = GetAlternateFormInfo ( ) ;
if not inAlternateForm then
raceID = 128 ;
end
end
local model ;
if raceList [ raceID ] and raceList [ raceID ] [ GenderID ] then
if Narci_FigureModelReference then
Narci_FigureModelReference : SetPoint ( " CENTER " , raceList [ raceID ] [ GenderID ] [ 1 ] , raceList [ raceID ] [ GenderID ] [ 2 ] )
end
for i = 1 , # ModelPieces do
model = ModelPieces [ i ] ;
model : SetUnit ( unit ) ;
model : SetCamera ( raceList [ raceID ] [ GenderID ] [ 5 ] ) ;
model : MakeCurrentCameraCustom ( ) ;
if raceList [ raceID ] [ GenderID ] [ 3 ] then
model : SetCameraDistance ( raceList [ raceID ] [ GenderID ] [ 3 ] )
end
if raceList [ raceID ] [ GenderID ] [ 4 ] then
a1 , a2 , a3 = model : GetCameraPosition ( ) ;
model : SetCameraPosition ( a1 , a2 , raceList [ raceID ] [ GenderID ] [ 4 ] )
end
if raceList [ raceID ] [ GenderID ] [ 6 ] then
model : SetAnimation ( 2 , raceList [ raceID ] [ GenderID ] [ 6 ] )
end
end
else
for i = 1 , # ModelPieces do
model = ModelPieces [ i ] ;
model : SetCamera ( 0 ) ;
model : MakeCurrentCameraCustom ( ) ;
a1 , a2 , a3 = model : GetCameraPosition ( ) ;
model : SetCameraPosition ( a1 , a2 , 1.1 ) ;
end
end
for i = 1 , # ModelPieces do
model = ModelPieces [ i ] ;
model : SetFacing ( - math.pi / 24 ) --Front pi/6
model : SetAnimation ( 804 , 1 ) ;
model : SetLight ( true , false , - 0.44699833180028 , 0.72403680806459 , - 0.52532198881773 , 0.8 , 0.7 , 0.5 , 0.8 , 1 , 0.8 , 0.8 , 0.8 )
model : UndressSlot ( 1 ) ;
model : UndressSlot ( 3 ) ;
model : UndressSlot ( 15 ) ; --Remove the cloak
model : UndressSlot ( 16 ) ;
model : UndressSlot ( 17 ) ;
end
end
--Static Events
EL : RegisterEvent ( " ADDON_LOADED " ) ;
EL : RegisterEvent ( " PLAYER_ENTERING_WORLD " ) ;
EL : RegisterEvent ( " UNIT_NAME_UPDATE " ) ;
EL : RegisterEvent ( " PLAYER_AVG_ITEM_LEVEL_UPDATE " ) ;
EL : RegisterEvent ( " ACTIVE_TALENT_GROUP_CHANGED " ) ;
EL : RegisterEvent ( " PLAYER_LEVEL_CHANGED " ) ;
--These events might become deprecated in future expansions
EL : RegisterEvent ( " COVENANT_CHOSEN " ) ;
EL : RegisterEvent ( " COVENANT_SANCTUM_RENOWN_LEVEL_CHANGED " ) ;
EL : SetScript ( " OnEvent " , function ( self , event , ... )
--print(event)
if event == " ADDON_LOADED " then
local name = ... ;
if name ~= " Narcissus " then
return ;
end
self : UnregisterEvent ( event ) ;
AssignFrame ( ) ;
AssignFrame = nil ;
ShowDetailedIlvlInfo ( ) ;
After ( 2 , function ( )
Narci_AliasButton_SetState ( ) ;
Narci_SetActiveBorderTexture ( ) ;
StatsUpdator : Instant ( ) ;
RadarChart : SetValue ( 0 , 0 , 0 , 0 , 1 ) ;
UpdateXmogName ( ) ;
end )
local AnimSequenceInfo = Narci.AnimSequenceInfo ;
InitializeAnimationContainer ( ASC2 , AnimSequenceInfo [ " Heart " ] , Narci_HeartofAzeroth_AnimFrame.Sequence )
InitializeAnimationContainer ( ASC , AnimSequenceInfo [ " Controller " ] , PhotoModeControllerTransition.Sequence )
local HeartSerialNumber = strsub ( UnitGUID ( " player " ) , 8 , 15 ) ;
Narci_HeartofAzeroth_AnimFrame.SN : SetText ( " No. " .. HeartSerialNumber ) ;
--[[
local timeStart = Narci.timeLoadingStart ;
local timeFinished = GetTimePreciseSec ( ) ;
print ( " Loading Time: " .. ( timeFinished - timeStart ) )
--]]
elseif event == " PLAYER_ENTERING_WORLD " then
self : UnregisterEvent ( event ) ;
MiniButton : InitPosition ( ) ;
UpdateXmogName ( ) ;
SetCVar ( " CameraKeepCharacterCentered " , 0 ) ;
--CameraMover:SetBlend(NarcissusDB.CameraTransition); --Load in Preference.lua
DefaultTooltip = NarciGameTooltip ; --Created in NarciAPI.lua
DefaultTooltip : SetParent ( Narci_Character ) ;
DefaultTooltip : SetFrameStrata ( " TOOLTIP " ) ;
DefaultTooltip.offsetX = 6 ;
DefaultTooltip.offsetY = - 18 ;
DefaultTooltip : SetIgnoreParentScale ( true ) ;
DefaultTooltip : SetIgnoreParentAlpha ( true ) ;
local HotkeyFrame = CreateFrame ( " Frame " , nil , Narci_Attribute , " NarciHotkeyNotificationTemplate " ) ;
HotkeyFrame : SetKey ( NARCI_MODIFIER_ALT , " LeftButton " , L [ " Swap items " ] ) ;
HotkeyFrame : SetPoint ( " BOTTOM " , DefaultTooltip , " TOP " , - 2 , 8 ) ;
HotkeyFrame : SetFrameStrata ( " TOOLTIP " ) ;
HotkeyFrame : SetIgnoreParentScale ( true ) ;
DefaultTooltip.HotkeyFrame = HotkeyFrame ;
DefaultTooltip : HookScript ( " OnHide " , function ( )
HotkeyFrame : FadeOut ( ) ;
end )
MiniButton : SetBackground ( ) ;
if IsAddOnLoaded ( " DynamicCam " ) then
CVarTemp.isDynamicCamLoaded = true ;
--Check validity
if not ( DynamicCam.BlockShoulderOffsetZoom and DynamicCam.AllowShoulderOffsetZoom ) then return end ;
hooksecurefunc ( " Narci_Open " , function ( )
if IS_OPENED then
DynamicCam : BlockShoulderOffsetZoom ( ) ;
else
DynamicCam : AllowShoulderOffsetZoom ( ) ;
end
end )
hooksecurefunc ( " Narci_OpenGroupPhoto " , function ( )
DynamicCam : BlockShoulderOffsetZoom ( ) ;
end )
ViewProfile : Disable ( ) ;
end
After ( 1.7 , function ( )
UpdateCharacterInfoFrame ( ) ;
hooksecurefunc ( " CameraZoomIn " , function ( increment )
if IS_OPENED and ( xmogMode ~= 1 ) then
UpdateShoulderCVar : Start ( - increment , true ) ;
end
end )
hooksecurefunc ( " CameraZoomOut " , function ( increment )
if IS_OPENED and ( xmogMode ~= 1 ) then
UpdateShoulderCVar : Start ( increment , true ) ;
end
end )
end )
--Cache
if false then
MiniButton : Disable ( ) ; --Disable minimap button while caching
After ( 1.3 , function ( )
CacheSourceInfo ( ) ;
end )
After ( 2.9 , function ( )
MOG_MODE = true ;
USE_DELAY = true ;
SlotController : RefreshAll ( ) ; --Cache transmog appearance sources
end )
After ( 3.7 , function ( )
MOG_MODE = false ;
SlotController : RefreshAll ( ) ;
MiniButton : Enable ( ) ;
MiniButton : SetMotionScriptsWhileDisabled ( false ) ;
end )
end
elseif event == " PLAYER_EQUIPMENT_CHANGED " then
local slotID , isItem = ... ;
--CacheSourceInfo(slotID)
USE_DELAY = false ;
SlotController : Refresh ( slotID ) ;
if EquipmentFlyoutFrame : IsShown ( ) and EquipmentFlyoutFrame.slotID == slotID then
EquipmentFlyoutFrame : DisplayItemsBySlotID ( slotID , false ) ;
end
USE_DELAY = true ;
ItemLevelFrame : UpdateDomination ( ) ;
elseif event == " AZERITE_ESSENCE_ACTIVATED " then
local neckSlotID = 2 ;
SlotController : Refresh ( neckSlotID ) ; --Heart of Azeroth
elseif event == " PLAYER_AVG_ITEM_LEVEL_UPDATE " then
if not self.isRefreshing then
self.isRefreshing = true ;
After ( 0 , function ( ) -- only want 1 update per 0.1s
ItemLevelFrame : Update ( ) ;
After ( 0.1 , function ( )
self.isRefreshing = nil ;
end )
end )
end
elseif event == " COVENANT_CHOSEN " then
local covenantID = ... ;
ItemLevelFrame : Update ( ) ;
MiniButton : SetBackground ( covenantID ) ;
elseif event == " COVENANT_SANCTUM_RENOWN_LEVEL_CHANGED " then
local newRenownLevel = ... ;
ItemLevelFrame : UpdateRenownLevel ( newRenownLevel ) ;
elseif event == " UNIT_NAME_UPDATE " then
local unit = ... ;
if unit == " player " then
UpdateCharacterInfoFrame ( ) ;
end
elseif event == " ACTIVE_TALENT_GROUP_CHANGED " then
UpdateCharacterInfoFrame ( ) ;
UpdateXmogName ( true ) ;
elseif event == " PLAYER_LEVEL_CHANGED " then
local oldLevel , newLevel = ... ;
UpdateCharacterInfoFrame ( newLevel )
elseif ( event == " COMBAT_RATING_UPDATE " or
event == " UNIT_MAXPOWER " or
event == " UNIT_STATS " or
event == " UNIT_DAMAGE " or event == " UNIT_ATTACK_SPEED " or event == " UNIT_MAXHEALTH " or event == " UNIT_AURA "
) and Narci.refreshCombatRatings then
-- don't refresh stats when equipment set manager is activated
StatsUpdator : Instant ( ) ;
if event == " COMBAT_RATING_UPDATE " then
if Narci_Character : IsShown ( ) then
RadarChart : AnimateValue ( ) ;
end
end
elseif event == " PLAYER_TARGET_CHANGED " then
RefreshStats ( 8 ) ; --Armor
RefreshStats ( 9 ) ; --Damage Reduction
elseif event == " UPDATE_SHAPESHIFT_FORM " then
ModifyCameraForShapeshifter ( ) ;
CameraMover : OnCameraChanged ( ) ;
elseif event == " PLAYER_MOUNT_DISPLAY_CHANGED " then
ModifyCameraForMounts ( ) ;
CameraMover : OnCameraChanged ( ) ;
elseif event == " PLAYER_REGEN_DISABLED " then
if Narci.isAFK and Narci.isActive then
--exit when entering combat during AFK mode
MiniButton : Click ( ) ;
Narci : PlayVoice ( " DANGER " ) ;
end
elseif event == " PLAYER_STARTED_MOVING " then
self : UnregisterEvent ( event ) ;
MoveViewRightStop ( ) ;
if Narci.isAFK and Narci.isActive then
--exit when entering combat during AFK mode
MiniButton : Click ( ) ;
end
elseif event == " PLAYER_STARTED_TURNING " and not MOG_MODE then
NarciAR.Turning . radian = GetPlayerFacing ( ) ;
NarciAR.Turning : Show ( ) ;
elseif event == " PLAYER_STOPPED_TURNING " and not MOG_MODE then
NarciAR.Turning : Hide ( ) ;
elseif event == " BAG_UPDATE_COOLDOWN " then
StatsUpdator : UpdateCooldown ( ) ;
elseif event == " BAG_UPDATE " then
local newTime = GetTime ( ) ;
if self.lastTime then
if newTime > self.lastTime + 0.2 then
self.lastTime = newTime ;
else
return
end
else
self.lastTime = newTime ;
end
ItemLevelFrame : UpdateDomination ( ) ;
elseif event == " UNIT_INVENTORY_CHANGED " then
SlotController : LazyRefresh ( " temp " ) ;
end
end )
function EL : ToggleDynamicEvents ( state )
local dynamicEvents = { " PLAYER_TARGET_CHANGED " , " COMBAT_RATING_UPDATE " , " PLAYER_MOUNT_DISPLAY_CHANGED " ,
" PLAYER_STARTED_MOVING " , " PLAYER_REGEN_DISABLED " , " UNIT_MAXPOWER " , " PLAYER_STARTED_TURNING " , " PLAYER_STOPPED_TURNING " ,
" BAG_UPDATE_COOLDOWN " , " UNIT_STATS " , " BAG_UPDATE " , " PLAYER_EQUIPMENT_CHANGED " , " AZERITE_ESSENCE_ACTIVATED " ,
} ;
local unitEvents = { " UNIT_DAMAGE " , " UNIT_ATTACK_SPEED " , " UNIT_MAXHEALTH " , " UNIT_AURA " , " UNIT_INVENTORY_CHANGED " } ;
if state then
for i = 1 , # dynamicEvents do
self : RegisterUnitEvent ( dynamicEvents [ i ] ) ;
end
for i = 1 , # unitEvents do
self : RegisterUnitEvent ( unitEvents [ i ] , " player " ) ;
end
else
for i = 1 , # dynamicEvents do
self : UnregisterEvent ( dynamicEvents [ i ] ) ;
end
for i = 1 , # unitEvents do
self : UnregisterEvent ( unitEvents [ i ] ) ;
end
end
dynamicEvents = nil ;
unitEvents = nil ;
end
EL : SetScript ( " OnShow " , function ( self )
self : ToggleDynamicEvents ( true ) ;
if NarciAR then
NarciAR : Show ( ) ;
end
end )
EL : SetScript ( " OnHide " , function ( self )
self : ToggleDynamicEvents ( false ) ;
self : UnregisterEvent ( " UPDATE_SHAPESHIFT_FORM " ) ;
if NarciAR then
NarciAR : Hide ( ) ;
end
end )
----------------------------------------------------------------------
--Double-click PaperDoll Button to open Narcissus
NarciPaperDollDoubleClickTriggerMixin = { } ;
local function Narci_DoubleClickTrigger_OnUpdate ( self , elapsed )
self.t = self.t + elapsed ;
if self.t > 0.25 then
self : SetScript ( " OnUpdate " , nil ) ;
end
end
function NarciPaperDollDoubleClickTriggerMixin : OnLoad ( )
self.t = 0 ;
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciPaperDollDoubleClickTriggerMixin : OnShow ( )
self.t = 0 ;
self : SetScript ( " OnUpdate " , Narci_DoubleClickTrigger_OnUpdate ) ;
end
function NarciPaperDollDoubleClickTriggerMixin : OnHide ( )
if ( self.t < 0.25 ) and NarcissusDB.EnableDoubleTap then
MiniButton : Click ( ) ;
end
end
----------------------------------------------------------------------
function Narci_SetActiveBorderTexture ( )
local themeName = NarciAPI.GetBorderThemeName ( ) ;
local MinimapButton = MiniButton ;
local minimapBackgroundSize = 42 ;
local slotWidth , slotHeight , iconSize , slotShadow , runePlateVisible ;
local borderSize ;
if themeName == " Dark " then
slotWidth = 70 ;
slotHeight = 72 ;
iconSize = 50 ;
borderSize = 128 ;
runePlateVisible = false ;
else
slotWidth = 64 ;
slotHeight = 68 ;
iconSize = 48 ;
borderSize = 64 ;
runePlateVisible = true ;
end
for slotID , slotButton in pairs ( slotTable ) do
--slotButton.RuneSlot.Background:SetShown(runePlateVisible);
slotButton.Icon : SetSize ( iconSize , iconSize ) ;
slotButton : SetSize ( slotWidth , slotHeight ) ;
slotButton.Border : SetSize ( borderSize , borderSize ) ;
end
SlotController : LazyRefresh ( ) ;
--Optimize this minimap button's radial offset
local IsAddOnLoaded = IsAddOnLoaded ;
if IsAddOnLoaded ( " AzeriteUI " ) then
MapShapeUtil.cornerRadius = 18 ;
minimapBackgroundSize = 48 ;
--Skin Tooltip
--Background gets reset once gametooltip is hidden. Ask Goldpaw some day.
local backdropInfo = {
bgFile = " Interface \\ AddOns \\ AddOns \\ Narcissus \\ Art \\ Masks \\ Full " ,
edgeFile = " Interface \\ AddOns \\ AzeriteUI \\ media \\ tooltip_border_hex " ,
tile = true ,
tileEdge = true ,
tileSize = 24 ,
edgeSize = 24 ,
insets = { left = 8 , right = 8 , top = 8 , bottom = 8 } ,
} ;
DefaultTooltip.backdropInfo = backdropInfo ;
DefaultTooltip.offsetX = 2 ;
DefaultTooltip.offsetY = - 12 ;
DefaultTooltip : HookScript ( " OnShow " , function ( self )
self : SetPadding ( 8 , 8 , 8 , 8 ) ;
end )
elseif IsAddOnLoaded ( " DiabolicUI " ) then
MapShapeUtil.cornerRadius = 12 ;
elseif IsAddOnLoaded ( " GoldieSix " ) then
--GoldpawUI
MapShapeUtil.cornerRadius = 18 ;
elseif IsAddOnLoaded ( " GW2_UI " ) then
MapShapeUtil.cornerRadius = 44 ;
elseif IsAddOnLoaded ( " SpartanUI " ) then
MapShapeUtil.cornerRadius = 8 ;
else
MapShapeUtil.cornerRadius = 10 ;
end
MinimapButton.Background : SetSize ( minimapBackgroundSize , minimapBackgroundSize ) ;
end
function Narci_GuideLineFrame_OnSizing ( self , offset )
local W ;
local W0 , H = WorldFrame : GetSize ( ) ;
if ( W0 and H ) and H ~= 0 then
self : ClearAllPoints ( ) ;
self : SetPoint ( " TOP " , UIParent , " TOP " , 0 , 0 ) ;
self : SetPoint ( " BOTTOM " , UIParent , " BOTTOM " , 0 , 0 ) ;
local offset = offset or 0 ;
W = math.min ( H / 9 * 16 , W0 ) ;
W = floor ( W + 0.5 ) ;
--print("Original: "..W0.." Calculated: "..W);
self : SetWidth ( W - offset ) ;
else
W = self : GetWidth ( ) ;
end
local C = W * 0.618 ;
self.VirtualLineRight : SetPoint ( " RIGHT " , C - W + 32 , 0 ) ;
self.VirtualLineRight . defaultX = C - W + 32 ;
local AnimFrame = self.VirtualLineRight . AnimFrame ;
AnimFrame.OppoDirection = false ;
AnimFrame.TimeSinceLastUpdate = 0 ;
AnimFrame.anchorPoint , AnimFrame.relativeTo , AnimFrame.relativePoint , AnimFrame.toX , AnimFrame.toY = AnimFrame : GetParent ( ) : GetPoint ( ) ;
AnimFrame.defaultX = AnimFrame.toX ;
end
function Narci : SetReferenceFrameOffset ( offset )
--A positive offset expands the reference frame.
Narci_GuideLineFrame_OnSizing ( Narci_GuideLineFrame , - offset ) ;
end
NarciRayTracingToggleMixin = { } ;
function NarciRayTracingToggleMixin : SetVisual ( level )
if level and level > 0 then
self.Label : SetText ( " |cffd9d9d9RTX|r " .. level ) ;
self.Fill : SetWidth ( level * 42 / 3 ) ;
self.Fill : Show ( ) ;
else
self.Label : SetText ( " |cffd9d9d9RTX|r OFF " ) ;
self.Fill : Hide ( ) ;
end
end
function NarciRayTracingToggleMixin : SetLevel ( level )
level = tonumber ( level ) or 0 ;
if level > 3 then
level = 3 ;
end
self : SetVisual ( level ) ;
SetCVar ( " shadowrt " , level ) ;
end
function NarciRayTracingToggleMixin : Restore ( )
if self.oldValue then
self : SetLevel ( self.oldValue ) ;
end
end
function NarciRayTracingToggleMixin : OnClick ( )
self.IsOn = not self.IsOn ;
if self.IsOn then
self : SetLevel ( 3 ) ;
else
self : Restore ( ) ;
end
end
function NarciRayTracingToggleMixin : OnShow ( )
local level = tonumber ( GetCVar ( " shadowrt " ) ) ;
self.oldValue = level ;
self : SetVisual ( level ) ;
end
function NarciRayTracingToggleMixin : OnHide ( )
self.IsOn = false ;
end
function NarciRayTracingToggleMixin : OnEnter ( )
self.Fill : SetAlpha ( 1 ) ;
self.Background : SetAlpha ( 1 ) ;
end
function NarciRayTracingToggleMixin : OnLeave ( )
self.Fill : SetAlpha ( 0.5 ) ;
self.Background : SetAlpha ( 0.5 ) ;
end
function NarciRayTracingToggleMixin : OnLoad ( )
local validity ;
if Advanced_RTShadowQualityDropDown then
validity = true ;
end
local info = { GetToolTipInfo ( 1 , 4 , " shadowrt " , 0 , 1 , 2 , 3 ) } ;
for i = 1 , # info do
if info [ i ] ~= 0 then
validity = validity and false ;
break ;
end
end
self.isValid = validity ;
if not validity then
self : Hide ( ) ;
self : Disable ( ) ;
TopQualityButton_MSAASlider : SetPoint ( " TOPLEFT " , Narci_XmogButton , " BOTTOMLEFT " , 4 , - 12 ) ;
end
self : SetScript ( " OnLoad " , nil ) ;
self.OnLoad = nil ;
end
function NarciRayTracingToggleMixin : FadeIn ( )
if self.isValid then
FadeFrame ( TopQualityButton_RayTracingToggle , 0.25 , 1 ) ;
end
end
function NarciRayTracingToggleMixin : FadeOut ( )
if self.isValid then
FadeFrame ( TopQualityButton_RayTracingToggle , 0.25 , 0 ) ;
end
end
NarciFlyoutOverlayMixin = { } ;
function NarciFlyoutOverlayMixin : In ( )
--FadeFrame(self, 0.2, 1);
self : Init ( ) ;
self.animFrame . toAlpha = 1 ;
self.animFrame : Show ( ) ;
self : Show ( ) ;
end
function NarciFlyoutOverlayMixin : Out ( )
--FadeFrame(self, 0.2, 0);
self : Init ( ) ;
self.animFrame . toAlpha = 0 ;
self.animFrame : Show ( ) ;
self : Show ( ) ;
end
function NarciFlyoutOverlayMixin : OnHide ( )
self : SetAlpha ( 0 ) ;
self : Hide ( ) ;
end
function NarciFlyoutOverlayMixin : Init ( )
if not self.animFrame then
self.animFrame = CreateFrame ( " Frame " , nil , self ) ;
self.animFrame : SetScript ( " OnUpdate " , function ( f , elapsed )
f.t = f.t + elapsed ;
local alpha ;
if f.t < 0.25 then
alpha = outSine ( f.t , f.fromAlpha , f.toAlpha , 0.25 ) ;
else
alpha = f.toAlpha ;
if alpha < 0 then
self : Hide ( ) ;
end
f : Hide ( ) ;
end
self : SetAlpha ( alpha ) ;
end ) ;
end
self.animFrame . t = 0 ;
self.animFrame . fromAlpha = self : GetAlpha ( ) ;
end
function NarciFlyoutOverlayMixin : RaiseFrameLevel ( widget )
local selfLevel = self : GetFrameLevel ( ) ;
if self.lastWidget then
self.lastWidget : SetFrameLevel ( selfLevel - 1 ) ;
self.lastWidget = nil ;
end
local widgetLevel = widget : GetFrameLevel ( ) ;
if widgetLevel <= selfLevel then
widget : SetFrameLevel ( selfLevel + 1 ) ;
self.lastWidget = widget ;
end
end
Narci.GetEquipmentSlotByID = function ( slotID ) return slotTable [ slotID ] end ;
Narci.RefreshSlot = function ( slotID ) SlotController : Refresh ( slotID ) return slotTable [ slotID ] end ;
Narci.RefreshAllSlots = SlotController.RefreshAll ;
Narci.RefreshAllStats = StatsUpdator.Instant ;
--[[
C_BarberShop.GetAvailableCustomizations ( ) ;
/ run BarberShopFrame : SetPropagateKeyboardInput ( true )
CharCustomizeFrame : SetCustomizationChoice
hooksecurefunc ( CharCustomizeFrame , " SetCustomizationChoice " , function ( optionID , choiceID ) print ( " Set " , optionID , choiceID ) end )
hooksecurefunc ( CharCustomizeFrame , " PreviewCustomizationChoice " , function ( optionID , choiceID ) print ( " Preview " , optionID , choiceID ) end )
Blizzard_CharacterCustomize
Blizzard_BarbershopUI
slotID shoulder ~ 3
C_Transmog.SetPending ( self.transmogLocation , sourceID , self.activeCategory ) ;
WardrobeCollectionFrame.ItemsCollectionFrame : SelectVisual ( )
/ run WardrobeCollectionFrame.ItemsCollectionFrame . RightShoulderCheckbox : Show ( ) ;
/ run GetMouseFocus ( ) . transmogLocation = TransmogUtil.GetTransmogLocation ( 3 , 0 , 0 ) --96875
New APIs :
CenterCamera ( ) ;
/ run CenterCamera ( ) ;
--]]
--Ember Court Correspondence
--https://wowpedia.fandom.com/wiki/Quill_of_Correspondence
--[[
function SaveCurrentMail ( )
local m = OpenMailBodyText : GetTextData ( ) ;
m.subject = OpenMailSubject : GetText ( ) ;
NarciDevToolOutput.mail = m ;
end
--]]