local _ , addon = ...
local MsgAlertContainer = addon.MsgAlertContainer ;
local TransitionAPI = addon.TransitionAPI ;
local SlotButtonOverlayUtil = addon.SlotButtonOverlayUtil ;
local Narci = Narci ;
Narci.refreshCombatRatings = true ;
local SLOT_TABLE = { } ;
Narci.slotTable = SLOT_TABLE ;
local STAT_STABLE = { } ;
local SHORT_STAT_TABLE = { } ;
local L = Narci.L ;
local VIGNETTE_ALPHA = 0.5 ;
local IS_OPENED = false ; --Addon was opened by clicking
local MOG_MODE = false ;
local SHOW_MISSING_ENCHANT_ALERT = true ;
local NarciAPI = NarciAPI ;
local GetItemEnchantID = NarciAPI.GetItemEnchantID ;
local GetItemEnchantText = NarciAPI.GetEnchantTextByItemLink ;
local EnchantInfo = Narci.EnchantData ; --Bridge/GearBonus.lua
local PlayLetteboxAnimation = NarciAPI_LetterboxAnimation ;
local SmartFontType = NarciAPI.SmartFontType ;
local IsItemSocketable = NarciAPI.IsItemSocketable ;
local SetBorderTexture = NarciAPI.SetBorderTexture ;
local GetBorderArtByItemID = NarciAPI.GetBorderArtByItemID ;
local GetVerticalRunicLetters = NarciAPI.GetVerticalRunicLetters ;
local FadeFrame = NarciFadeUI.Fade ;
local inOutSine = addon.EasingFunctions . inOutSine
local linear = addon.EasingFunctions . linear ;
local outSine = addon.EasingFunctions . outSine ;
local GetToolbarButtonByButtonType = addon.GetToolbarButtonByButtonType ;
local TransmogDataProvider = addon.TransmogDataProvider ;
--local GetCorruptedItemAffix = NarciAPI_GetCorruptedItemAffix;
local Narci_AlertFrame_Autohide = Narci_AlertFrame_Autohide ;
local C_Item = C_Item ;
local GetItemInfo = GetItemInfo ;
local C_LegendaryCrafting = C_LegendaryCrafting ;
local C_TransmogCollection = C_TransmogCollection ;
local After = C_Timer.After ;
local ItemLocation = ItemLocation ;
local IsPlayerInAlteredForm = TransitionAPI.IsPlayerInAlteredForm ;
local InCombatLockdown = InCombatLockdown ;
local GetItemInfoInstant = GetItemInfoInstant ;
local GetInventoryItemTexture = GetInventoryItemTexture ;
local GetCameraZoom = GetCameraZoom ;
local floor = math.floor ;
local max = math.max ;
local UIParent = _G.UIParent ;
local Toolbar = NarciScreenshotToolbar ;
local EquipmentFlyoutFrame ;
local ItemLevelFrame ;
local RadarChart ;
local ItemTooltip ;
local MiniButton = Narci_MinimapButton ;
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 ( ) ;
EL.EVENTS_DYNAMIC = { " 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 " ,
} ;
EL.EVENTS_UNIT = { " UNIT_DAMAGE " , " UNIT_ATTACK_SPEED " , " UNIT_MAXHEALTH " , " UNIT_AURA " , " UNIT_INVENTORY_CHANGED " } ;
--[[
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 ;
local ShowDelayedTooltip = NarciAPI_ShowDelayedTooltip ;
function Narci_ShowButtonTooltip ( self )
DefaultTooltip : HideTooltip ( ) ;
DefaultTooltip : SetOwner ( self , " ANCHOR_NONE " ) ;
if not self.tooltipHeadline then
return
end
DefaultTooltip : SetPoint ( " BOTTOM " , self , " TOP " , 0 , 2 ) ;
DefaultTooltip : SetText ( self.tooltipHeadline ) ;
if self.tooltipLine1 then
DefaultTooltip : AddLine ( self.tooltipLine1 , 1 , 1 , 1 , true ) ;
end
if self.tooltipSpecial then
DefaultTooltip : AddLine ( " " ) ;
DefaultTooltip : AddLine ( self.tooltipSpecial , 0.25 , 0.78 , 0.92 , true ) ;
end
DefaultTooltip : Show ( ) ;
DefaultTooltip : FadeIn ( ) ;
--ShowDelayedTooltip("BOTTOM", self, "TOP", 0, 2);
end
function Narci : HideButtonTooltip ( )
--ShowDelayedTooltip(false);
DefaultTooltip : HideTooltip ( ) ;
ItemTooltip : HideTooltip ( ) ;
--DefaultTooltip:SetFrameStrata("TOOLTIP");
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 = ( C_CVar and C_CVar.GetCVar ) or GetCVar ;
local SetCVar = ( C_CVar and C_CVar.SetCVar ) or SetCVar ;
ConsoleExec ( " pitchlimit 88 " ) ;
local CVarTemp = { } ;
function CVarTemp : BackUp ( )
self.zoomLevel = GetCameraZoom ( ) ;
self.dynamicPitch = tonumber ( GetCVar ( " test_cameraDynamicPitch " ) ) ;
self.shoulderOffset = GetCVar ( " test_cameraOverShoulder " ) ;
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 ( not CVarTemp.cameraSafeMode )
end
CVarTemp.shoulderOffset = 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.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 MOG_MODE_OFFSET = 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 ] = { 4.61 , 0.1067 , - 0.02 , 5 } , --Fly Swift
[ 29 ] = { 4.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 " ] = { [ 2 ] = { 8 , 1.2495 , - 4 , 5.5 } ,
[ 3 ] = { 8 , 1.2495 , - 4 , 5.5 } } ,
[ 52 ] = { [ 2 ] = { 2.1 , 0.361 , - 0.1654 , 4 } , --Dracthyr Visage (Male elf)
[ 3 ] = { 2.0 , 0.38 , 0.0311 , 3.6 } } , --Dracthyr Visage (Female human)
[ " Dracthyr " ] = { [ 2 ] = { 2.6 , 0.1704 , 0.0749 , 5 } , --Dracthyr Dragon Form
[ 3 ] = { 2.6 , 0.1704 , 0.0749 , 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
--/run NarciScreenshotToolbar:ShowUI("Blizzard")
} ;
local _ , _ , PLAYER_RACE_ID = UnitRace ( " player " )
local PLAYER_GENDER_ID = UnitSex ( " player " )
local _ , _ , PLAYER_CLASS_ID = UnitClass ( " player " ) ;
local CAM_DISTANCE_INDEX = 1 ;
local ZOOM_IN_VALUE = ZoomValuebyRaceID [ 0 ] [ 1 ] ;
local ZOOM_IN_VALUE_MOG = 3.8 ;
local SHOULDER_FACTOR_1 = ZoomValuebyRaceID [ 0 ] [ 2 ] [ 2 ] ;
local SHOULDER_FACTOR_2 = ZoomValuebyRaceID [ 0 ] [ 2 ] [ 3 ] ;
local CameraMover = { } ;
local CameraUtil = { } ;
function CameraUtil : UpdateParametersDefault ( )
local raceKey ;
if IsMounted ( ) then
raceKey = " Mounted " ;
else
raceKey = self : GetRaceKey ( ) ;
end
ZOOM_IN_VALUE = ZoomValuebyRaceID [ raceKey ] [ PLAYER_GENDER_ID ] [ CAM_DISTANCE_INDEX ] ;
SHOULDER_FACTOR_1 = ZoomValuebyRaceID [ raceKey ] [ PLAYER_GENDER_ID ] [ 2 ] ;
SHOULDER_FACTOR_2 = ZoomValuebyRaceID [ raceKey ] [ PLAYER_GENDER_ID ] [ 3 ] ;
ZOOM_IN_VALUE_MOG = ZoomValuebyRaceID [ raceKey ] [ PLAYER_GENDER_ID ] [ 4 ] ;
end
CameraUtil.UpdateParameters = CameraUtil.UpdateParametersDefault ;
function CameraUtil : GetRaceKey ( )
return PLAYER_RACE_ID
end
function CameraUtil : GetRaceKey_Worgen ( )
local raceKey ;
local inAlternateForm = IsPlayerInAlteredForm ( ) ;
if inAlternateForm then
--Human
raceKey = 1 ;
else
raceKey = " Wolf " ;
end
return raceKey
end
function CameraUtil : GetRaceKey_Dracthyr ( )
local raceKey ;
local inAlternateForm = IsPlayerInAlteredForm ( ) ;
if inAlternateForm then
--Visage
raceKey = 52 ;
else
raceKey = " Dracthyr " ;
end
return raceKey
end
function CameraUtil : UpdateParameters_Druid ( )
local formID = GetShapeshiftFormID ( ) ;
if formID then
if formID == 31 then
local _ , glyphID = GetCurrentGlyphNameForSpell ( 24858 ) ; --Moonkin form with Glyph of Stars use regular configuration
if glyphID and glyphID == 114301 then
self : UpdateParametersDefault ( ) ;
return
end
end
local raceKey = " Druid " ;
ZOOM_IN_VALUE = ZoomValuebyRaceID [ raceKey ] [ formID ] [ CAM_DISTANCE_INDEX ] ;
SHOULDER_FACTOR_1 = ZoomValuebyRaceID [ raceKey ] [ formID ] [ 2 ] ;
SHOULDER_FACTOR_2 = ZoomValuebyRaceID [ raceKey ] [ formID ] [ 3 ] ;
ZOOM_IN_VALUE_MOG = ZoomValuebyRaceID [ raceKey ] [ formID ] [ 4 ] ;
else
self : UpdateParametersDefault ( ) ;
end
end
do
if PLAYER_RACE_ID == 25 or PLAYER_RACE_ID == 26 then --Pandaren A|H
PLAYER_RACE_ID = 24 ;
elseif PLAYER_RACE_ID == 30 then --Lightforged
PLAYER_RACE_ID = 11 ;
elseif PLAYER_RACE_ID == 36 then --Mag'har Orc
PLAYER_RACE_ID = 2 ;
elseif PLAYER_RACE_ID == 34 then --DarkIron
PLAYER_RACE_ID = 3 ;
elseif PLAYER_RACE_ID == 37 then --Mechagnome
PLAYER_RACE_ID = 7 ;
elseif PLAYER_RACE_ID == 22 then
CameraUtil.GetRaceKey = CameraUtil.GetRaceKey_Worgen ;
elseif PLAYER_RACE_ID == 52 or PLAYER_RACE_ID == 70 then
PLAYER_RACE_ID = 52 ; --Dracthyr Horde -> Alliance
CameraUtil.GetRaceKey = CameraUtil.GetRaceKey_Dracthyr ;
end
local _ , _ , playerClassID = UnitClass ( " player " ) ;
if playerClassID == 11 then
CameraUtil.UpdateParameters = CameraUtil.UpdateParameters_Druid ;
table.insert ( EL.EVENTS_DYNAMIC , " UPDATE_SHAPESHIFT_FORM " ) ;
end
end
for raceKey , data in pairs ( ZoomValuebyRaceID ) do
local id = tonumber ( raceKey ) ;
if id and id > 1 and id ~= PLAYER_RACE_ID then
ZoomValuebyRaceID [ raceKey ] = nil ;
end
end
function CameraUtil : OnPlayerFormChanged ( pauseDuration )
if not self.frame then
self.frame = CreateFrame ( " Frame " ) ;
self.frame : SetScript ( " OnUpdate " , function ( f , elapsed )
f.t = f.t + elapsed ;
if f.t > 0 then
f : Hide ( ) ;
self : UpdateParameters ( ) ;
CameraMover : OnCameraChanged ( ) ;
end
end ) ;
end
if not self.pauseUpdate then
--self.pauseUpdate = true;
pauseDuration = pauseDuration or 0 ;
self.frame . t = - pauseDuration ;
self.frame : Show ( ) ;
end
end
local function GetShoulderOffsetByZoom ( zoom )
return zoom * SHOULDER_FACTOR_1 + SHOULDER_FACTOR_2 + MOG_MODE_OFFSET
end
local SmoothShoulder = CreateFrame ( " Frame " ) ;
SmoothShoulder.t = 0 ;
SmoothShoulder.duration = 1 ;
SmoothShoulder.zoom = 0 ;
SmoothShoulder : Hide ( ) ;
SmoothShoulder : SetScript ( " OnShow " , function ( self )
self.fromPoint = GetCVar ( " test_cameraOverShoulder " ) ;
end ) ;
local function SmoothShoulder_OnUpdate_ToValue ( 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
local function SmoothShoulder_OnUpdate_ByZoom ( self , elapsed )
local zoom = GetCameraZoom ( ) ;
if zoom ~= self.zoom then
local value = GetShoulderOffsetByZoom ( zoom ) ;
if value < 0 then
value = 0 ;
end
SetCVar ( " test_cameraOverShoulder " , value ) ;
else
self : Hide ( ) ;
end
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 : SetScript ( " OnUpdate " , SmoothShoulder_OnUpdate_ToValue ) ;
SmoothShoulder.t = 0 ;
SmoothShoulder.toPoint = toPoint ;
SmoothShoulder.fromPoint = GetCVar ( " test_cameraOverShoulder " ) ;
SmoothShoulder : Show ( ) ;
end
local function SmoothShoulder_OnUpdate_UntilStable ( self , elapsed )
self.t = self.t + elapsed ;
if self.t >= 0.1 then
local zoom = GetCameraZoom ( ) ;
if zoom ~= self.zoom then
self.zoom = zoom ;
self.t = 0 ;
else
local value = GetShoulderOffsetByZoom ( zoom ) ;
if value < 0 then
value = 0 ;
end
SmoothShoulderCVar ( value , true ) ;
end
end
end
local UpdateShoulderCVar = { } ;
UpdateShoulderCVar.steps = 0 ;
function UpdateShoulderCVar : Start ( increment )
SmoothShoulder : SetScript ( " OnUpdate " , SmoothShoulder_OnUpdate_UntilStable ) ;
SmoothShoulder.t = 0 ;
SmoothShoulder : Show ( ) ;
end
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
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.0 , function ( )
--self:ZoomIn(ZOOM_IN_VALUE);
local zoom = GetCameraZoom ( ) ;
if zoom < ZOOM_IN_VALUE then
self : ZoomIn ( ZOOM_IN_VALUE ) ;
else
CameraZoomIn ( 0 ) ;
end
self.pauseUpdate = nil ;
end ) ;
end
end
function CameraMover : SetBlend ( enable )
local divisor ;
if enable then
--Smooth
DURATION_TRANSLATION = 0.8 ;
divisor = 20 ;
else
--Instant
DURATION_TRANSLATION = 0.4 ;
divisor = 80 ;
end
for k , slot in pairs ( STAT_STABLE ) do
local delay = ( slot : GetID ( ) ) / divisor ;
if slot.animIn then
slot.animIn . A2 : SetStartDelay ( delay ) ;
end
end
for k , slot in pairs ( SHORT_STAT_TABLE ) 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 = ZOOM_IN_VALUE or GetCameraZoom ( ) ;
local shoulderOffset = GetShoulderOffsetByZoom ( zoom ) ;
SetCVar ( " test_cameraOverShoulder " , shoulderOffset ) ; --CameraZoomIn(0.0) --Smooth
self : ZoomIn ( ZOOM_IN_VALUE ) ;
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 ( ZOOM_IN_VALUE ) ;
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 ( ZOOM_IN_VALUE ) ;
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
function CameraMover : MakeActive ( )
--Reserved for DynamicCam users
end
function CameraMover : MakeInactive ( )
--Reserved for DynamicCam users
end
function CameraMover : UpdateMovementMethodForDynamicCam ( )
if not self.handler then
self.handler = CreateFrame ( " Frame " ) ;
end
local f = self.handler ;
f : Hide ( ) ;
f.t = 0 ;
f : SetScript ( " OnUpdate " , function ( _ , elapsed )
f.t = f.t + elapsed ;
if f.t >= 0.2 then
f.currentZoom = GetCameraZoom ( ) ;
if f.currentZoom ~= f.lastZoom then
f.lastZoom = f.currentZoom ;
UpdateShoulderCVar : Start ( ) ;
end
end
end ) ;
function self : MakeActive ( )
f.lastZoom = - 1 ;
f : Show ( ) ;
end
function self : MakeInactive ( )
f : Hide ( ) ;
end
end
------------------------------
------------------------------
local function ExitFunc ( )
IS_OPENED = false ;
MOG_MODE_OFFSET = 0 ;
EL : Hide ( ) ;
CameraMover : MakeInactive ( ) ;
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.shoulderOffset ) ;
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 cameraSmoothStyle = GetCVar ( " cameraSmoothStyle " ) ;
if tonumber ( cameraSmoothStyle ) == 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 : HideTooltip ( ) ;
MsgAlertContainer : Hide ( ) ;
UIErrorsFrame : Clear ( ) ;
Narci_ModelContainer : HideAndClearModel ( ) ;
Narci_ModelSettings : Hide ( ) ;
Narci_XmogNameFrame : Hide ( ) ;
NarciSettingsFrame : CloseUI ( ) ;
MOG_MODE = false ;
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.shoulderOffset = 0 ;
SetCVar ( " test_cameraOverShoulder " , 0 ) ;
SetCVar ( " cameraViewBlendStyle " , 1 ) ;
ConsoleExec ( " actioncam off " ) ;
CameraMover : MakeInactive ( ) ;
Narci_ModelContainer : HideAndClearModel ( ) ;
Narci_ModelSettings : Hide ( ) ;
Narci_Character : Hide ( ) ;
Narci_Attribute : Hide ( ) ;
Narci_Vignette : Hide ( ) ;
IS_OPENED = false ;
MOG_MODE_OFFSET = 0 ;
EL : Hide ( ) ;
end
---------------End of derivation---------------
---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 SLOT_TABLE [ index ] and SLOT_TABLE [ index ] . hyperlink then
After ( delay , function ( )
SendChatMessage ( xmogTable [ i ] [ 2 ] .. " : " .. SLOT_TABLE [ 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 : HideTooltip ( ) ;
end
end
local IsItemEnchantable = {
[ 11 ] = true ,
[ 12 ] = true ,
[ 16 ] = true ,
[ 17 ] = true ,
[ 5 ] = true ,
[ 8 ] = true ,
[ 9 ] = true ,
[ 10 ] = true ,
[ 15 ] = true ,
} ;
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 ( ) ;
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 . 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 ( ) ;
DefaultTooltip : FadeIn ( ) ;
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 function GetRuneForgeLegoIcon ( itemLocation )
local componentInfo = C_LegendaryCrafting.GetRuneforgeLegendaryComponentInfo ( itemLocation ) ;
if componentInfo and componentInfo.powerID then
local powerInfo = C_LegendaryCrafting.GetRuneforgePowerInfo ( componentInfo.powerID ) ;
return powerInfo and powerInfo.iconFileID
end
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 : AnchorAlertFrame ( )
self : RegisterErrorEvent ( ) ;
Narci_AlertFrame_Autohide : SetAnchor ( self , - 12 , true ) ;
end
function NarciItemButtonSharedMixin : PlayGamePadAnimation ( )
if self.gamepad then
self.Icon . ScaleUp : Play ( ) ;
self.IconMask . ScaleUp : Play ( ) ;
self.Border . ScaleUp : Play ( ) ;
self.Border . BorderMask.ScaleUp : Play ( ) ;
end
end
function NarciItemButtonSharedMixin : ResetAnimation ( )
if self.gamepad then
self.Icon . ScaleUp : Stop ( ) ;
self.Border . ScaleUp : Stop ( ) ;
self.Border . BorderMask.ScaleUp : Stop ( ) ;
self.IconMask . ScaleUp : Stop ( ) ;
self.Icon : SetScale ( 1 ) ;
self.Border : SetScale ( 1 ) ;
self.IconMask : SetScale ( 1 ) ;
self.Border . BorderMask : SetScale ( 1 ) ;
if self.gamepadOverlay then
self.gamepadOverlay : Hide ( ) ;
self.gamepadOverlay = nil ;
end
end
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 ,
} ;
local function GetFormattedSourceText ( sourceInfo )
local sourceType = sourceInfo.sourceType ;
local itemQuality = sourceInfo.quality or 1 ;
local hex = NarciAPI.GetItemQualityHexColor ( itemQuality ) ;
local difficulty ;
local bonusID ;
local colorizedText , plainText , hyperlink ;
if sourceType == 1 then --TRANSMOG_SOURCE_BOSS_DROP = 1
local drops = C_TransmogCollection.GetAppearanceSourceDrops ( sourceInfo.sourceID ) ;
if drops and drops [ 1 ] then
colorizedText = drops [ 1 ] . encounter .. " " .. " |cFFFFD100 " .. drops [ 1 ] . instance .. " |r " ;
plainText = drops [ 1 ] . encounter .. " " .. drops [ 1 ] . instance ;
if sourceInfo.itemModID == 0 then
difficulty = PLAYER_DIFFICULTY1 ;
bonusID = 3561 ;
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 1 " .. " :1476:|h|r " ;
elseif sourceInfo.itemModID == 1 then
difficulty = PLAYER_DIFFICULTY2 ;
bonusID = 3562 ;
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 2 " .. " :1476:|h|r " ;
elseif sourceInfo.itemModID == 3 then
difficulty = PLAYER_DIFFICULTY6 ;
bonusID = 3563 ;
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 3 " .. " :1476:|h|r " ;
elseif sourceInfo.itemModID == 4 then
difficulty = PLAYER_DIFFICULTY3 ;
bonusID = 3564 ;
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:356 " .. " 4 " .. " :1476:|h|r " ;
end
if difficulty then
colorizedText = colorizedText .. " |CFFf8e694 " .. difficulty .. " |r " ;
plainText = plainText .. " " .. difficulty ;
end
else
local sourceText = _G [ " TRANSMOG_SOURCE_1 " ] ; --Boss Drop
colorizedText = sourceText ;
plainText = sourceText ;
end
else
if sourceType == 2 then --quest
colorizedText = TRANSMOG_SOURCE_2 ;
if sourceInfo.itemModID == 3 then
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:512 " .. " 6 " .. " :1562:|h|r " ;
bonusID = 5126 ;
elseif sourceInfo.itemModID == 2 then
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:512 " .. " 5 " .. " :1562:|h|r " ;
bonusID = 5125 ;
elseif sourceInfo.itemModID == 1 then
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " ::::::::120::::2:512 " .. " 4 " .. " :1562:|h|r " ;
bonusID = 5124 ;
end
elseif sourceType == 3 then --vendor
colorizedText = TRANSMOG_SOURCE_3 ;
elseif sourceType == 4 then --world drop
colorizedText = TRANSMOG_SOURCE_4 ;
elseif sourceType == 5 then --achievement
colorizedText = TRANSMOG_SOURCE_5 ;
elseif sourceType == 6 then --profession
colorizedText = TRANSMOG_SOURCE_6 ;
else
if itemQuality == 6 then
colorizedText = ITEM_QUALITY6_DESC ;
elseif itemQuality == 5 then
colorizedText = ITEM_QUALITY5_DESC ;
end
end
plainText = colorizedText ;
end
if not hyperlink then
hyperlink = " |c " .. hex .. " |Hitem: " .. sourceInfo.itemID .. " :|h|r " ;
end
return colorizedText , plainText , hyperlink ;
end
NarciEquipmentSlotMixin = CreateFromMixins { NarciItemButtonSharedMixin } ;
function NarciEquipmentSlotMixin : SetTransmogSourceID ( appliedSourceID , secondarySourceID )
self.sourceID = appliedSourceID ;
if appliedSourceID and appliedSourceID > 0 then
self.Icon : SetDesaturated ( false ) ;
self.Name : Show ( ) ;
self.ItemLevel : Show ( ) ;
self.GradientBackground : Show ( ) ;
else
self.Icon : SetDesaturated ( true ) ;
self.Name : SetText ( nil ) ;
self.ItemLevel : SetText ( nil ) ;
self.GradientBackground : Hide ( ) ;
self : SetBorderTexture ( self.Border , 0 ) ;
if self.slotID == 2 then
self : DisplayDirectionMark ( false ) ;
end
return
end
local itemName , itemIcon , itemQuality , subText ;
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 ;
self.itemModID = sourceInfo.itemModID ;
itemQuality = sourceInfo.quality or 1 ;
itemIcon = C_TransmogCollection.GetSourceIcon ( appliedSourceID ) ;
subText = TransmogDataProvider : GetSpecialItemSourceText ( appliedSourceID , self.itemID , self.itemModID ) ;
if subText then
self.sourcePlainText = NarciAPI.RemoveColorString ( subText ) ;
_ , _ , self.hyperlink = GetFormattedSourceText ( sourceInfo ) ;
else
subText , self.sourcePlainText , self.hyperlink = GetFormattedSourceText ( sourceInfo ) ;
end
if self.hyperlink then
_ , self.hyperlink = GetItemInfo ( self.hyperlink ) ; --original hyperlink cannot be printed (workaround)
end
local bonusID ;
if itemQuality == 6 then
if self.slotID == 16 then
bonusID = ( sourceInfo.itemModID or 0 ) ; --Artifact use itemModID "7V0" + modID - 1
else
bonusID = 0 ;
end
end
self.bonusID = bonusID ;
local bR , bG , bB = GetItemQualityColor ( itemQuality ) ;
local borderTexKey = itemQuality ;
self : SetBorderTexture ( self.Border , borderTexKey ) ;
if self : IsVisible ( ) then
if itemIcon then
self.IconOverlay : SetTexture ( itemIcon ) ;
self.Icon . anim : Play ( ) ;
end
self.ItemLevel . anim1 : SetScript ( " OnFinished " , function ( f )
self.ItemLevel : SetText ( subText ) ;
self.ItemLevel . anim2 : Play ( ) ;
f : SetScript ( " OnFinished " , nil ) ;
end )
self.Name . anim1 : SetScript ( " OnFinished " , function ( f )
self.Name : SetText ( itemName ) ;
self.Name : SetTextColor ( bR , bG , bB ) ;
self.Name . anim2 : Play ( ) ;
f : SetScript ( " OnFinished " , nil ) ;
After ( 0 , function ( )
self : UpdateGradientSize ( ) ;
end )
end )
self.ItemLevel . anim1 : Play ( ) ;
self.Name . anim1 : Play ( ) ;
else
self.ItemLevel : SetText ( subText ) ;
self.Name : SetText ( itemName ) ;
self.Name : SetTextColor ( bR , bG , bB ) ;
if itemIcon then
self.Icon : SetTexture ( itemIcon ) ;
end
self : UpdateGradientSize ( ) ;
end
if self.slotID == 3 then
--shoulder
if secondarySourceID and secondarySourceID > 0 then
self : DisplayDirectionMark ( true , itemQuality ) ;
SLOT_TABLE [ 2 ] : SetTransmogSourceID ( secondarySourceID , secondarySourceID ) ;
else
self : DisplayDirectionMark ( false ) ;
end
elseif self.slotID == 2 then
self : DisplayDirectionMark ( appliedSourceID , itemQuality ) ;
end
end
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 isCorruptedItem = false;
local bR , bG , bB ; --Item Name Color
if C_Item.DoesItemExist ( itemLocation ) then
if MOG_MODE then
self : UntrackCooldown ( ) ;
self : UntrackTempEnchant ( ) ;
self : ClearOverlay ( ) ;
self : HideVFX ( ) ;
self.itemLink = nil ;
self.isSlotHidden = false ; --Undress an item from player model
self.RuneSlot : Hide ( ) ;
self.GradientBackground : Show ( ) ;
local appliedSourceID , appliedVisualID , hasSecondaryAppearance = GetSlotVisualID ( slotID ) ;
self.sourceID = appliedSourceID ;
if appliedVisualID > 0 then
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 ;
self.itemModID = sourceInfo.itemModID ;
itemIcon = C_TransmogCollection.GetSourceIcon ( appliedSourceID ) ;
effectiveLvl = TransmogDataProvider : GetSpecialItemSourceText ( appliedSourceID , self.itemID , self.itemModID ) ;
if effectiveLvl then
self.sourcePlainText = NarciAPI.RemoveColorString ( effectiveLvl ) ;
_ , _ , self.hyperlink = GetFormattedSourceText ( sourceInfo ) ;
else
effectiveLvl , self.sourcePlainText , self.hyperlink = GetFormattedSourceText ( sourceInfo ) ;
end
if self.hyperlink then
_ , self.hyperlink = GetItemInfo ( self.hyperlink ) ; --original hyperlink cannot be printed (workaround)
end
local bonusID ;
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
effectiveLvl = TransmogDataProvider : GetSpecialItemSourceText ( appliedSourceID , self.itemID , self.itemModID ) 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 ( ) ;
self.sourceID = nil ;
self.hyperlink = nil ;
self.sourcePlainText = nil ;
--[[
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 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
self.itemLink = itemLink ;
local itemVFX , hideItemIcon ;
local itemID = GetItemInfoInstant ( itemLink ) ;
borderTexKey , itemVFX , bR , bG , bB , hideItemIcon = GetBorderArtByItemID ( itemID ) ;
itemIcon = ( ( not hideItemIcon ) and GetInventoryItemTexture ( " player " , slotID ) ) or nil ;
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
if not hideItemIcon then
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
gemName , gemLink = IsItemSocketable ( itemLink ) ;
end
end
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.GetItemRankText ( itemLink , " ITEM_MOD_CORRUPTION_RESISTANCE " ) ;
effectiveLvl = effectiveLvl .. " " .. rank .. " |cFFFFD100 " .. corruptionResistance .. " |r " ;
borderTexKey = " BlackDragon " ;
itemVFX = " DragonFire " ;
end
end
if slotID ~= 13 and slotID ~= 14 then
local isRuneforgeLegendary = C_LegendaryCrafting.IsRuneforgeLegendary ( itemLocation ) ;
if isRuneforgeLegendary then
itemVFX = " Runeforge " ;
borderTexKey = " Runeforge " ;
itemIcon = GetRuneForgeLegoIcon ( itemLocation ) or itemIcon ;
end
end
local enchantText , isEnchanted = GetItemEnchantText ( itemLink , true , self.isRight ) ; --enchantText (effect texts) may not be available yet
if enchantText then
if self.isRight then
effectiveLvl = enchantText .. " " .. effectiveLvl ;
else
effectiveLvl = effectiveLvl .. " " .. enchantText ;
end
self : ClearOverlay ( ) ;
elseif not isEnchanted then
if SHOW_MISSING_ENCHANT_ALERT and SlotButtonOverlayUtil : IsSlotValidForEnchant ( slotID , itemID ) then
SlotButtonOverlayUtil : ShowEnchantAlert ( self , slotID , itemID ) ;
if self.isRight then
effectiveLvl = effectiveLvl .. " " .. L [ " Missing Enchant " ] ;
else
effectiveLvl = L [ " Missing Enchant " ] .. " " .. effectiveLvl ;
end
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
else
self : UntrackCooldown ( ) ;
self : UntrackTempEnchant ( ) ;
self : ClearOverlay ( ) ;
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.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 ;
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 ;
--regular gems
if gemLink then
gemID , _ , _ , _ , gemIcon , _ , itemSubClassID = GetItemInfoInstant ( gemLink ) ;
gemBorder = GetGemBorderTexture ( itemSubClassID , gemID ) ;
else
gemBorder = GetGemBorderTexture ( nil ) ;
end
self.GemSlot . GemBorder : SetTexture ( gemBorder ) ;
self.GemSlot . GemIcon : SetTexture ( gemIcon ) ;
self.GemSlot . GemIcon : Show ( ) ;
self.GemSlot . sockedGemItemID = gemID ;
if self : IsVisible ( ) then
self.GemSlot : FadeIn ( ) ;
else
self.GemSlot : ShowSlot ( ) ;
end
else
if self : IsVisible ( ) then
self.GemSlot : FadeOut ( ) ;
else
self.GemSlot : HideSlot ( ) ;
end
self.GemSlot . sockedGemItemID = nil ;
end
--if slotID == 13 then itemName = "The Lion\'s Roar"; end --Antumbra, Shadow of the Cosmos
--------------------------------------------------
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 ( f )
self.ItemLevel : SetText ( effectiveLvl ) ;
self.ItemLevel . anim2 : Play ( ) ;
f : SetScript ( " OnFinished " , nil ) ;
end )
self.Name . anim1 : SetScript ( " OnFinished " , function ( f )
self.Name : SetText ( itemName ) ;
self.Name : SetTextColor ( bR , bG , bB ) ;
self.Name . anim2 : Play ( ) ;
f : SetScript ( " OnFinished " , nil ) ;
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 ) + 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 " , " RightButtonDown " , " RightButtonUp " ) ;
if self : GetParent ( ) then
if not self : GetParent ( ) . slotTable then
self : GetParent ( ) . slotTable = { }
end
tinsert ( self : GetParent ( ) . slotTable , self ) ;
end
SLOT_TABLE [ 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
if not MOG_MODE then
ItemTooltip : SetFromSlotButton ( self , - 2 , 6 ) ;
end
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 : ClearOverlay ( )
if SHOW_MISSING_ENCHANT_ALERT and self.slotOverlay then
SlotButtonOverlayUtil : ClearOverlay ( self ) ;
self.slotOverlay = 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 : PlayGamePadAnimation ( ) ;
else
FadeFrame ( self.Highlight , 0.15 , 1 ) ;
end
if IsAltKeyDown ( ) and not MOG_MODE then
EquipmentFlyoutFrame : SetItemSlot ( self , true ) ;
return
end
if EquipmentFlyoutFrame : IsShown ( ) then
Narci_Comparison_SetComparison ( EquipmentFlyoutFrame.BaseItem , self ) ;
return ;
end
if MOG_MODE then
ItemTooltip : SetTransmogFromSlotButton ( self , - 2 , 6 ) ;
else
ItemTooltip : SetFromSlotButton ( self , - 2 , 6 , isGamepad and 0.4 ) ; --delay 0.4s
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 : SetPlayerInventoryItem ( self : GetID ( ) ) ;
if isGamepad then
DefaultTooltip : SetAlpha ( 0 ) ;
if self.isRight then
ShowDelayedTooltip ( " TOPRIGHT " , self , " TOPLEFT " , DefaultTooltip.offsetX , DefaultTooltip.offsetY ) ;
else
ShowDelayedTooltip ( " TOPLEFT " , self , " TOPRIGHT " , - DefaultTooltip.offsetX , DefaultTooltip.offsetY ) ;
end
else
DefaultTooltip : Show ( ) ;
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 : PreClick ( button )
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
if ChatEdit_InsertLink ( self.hyperlink ) then
return
elseif SocialPostFrame and Social_IsShown ( ) then
Social_InsertLink ( self.hyperlink ) ;
return
end
end
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
self : AnchorAlertFrame ( ) ;
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 ) ;
ShowDelayedTooltip ( " BOTTOM " , self , " TOP " , 0 , - 4 ) ;
--print("Narci_ShowStatTooltipDelayed")
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
--]]
function NarciItemLevelFrameMixin : OnLoad ( )
--Declared in Modules\CharacterFrame\ItemLevelFrame.lua
ItemLevelFrame = self ;
local function SideButton_OnEnter ( f )
if f.onEnterFunc then
f.onEnterFunc ( f ) ;
FadeFrame ( f.Highlight , 0.15 , 1 ) ;
end
end
local function SideButton_OnLeave ( f )
Narci : HideButtonTooltip ( ) ;
FadeFrame ( f.Highlight , 0.25 , 0 ) ;
end
local function SideButton_ShowDetailedItemLevel ( f )
if f.isSameLevel then
f.tooltipHeadline = string.format ( f.tooltipFormat , f.Level : GetText ( ) ) ;
else
f.tooltipHeadline = string.format ( f.tooltipFormat , f.Level : GetText ( ) ) .. string.format ( " (max %s) " , f.avgItemLevel ) ;
end
if f.avgItemLevelPvp and f.avgItemLevelPvp ~= 0 then
f.tooltipSpecial = string.format ( STAT_AVERAGE_PVP_ITEM_LEVEL , f.avgItemLevelPvp ) ;
else
f.tooltipSpecial = nil ;
end
Narci_ShowButtonTooltip ( f ) ;
end
local function SideButton_ShowMajorFactionInfo ( f )
DefaultTooltip : HideTooltip ( ) ;
DefaultTooltip : SetOwner ( f , " ANCHOR_NONE " ) ;
DefaultTooltip : SetPoint ( " BOTTOM " , f , " TOP " , 0 , 2 ) ;
DefaultTooltip : SetText ( DRAGONFLIGHT_LANDING_PAGE_TITLE ) ;
local factionIDs = C_MajorFactions.GetMajorFactionIDs ( ) ;
local factionList = { } ;
if factionIDs and # factionIDs > 0 then
local factionData ;
for _ , majorFactionID in ipairs ( factionIDs ) do
factionData = C_MajorFactions.GetMajorFactionData ( majorFactionID ) ;
if factionData then
table.insert ( factionList , factionData ) ;
end
end
local function UnlockOrderSort ( faction1 , faction2 )
if faction1.uiPriority then
return faction1.uiPriority < faction2.uiPriority ;
else
return faction1.unlockOrder < faction2.unlockOrder ;
end
end
table.sort ( factionList , UnlockOrderSort ) ;
--Embedded Frame
if not f.FactionListFrame then
f.FactionListFrame = CreateFrame ( " Frame " , nil , f ) ;
f.factionButtons = { } ;
f.FactionListFrame : SetWidth ( 154 ) ;
end
for i = 1 , # f.factionButtons do
f.factionButtons [ i ] : Hide ( ) ;
end
local maxTextWidth = 0 ;
local description , level , textWidth ;
for i , data in ipairs ( factionList ) do
if not f.factionButtons [ i ] then
f.factionButtons [ i ] = CreateFrame ( " Frame " , nil , f.FactionListFrame , " NarciGameTooltipEmbeddedIconTextFrame " ) ;
if i == 1 then
f.factionButtons [ i ] : SetPoint ( " TOPLEFT " , f.FactionListFrame , " TOPLEFT " , 0 , 0 ) ;
else
f.factionButtons [ i ] : SetPoint ( " TOPLEFT " , f.factionButtons [ i - 1 ] , " BOTTOMLEFT " , 0 , - 6 ) ;
end
end
level = data.renownLevel or 0 ;
if level < 10 then
level = level .. " " ;
end
if not data.isUnlocked then
description = MAJOR_FACTION_BUTTON_FACTION_LOCKED ;
elseif C_MajorFactions.HasMaximumRenown ( data.factionID ) then
if C_Reputation.IsFactionParagon ( data.factionID ) then
local totalEarned , threshold = C_Reputation.GetFactionParagonInfo ( data.factionID ) ;
if totalEarned and threshold and threshold ~= 0 then
local paragonLevel = floor ( totalEarned / threshold ) ;
local currentValue = totalEarned - paragonLevel * threshold ;
description = string.format ( " |cff00ccffP%s|r %d/%d " , paragonLevel , currentValue , threshold ) ;
else
description = MAJOR_FACTION_MAX_RENOWN_REACHED ;
end
else
description = MAJOR_FACTION_MAX_RENOWN_REACHED ;
end
else
description = string.format ( " |cffffd100%s|r %d/%d " , level , data.renownReputationEarned , data.renownLevelThreshold ) ;
end
f.factionButtons [ i ] . Icon : SetAtlas ( string.format ( " majorFactions_icons_%s512 " , data.textureKit ) , false ) ;
f.factionButtons [ i ] . Text : SetText ( string.format ( " |cffffffff%s|r \n %s " , data.name , description ) ) ;
f.factionButtons [ i ] . Text : SetTextColor ( 0.5 , 0.5 , 0.5 ) ;
f.factionButtons [ i ] : Show ( ) ;
textWidth = f.factionButtons [ i ] . Text : GetWrappedWidth ( ) ;
if textWidth and textWidth > maxTextWidth then
maxTextWidth = textWidth ;
end
end
local numButtons = # factionList ;
f.FactionListFrame : SetHeight ( ( 28 + 6 ) * numButtons - 12 ) ;
f.FactionListFrame : SetWidth ( floor ( maxTextWidth + 0.5 ) + 28 + 6 ) ;
local function GameTooltip_InsertFrame ( tooltipFrame , frame , verticalPadding ) -- this is an exact copy of GameTooltip_InsertFrame to avoid "Execution tainted"
verticalPadding = verticalPadding or 0 ;
local textSpacing = tooltipFrame : GetCustomLineSpacing ( ) or 2 ;
local textHeight = Round ( _G [ tooltipFrame : GetName ( ) .. " TextLeft2 " ] : GetLineHeight ( ) ) ;
local neededHeight = Round ( frame : GetHeight ( ) + verticalPadding ) ;
local numLinesNeeded = math.ceil ( neededHeight / ( textHeight + textSpacing ) ) ;
local currentLine = tooltipFrame : NumLines ( ) ;
if numLinesNeeded ~= nil then
for i = 1 , numLinesNeeded do
tooltipFrame : AddLine ( " " ) ;
end
end
frame : SetParent ( tooltipFrame ) ;
frame : ClearAllPoints ( ) ;
frame : SetPoint ( " TOPLEFT " , tooltipFrame : GetName ( ) .. " TextLeft " .. ( currentLine + 1 ) , " TOPLEFT " , 0 , - verticalPadding ) ;
if not tooltipFrame.insertedFrames then
tooltipFrame.insertedFrames = { } ;
end
local frameWidth = frame : GetWidth ( ) ;
if tooltipFrame : GetMinimumWidth ( ) < frameWidth then
tooltipFrame : SetMinimumWidth ( frameWidth ) ;
end
frame : Show ( ) ;
tinsert ( tooltipFrame.insertedFrames , frame ) ;
return ( numLinesNeeded * textHeight ) + ( numLinesNeeded - 1 ) * textSpacing ;
end
GameTooltip_InsertFrame ( DefaultTooltip , f.FactionListFrame , 6 ) ;
else
DefaultTooltip : AddLine ( MAJOR_FACTION_BUTTON_FACTION_LOCKED , 0.5 , 0.5 , 0.5 , true ) ;
end
DefaultTooltip : Show ( ) ;
DefaultTooltip : FadeIn ( ) ;
end
local LeftButton = self.LeftButton ;
LeftButton : SetScript ( " OnEnter " , SideButton_OnEnter ) ;
LeftButton : SetScript ( " OnLeave " , SideButton_OnLeave ) ;
LeftButton.onEnterFunc = SideButton_ShowDetailedItemLevel ;
LeftButton.tooltipFormat = L [ " Equipped Item Level Format " ] ;
LeftButton.tooltipLine1 = STAT_AVERAGE_ITEM_LEVEL_TOOLTIP ;
local RightButton = self.RightButton ;
RightButton : SetScript ( " OnEnter " , SideButton_OnEnter ) ;
RightButton : SetScript ( " OnLeave " , SideButton_OnLeave ) ;
RightButton.onEnterFunc = SideButton_ShowMajorFactionInfo ;
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 : UpdateItemLevel ( 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 ( ) ;
if MOG_MODE and Toolbar.TransmogListFrame : IsShown ( ) then
After ( 0.5 , function ( )
Toolbar.TransmogListFrame : UpdateTransmogList ( ) ;
end ) ;
end
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 SLOT_TABLE [ slotID ] then
SLOT_TABLE [ slotID ] : Refresh ( forceRefresh ) ;
return true ;
end
end
function SlotController : RefreshAll ( forceRefresh )
for slotID , slotButton in pairs ( SLOT_TABLE ) do
slotButton : Refresh ( forceRefresh ) ;
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 : ClearCache ( )
for slotID , slotButton in pairs ( SLOT_TABLE ) do
slotButton.itemLink = nil ;
end
end
function SlotController : PlayAnimOut ( )
if not InCombatLockdown ( ) and Narci_Character : IsShown ( ) then
for slotID , slotButton in pairs ( SLOT_TABLE ) do
slotButton.animOut : Play ( ) ;
end
Narci_Character.animOut : Play ( ) ;
end
end
function SlotController : IsMouseOver ( )
for slotID , slotButton in pairs ( SLOT_TABLE ) do
if slotButton : IsMouseOver ( ) then
return true
end
end
return false
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 : AnchorAlertFrame ( ) ;
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 )
Narci_Comparison_SetComparison ( self.itemLocation , self ) ;
if isGamepad then
self : PlayGamePadAnimation ( ) ;
else
FadeFrame ( self.Highlight , 0.15 , 1 ) ;
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 " ;
itemIcon = GetRuneForgeLegoIcon ( itemLocation ) or itemIcon ;
end
itemQuality = GetBorderArtByItemID ( itemID ) or itemQuality ;
if maxItemLevel and itemLevel < maxItemLevel and itemQuality ~= " Runeforge " 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 MOG_MODE then
return
end
local level = Narci_FlyoutBlack : GetFrameLevel ( ) - 1 ;
for slotID , slotButton in pairs ( SLOT_TABLE ) 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 ;
self : SetFixedFrameStrata ( true ) ;
self : SetFrameStrata ( " HIGH " ) ;
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 ( 50 ) ;
NarciEquipmentTooltip : HideTooltip ( ) ;
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 ) ;
Narci_ShowComparisonTooltip ( Tooltip ) ;
end
function NarciEquipmentFlyoutFrameMixin : CreateItemButton ( )
local perRow = 5 ; --EQUIPMENTFLYOUT_ITEMS_PER_ROW
local numButtons = # self.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 ) ;
self.buttons [ numButtons + 1 ] = button ;
button.FlyUp . Move : SetStartDelay ( numButtons / 25 ) ;
button.FlyUp . Fade : SetStartDelay ( numButtons / 25 ) ;
button.isFlyout = true ;
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 = { } ;
local numItems = 0 ;
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 ) ;
LoadItemData ( itemLocation ) ;
itemInfo = { level = itemLevel , itemLocation = itemLocation , location = location } ;
numItems = numItems + 1 ;
sortedItems [ numItems ] = 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 ;
local GetCombatRating = GetCombatRating ;
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
haste = GetCombatRating ( CR_HASTE_MELEE ) or 0 ;
end
if m then
mastery = m ;
else
mastery = 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
local function RefreshStats ( id , frame )
frame = frame or " Detailed " ;
if frame == " Detailed " then
if STAT_STABLE [ id ] then
STAT_STABLE [ id ] : Update ( ) ;
end
elseif frame == " Concise " then
if SHORT_STAT_TABLE [ id ] then
SHORT_STAT_TABLE [ 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 STAT_STABLE [ i ] then
STAT_STABLE [ i ] : Update ( ) ;
end
if SHORT_STAT_TABLE [ i ] then
SHORT_STAT_TABLE [ i ] : Update ( ) ;
end
if i >= 20 then
self : Hide ( ) ;
self.index = 1 ;
else
self.index = i + 1 ;
end
end
end ) ;
function StatsUpdator : Gradual ( )
ItemLevelFrame : AsyncUpdate ( 0.05 ) ;
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 ( SLOT_TABLE ) 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 = STAT_STABLE [ i ] . animIn ;
if anim then
anim.A2 : SetToAlpha ( STAT_STABLE [ 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 ( )
local statFrame = Narci_DetailedStatFrame ;
local radar = RadarChart ;
STAT_STABLE [ 1 ] = statFrame.Primary ;
STAT_STABLE [ 2 ] = statFrame.Stamina ;
STAT_STABLE [ 3 ] = statFrame.Damage ;
STAT_STABLE [ 4 ] = statFrame.AttackSpeed ;
STAT_STABLE [ 5 ] = statFrame.Power ;
STAT_STABLE [ 6 ] = statFrame.Regen ;
STAT_STABLE [ 7 ] = statFrame.Health ;
STAT_STABLE [ 8 ] = statFrame.Armor ;
STAT_STABLE [ 9 ] = statFrame.Reduction ;
STAT_STABLE [ 10 ] = statFrame.Dodge ;
STAT_STABLE [ 11 ] = statFrame.Parry ;
STAT_STABLE [ 12 ] = statFrame.Block ;
STAT_STABLE [ 13 ] = radar.Crit ;
STAT_STABLE [ 14 ] = radar.Haste ;
STAT_STABLE [ 15 ] = radar.Mastery ;
STAT_STABLE [ 16 ] = radar.Versatility ;
STAT_STABLE [ 17 ] = statFrame.Leech ;
STAT_STABLE [ 18 ] = statFrame.Avoidance ;
STAT_STABLE [ 19 ] = statFrame.MovementSpeed ;
STAT_STABLE [ 20 ] = statFrame.Speed ;
local statFrame_Short = Narci_ConciseStatFrame ;
SHORT_STAT_TABLE [ 1 ] = statFrame_Short.Primary ;
SHORT_STAT_TABLE [ 2 ] = statFrame_Short.Stamina ;
SHORT_STAT_TABLE [ 3 ] = statFrame_Short.Health ;
SHORT_STAT_TABLE [ 4 ] = statFrame_Short.Power ;
SHORT_STAT_TABLE [ 5 ] = statFrame_Short.Regen ;
SHORT_STAT_TABLE [ 6 ] = statFrame_Short.Crit ;
SHORT_STAT_TABLE [ 7 ] = statFrame_Short.Haste ;
SHORT_STAT_TABLE [ 8 ] = statFrame_Short.Mastery ;
SHORT_STAT_TABLE [ 9 ] = statFrame_Short.Versatility ;
SHORT_STAT_TABLE [ 10 ] = statFrame_Short.Leech ;
SHORT_STAT_TABLE [ 11 ] = statFrame_Short.Avoidance ;
SHORT_STAT_TABLE [ 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
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 ( ) ;
Toolbar : ShowUI ( " Narcissus " ) ;
ViewProfile : SaveView ( 5 ) ;
CameraUtil : UpdateParameters ( ) ;
CameraMover : MakeActive ( ) ;
MOG_MODE_OFFSET = 0 ;
local speedFactor = 180 / ( GetCVar ( " cameraYawMoveSpeed " ) or 180 ) ;
ZoomFactor.toSpeed = speedFactor * ZoomFactor.toSpeedBasic ;
ZoomFactor.fromSpeed = speedFactor * ZoomFactor.fromSpeedBasic ;
EL : Show ( ) ;
After ( 0 , function ( )
CameraMover : Enter ( ) ;
RadarChart : SetValue ( 0 , 0 , 0 , 0 , 1 ) ;
PlayLetteboxAnimation ( ) ;
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 ( ) ;
SlotButtonOverlayUtil : UpdateData ( ) ;
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 ( ) ;
PlayLetteboxAnimation ( " OUT " ) ;
EquipmentFlyoutFrame : Hide ( ) ;
Narci_ModelSettings : Hide ( ) ;
Toolbar : HideUI ( ) ;
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 ( ) ;
Toolbar : ShowUI ( " Narcissus " ) ;
ViewProfile : SaveView ( 5 ) ;
CameraUtil : UpdateParameters ( ) ;
CameraMover : MakeActive ( ) ;
SetCVar ( " test_cameraDynamicPitch " , 1 ) ;
local speedFactor = 180 / ( GetCVar ( " cameraYawMoveSpeed " ) or 180 ) ;
ZoomFactor.toSpeed = speedFactor * ZoomFactor.toSpeedBasic ;
ZoomFactor.fromSpeed = speedFactor * ZoomFactor.fromSpeedBasic ;
EL : Show ( ) ;
CameraMover : Pitch ( ) ;
After ( 0 , function ( )
Toolbar : Expand ( true ) ;
local toolbarButton = GetToolbarButtonByButtonType ( " Mog " ) ;
toolbarButton : OnClick ( ) ;
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 ( )
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
------------------------------------------------------
------------------Photo Mode Controller---------------
------------------------------------------------------
function Narci_KeyListener_OnEscapePressed ( self )
if IS_OPENED then
MiniButton : Click ( ) ;
if self then
self : SetPropagateKeyboardInput ( false ) ;
After ( 0 , function ( )
self : SetPropagateKeyboardInput ( true ) ;
end ) ;
end
end
end
local function UseXmogLayout ( )
MOG_MODE_OFFSET = 0.2 ;
NarciPlayerModelFrame1.xmogMode = 2 ;
if Narci_Character : IsVisible ( ) then
FadeFrame ( NarciModel_RightGradient , 0.5 , 1 ) ;
end
Narci_ModelContainer : Show ( ) ;
Narci_PlayerModelAnimIn : Show ( ) ;
Narci_PlayerModelGuideFrame.VignetteRightSmall : Show ( ) ;
Narci_GuideLineFrame.VirtualLineRight . AnimFrame.toX = - 600 ;
Narci_GuideLineFrame.VirtualLineRight . AnimFrame : Show ( ) ;
After ( 0 , function ( )
if not IsMounted ( ) then
CameraMover : Pitch ( ) ;
CameraMover : ZoomIn ( ZOOM_IN_VALUE_MOG ) ; --ajust by raceID
else
CameraMover : ZoomIn ( 8 ) ; --ajust by raceID
end
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 )
MOG_MODE_OFFSET = 0.2 ;
NarciPlayerModelFrame1.xmogMode = 2 ;
MsgAlertContainer : Display ( ) ;
UseXmogLayout ( ) ;
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_FACTOR_1 * zoom + SHOULDER_FACTOR_2 )
end
FadeFrame ( Narci_XmogNameFrame , 0.2 , 0 )
ShowAttributeButton ( ) ;
MOG_MODE_OFFSET = 0 ;
MsgAlertContainer : Hide ( ) ;
RadarChart : SetValue ( ) ;
end
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 ) or IsSpellKnown ( 366522 ) 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 SLOT_TABLE [ slot ] and SLOT_TABLE [ slot ] . itemID then
ItemList [ slot ] = { SLOT_TABLE [ slot ] . itemID , SLOT_TABLE [ slot ] . bonusID } ;
end
end
return NarciAPI.EncodeItemlist ( ItemList ) ;
end
local function CopyTexts ( textFormat , includeID )
local texts = Narci_XmogNameFrame.PlayerName : GetText ( ) or " My Transmog " ;
textFormat = textFormat or " text " ;
local source ;
if textFormat == " text " then
texts = texts .. " \n "
for i = 1 , # xmogTable do
local index = xmogTable [ i ] [ 1 ]
if SLOT_TABLE [ index ] and SLOT_TABLE [ index ] . Name : GetText ( ) then
local text = " |cFFFFD100 " .. xmogTable [ i ] [ 2 ] .. " :|r " .. ( SLOT_TABLE [ index ] . Name : GetText ( ) or " " ) ;
if includeID and SLOT_TABLE [ index ] . itemID then
text = text .. " |cFFacacac " .. SLOT_TABLE [ index ] . itemID .. " |r " ;
end
source = SLOT_TABLE [ index ] . ItemLevel : GetText ( ) ;
if source and source ~= " " then
text = text .. " ( " .. source .. " ) "
end
if text then
texts = texts .. " \n " .. text ;
end
end
end
elseif textFormat == " reddit " then
texts = " |cFF959595**|r " .. texts .. " |cFF959595** \n \n | Slot | Name | Source | " .. " \n " .. " |:--|:--|:--| "
for i = 1 , # xmogTable do
local index = xmogTable [ i ] [ 1 ]
if SLOT_TABLE [ index ] and SLOT_TABLE [ index ] . Name : GetText ( ) then
local text = " |cFF959595| |r|cFFFFD100 " .. xmogTable [ i ] [ 2 ] .. " |r |cFF959595| |r "
if includeID and SLOT_TABLE [ index ] . itemID then
text = text .. " |cFF959595[|r " .. ( SLOT_TABLE [ index ] . Name : GetText ( ) or " " ) .. " |cFF959595](https://www.wowhead.com/item=|r " .. SLOT_TABLE [ index ] . itemID .. " )|r "
else
text = text .. ( SLOT_TABLE [ index ] . Name : GetText ( ) or " " )
end
source = SLOT_TABLE [ 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 " ;
else
if textFormat == " 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 textFormat == " 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 textFormat == " 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 SLOT_TABLE [ index ] and SLOT_TABLE [ index ] . Name : GetText ( ) then
local text = " |cFF959595[tr][td]|r " .. " |cFFFFD100 " .. xmogTable [ i ] [ 2 ] .. " |r|cFF959595[/td][td]|r "
if includeID and SLOT_TABLE [ index ] . itemID then
if textFormat == " wowhead " then
text = text .. " [item= " .. SLOT_TABLE [ index ] . itemID .. " |r|cFF959595][/td]|r "
elseif textFormat == " nga " then
text = text .. " |cFF959595[url=https://www.wowhead.com/item= " .. SLOT_TABLE [ index ] . itemID .. " ]|r " .. ( SLOT_TABLE [ index ] . Name : GetText ( ) or " " ) .. " |cFF959595[/url][/td]|r "
elseif textFormat == " mmo-champion " then
text = text .. " |cFF959595[url=https://www.wowdb.com/items/ " .. SLOT_TABLE [ index ] . itemID .. " ]|r " .. ( SLOT_TABLE [ index ] . Name : GetText ( ) or " " ) .. " |cFF959595[/url][/td]|r "
end
else
text = text .. ( SLOT_TABLE [ index ] . Name : GetText ( ) or " " ) .. " |r|cFF959595[/td]|r "
end
source = SLOT_TABLE [ 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 textFormat == " wowhead " then
texts = GetWowHeadDressingRoomURL ( ) ;
end
end
return texts ;
end
local function Narci_XmogButton_OnClick ( self )
MoveViewRightStop ( ) ;
EquipmentFlyoutFrame : Hide ( ) ;
MOG_MODE = not MOG_MODE ;
self.isOn = MOG_MODE ;
if self.isOn then
FadeFrame ( Narci_VignetteRightSmall , 0.5 , NarcissusDB.VignetteStrength ) ;
FadeFrame ( Narci_VignetteRightLarge , 0.5 , 0 ) ;
Narci_SnowEffect ( false ) ;
PlayLetteboxAnimation ( " OUT " ) ;
Narci_XmogNameFrame.PlayerName : SetText ( Narci_PlayerInfoFrame.PlayerName : GetText ( ) )
Toolbar.TransmogListFrame : ShowUI ( ) ;
Toolbar.showTransmogFrame = true ;
else
--Exit Xmog mode
Toolbar.TransmogListFrame : Hide ( ) ;
Toolbar.showTransmogFrame = nil ;
FadeFrame ( Narci_VignetteRightSmall , 0.5 , 0 ) ;
FadeFrame ( Narci_VignetteRightLarge , 0.5 , NarcissusDB.VignetteStrength ) ;
Narci_SnowEffect ( true ) ;
PlayLetteboxAnimation ( ) ;
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 ( ) ;
if not Narci_ExitConfirmationDialog : IsShown ( ) then
Narci.showExitConfirm = false ;
end
if ( not InCombatLockdown ( ) ) and ( not Narci_Character : IsShown ( ) ) then
Narci_Character : Show ( ) ;
Narci_Character : SetAlpha ( 1 ) ;
StatsUpdator : Gradual ( ) ;
end
end
SlotController : LazyRefresh ( ) ;
After ( 0.1 , function ( )
ActivateMogMode ( ) ;
end )
self : UpdateIcon ( ) ;
end
addon.OverrideToolbarButtonOnClickFunc ( " Mog " , Narci_XmogButton_OnClick ) ;
addon.OverrideToolbarButtonOnInitFunc ( " Mog " , function ( self )
if MOG_MODE then
self.isOn = true ;
self : UpdateIcon ( ) ;
end
end ) ;
Toolbar.TransmogListFrame . getItemListFunc = CopyTexts ;
function Narci_SetButtonColor ( self )
ColorUtil : SetWidgetColor ( self.Color ) ;
ColorUtil : SetWidgetColor ( self.HighlightColor ) ;
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
------Photo Mode Toolbar------
hooksecurefunc ( " SetUIVisibility " , function ( state )
if IS_OPENED then --when Narcissus hide the UI
if state then
MsgAlertContainer : SetDND ( true ) ;
Toolbar : UseLowerLevel ( true ) ;
else
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
if not GetKeepActionCam ( ) then
After ( 0.6 , function ( )
ConsoleExec ( " actioncam off " ) ;
end )
end
Toolbar : HideUI ( ) ;
else
local bar = Toolbar ;
if not bar : IsShown ( ) then
CVarTemp.shoulderOffset = GetCVar ( " test_cameraOverShoulder " ) ;
end
bar : ShowUI ( " Blizzard " ) ;
end
end
end )
do
--Slash Command
local commandName = " narci " ;
local commandAlias = " narcissus " ;
local function callback ( msg )
if not msg then
msg = " " ;
end
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 ) ;
if NarciDressingRoomOverlay then
NarciDressingRoomOverlay : ShowItemList ( ) ;
end
elseif msg == " resetposition " then
MiniButton : ResetPosition ( ) ;
elseif string.find ( msg , " /outfit " ) then
Narci : LoadOutfitSlashCommand ( msg ) ;
--/narci /outfit v1 50109,182541,0,77345,182521,2633,0,181613,182527,79067,182538,84323,80378,-1,0,77903,0
else
local color = " |cff40C7EB " ;
print ( " " ) ;
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 " ) ;
end
end
--RegisterNewSlashCommand(callback, commandName, commandAlias);
---- Alternative method to avoid slash command taint
if ChatEdit_HandleChatType then
local VALID_COMMANDS = {
[ " /NARCI " ] = true ,
[ " /NARCISSUS " ] = true ,
} ;
local c , m ;
hooksecurefunc ( " ChatEdit_HandleChatType " , function ( editBox , msg , command , send )
c = command ;
m = msg ;
if send == 1 then
if c and VALID_COMMANDS [ c ] then
callback ( m ) ;
end
c = nil ;
m = nil ;
end
end ) ;
end
--local f = CreateFrame("Frame");
--f:RegisterEvent("EXECUTE_CHAT_LINE");
--f:SetScript("OnEvent", function(self, event, line)
-- print(line)
--end)
end
----------------
--3D Animation--
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 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 ) ;
local RACE_PORTRAIT_CAMERA = { --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 √
} ,
[ 52 ] = { [ 2 ] = { 18 , - 18 , 1.4 , false , 1 } , --Dracthyr
[ 3 ] = { 18 , - 18 , 1.4 , false , 1 } ,
} ,
[ 520 ] = { [ 2 ] = { 8 , - 5 , 0.75 , 1.2 , 0 } , --Dracthyr Visage Male
[ 3 ] = { 12 , - 10 , 0.71 , 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 inHumanForm = IsPlayerInAlteredForm ( ) ;
if not inHumanForm then
raceID = 128 ;
end
elseif raceID == 52 or raceID == 70 then
local inVisageForm = IsPlayerInAlteredForm ( ) ;
if not inVisageForm then
raceID = 52 ;
else
raceID = 520 ;
end
end
local model ;
if RACE_PORTRAIT_CAMERA [ raceID ] and RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] then
if Narci_FigureModelReference then
Narci_FigureModelReference : SetPoint ( " CENTER " , RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 1 ] , RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 2 ] )
end
for i = 1 , # ModelPieces do
model = ModelPieces [ i ] ;
TransitionAPI.SetModelByUnit ( model , " player " ) ;
model : SetCamera ( RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 5 ] ) ;
model : MakeCurrentCameraCustom ( ) ;
if RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 3 ] then
model : SetCameraDistance ( RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 3 ] )
end
if RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 4 ] then
a1 , a2 , a3 = model : GetCameraPosition ( ) ;
model : SetCameraPosition ( a1 , a2 , RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 4 ] )
end
if RACE_PORTRAIT_CAMERA [ raceID ] [ GenderID ] [ 6 ] then
model : SetAnimation ( 2 , RACE_PORTRAIT_CAMERA [ 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 ) ;
TransitionAPI.SetModelLight ( model , 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 ( " PLAYER_ENTERING_WORLD " ) ;
EL : RegisterUnitEvent ( " UNIT_NAME_UPDATE " , " player " ) ;
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 : SetScript ( " OnEvent " , function ( self , event , ... )
--print(event)
if event == " PLAYER_ENTERING_WORLD " then
self : UnregisterEvent ( event ) ;
After ( 2 , function ( )
Narci_AliasButton_SetState ( ) ;
StatsUpdator : Instant ( ) ;
RadarChart : SetValue ( 0 , 0 , 0 , 0 , 1 ) ;
UpdateXmogName ( ) ;
end )
local AnimSequenceInfo = Narci.AnimSequenceInfo ;
InitializeAnimationContainer ( ASC2 , AnimSequenceInfo [ " Heart " ] , Narci_HeartofAzeroth_AnimFrame.Sequence )
local HeartSerialNumber = strsub ( UnitGUID ( " player " ) , 8 , 15 ) ;
Narci_HeartofAzeroth_AnimFrame.SN : SetText ( " No. " .. HeartSerialNumber ) ;
Narci_HeartofAzeroth_AnimFrame.Quote : SetText ( L [ " Heart Azerite Quote " ] ) ;
UpdateXmogName ( ) ;
SetCVar ( " CameraKeepCharacterCentered " , 0 ) ;
--CameraMover:SetBlend(NarcissusDB.CameraTransition); --Load in Settings.lua
DefaultTooltip = NarciGameTooltip ; --Created in Module\GameTooltip.lua
if not ItemTooltip then
ItemTooltip = DefaultTooltip ;
end
DefaultTooltip : SetParent ( Narci_Character ) ;
DefaultTooltip : SetFrameStrata ( " TOOLTIP " ) ;
DefaultTooltip.offsetX = 4 ;
DefaultTooltip.offsetY = - 16 ;
DefaultTooltip : SetIgnoreParentAlpha ( true ) ;
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 ( ) ;
else
if NarcissusDB.CameraSafeMode then
local temp = GetCVar ( " test_cameraOverShoulder " ) ;
if tonumber ( temp ) ~= 0 then
--SetCVar("test_cameraOverShoulder", 0);
ConsoleExec ( " actioncam off " ) ;
NarciAPI.PrintPresetMessage ( " camera " ) ;
end
end
end
After ( 1.7 , function ( )
UpdateCharacterInfoFrame ( ) ;
if CVarTemp.isDynamicCamLoaded then
CameraMover : UpdateMovementMethodForDynamicCam ( ) ;
else
hooksecurefunc ( " CameraZoomIn " , function ( increment )
if IS_OPENED then
UpdateShoulderCVar : Start ( - increment ) ;
end
end )
hooksecurefunc ( " CameraZoomOut " , function ( increment )
if IS_OPENED then
UpdateShoulderCVar : Start ( increment ) ;
end
end )
end
end )
elseif event == " PLAYER_EQUIPMENT_CHANGED " then
local slotID , isItem = ... ;
USE_DELAY = false ;
SlotController : Refresh ( slotID ) ;
if EquipmentFlyoutFrame : IsShown ( ) and EquipmentFlyoutFrame.slotID then
EquipmentFlyoutFrame : DisplayItemsBySlotID ( EquipmentFlyoutFrame.slotID , false ) ;
end
USE_DELAY = true ;
ItemLevelFrame : AsyncUpdate ( ) ;
local slot = SLOT_TABLE [ slotID ] ;
if slot and slot : IsMouseOver ( ) then
slot : Disable ( ) ;
After ( 0 , function ( )
slot : Enable ( ) ;
end ) ;
end
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.pendingItemLevel then
self.pendingItemLevel = true ;
After ( 0.1 , function ( ) -- only want 1 update per 0.1s
ItemLevelFrame : UpdateItemLevel ( ) ;
self.pendingItemLevel = nil ;
end )
end
elseif event == " COVENANT_CHOSEN " then
local covenantID = ... ;
ItemLevelFrame : AsyncUpdate ( ) ;
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 ) ;
SlotButtonOverlayUtil : UpdateData ( ) ;
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
if event == " UNIT_AURA " then
local inAlteredForm = IsPlayerInAlteredForm ( ) ;
if self.wasAlteredForm ~= inAlteredForm then
self.wasAlteredForm = inAlteredForm ;
CameraUtil : OnPlayerFormChanged ( 0.0 ) ;
end
end
elseif event == " PLAYER_TARGET_CHANGED " then
RefreshStats ( 8 ) ; --Armor
RefreshStats ( 9 ) ; --Damage Reduction
elseif event == " UPDATE_SHAPESHIFT_FORM " then
CameraUtil : OnPlayerFormChanged ( 0.1 ) ;
elseif event == " PLAYER_MOUNT_DISPLAY_CHANGED " then
CameraUtil : OnPlayerFormChanged ( 0.0 ) ;
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 : AsyncUpdate ( 0.1 ) ;
elseif event == " UNIT_INVENTORY_CHANGED " then
SlotController : LazyRefresh ( " temp " ) ;
end
end )
function EL : ToggleDynamicEvents ( state )
if state then
for _ , event in ipairs ( self.EVENTS_DYNAMIC ) do
self : RegisterUnitEvent ( event ) ;
end
for _ , event in ipairs ( self.EVENTS_UNIT ) do
self : RegisterUnitEvent ( event , " player " ) ;
end
else
for _ , event in ipairs ( self.EVENTS_DYNAMIC ) do
self : UnregisterEvent ( event ) ;
end
for _ , event in ipairs ( self.EVENTS_UNIT ) do
self : UnregisterEvent ( event ) ;
end
end
end
EL : SetScript ( " OnShow " , function ( self )
self : ToggleDynamicEvents ( true ) ;
if NarciAR then
NarciAR : Show ( ) ;
end
end )
EL : SetScript ( " OnHide " , function ( self )
self : ToggleDynamicEvents ( false ) ;
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 ;
AssignFrame ( ) ;
AssignFrame = nil ;
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_GuideLineFrame_OnSizing ( self , offset )
local W ;
local W0 , H = WorldFrame : GetSize ( ) ;
if ( W0 and H ) and H ~= 0 then
local ratio = floor ( W0 / H * 100 + 0.5 ) / 100 ;
if ratio == 1.78 then
return
end
self : ClearAllPoints ( ) ;
self : SetPoint ( " TOP " , UIParent , " TOP " , 0 , 0 ) ;
self : SetPoint ( " BOTTOM " , UIParent , " BOTTOM " , 0 , 0 ) ;
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
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 SLOT_TABLE [ slotID ] end ;
Narci.RefreshSlot = function ( slotID ) SlotController : Refresh ( slotID ) return SLOT_TABLE [ slotID ] end ;
Narci.RefreshAllSlots = SlotController.RefreshAll ;
Narci.RefreshAllStats = StatsUpdator.Instant ;
function Narci : SetItemTooltipStyle ( id )
end
function Narci : CloseCharacterUI ( )
if IS_OPENED then
Narci_Open ( ) ;
end
end
do
local SettingFunctions = addon.SettingFunctions ;
function SettingFunctions . SetItemTooltipStyle ( id , db )
if id == nil then
id = db [ " ItemTooltipStyle " ] ;
end
if id == 2 then
ItemTooltip = NarciGameTooltip ;
else
ItemTooltip = NarciEquipmentTooltip ;
end
NarciEquipmentTooltip : SetParent ( Narci_Character ) ;
end
function SettingFunctions . SetVignetteStrength ( alpha , db )
if alpha == nil then
alpha = db [ " VignetteStrength " ] ;
end
alpha = tonumber ( alpha ) 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
function SettingFunctions . SetUltraWideFrameOffset ( offset , db )
--A positive offset expands the reference frame.
if not offset then
offset = db [ " BaseLineOffset " ] ;
offset = tonumber ( offset ) or 0
end
Narci_GuideLineFrame_OnSizing ( Narci_GuideLineFrame , - offset ) ;
end
function SettingFunctions . ShowDetailedStats ( state , db )
if state == nil then
state = db [ " DetailedIlvlInfo " ] ;
end
if Narci_Attribute : IsVisible ( ) then
if state then
FadeFrame ( Narci_DetailedStatFrame , 0.5 , 1 ) ;
FadeFrame ( RadarChart , 0.5 , 1 ) ;
FadeFrame ( Narci_ConciseStatFrame , 0.5 , 0 ) ;
else
FadeFrame ( Narci_DetailedStatFrame , 0.5 , 0 ) ;
FadeFrame ( RadarChart , 0.5 , 0 ) ;
FadeFrame ( Narci_ConciseStatFrame , 0.5 , 1 ) ;
end
else
if state 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
Narci_ItemLevelFrame : ToggleExtraInfo ( state ) ;
Narci_ItemLevelFrame.showExtraInfo = state ;
Narci_NavBar : SetMaximizedMode ( state ) ;
end
function SettingFunctions . SetCharacterUIScale ( scale , db )
if not scale then
scale = db [ " GlobalScale " ] ;
end
scale = tonumber ( scale ) or 1 ;
NarciScreenshotToolbar : SetDefaultScale ( scale ) ;
Narci_Character : SetScale ( scale ) ;
Narci_Attribute : SetScale ( scale ) ;
NarciTooltip : SetScale ( scale ) ;
end
function SettingFunctions . SetItemNameTextHeight ( height , db )
if not height then
height = db [ " FontHeightItemName " ] ;
end
height = tonumber ( height ) or 10 ;
local font , _ , flag = SLOT_TABLE [ 1 ] . Name : GetFont ( ) ;
for id , slotButton in pairs ( SLOT_TABLE ) do
slotButton.Name : SetFont ( font , height , flag ) ;
slotButton : UpdateGradientSize ( ) ;
end
end
function SettingFunctions . SetItemNameTextWidth ( width , db )
if not width then
width = db [ " ItemNameWidth " ] ;
end
width = tonumber ( width ) or 200 ;
if width >= 200 then
width = 512 ;
end
for id , slotButton in pairs ( SLOT_TABLE ) do
slotButton.Name : SetWidth ( width ) ;
slotButton.ItemLevel : SetWidth ( width ) ;
slotButton : UpdateGradientSize ( ) ;
end
end
function SettingFunctions . SetItemNameTruncated ( state , db )
if state == nil then
state = db [ " TruncateText " ] ;
end
local maxLines ;
if state then
maxLines = 1 ;
else
maxLines = 2 ;
end
for id , slotButton in pairs ( SLOT_TABLE ) do
slotButton.Name : SetMaxLines ( maxLines ) ;
slotButton.ItemLevel : SetMaxLines ( maxLines ) ;
slotButton.Name : SetWidth ( slotButton.Name : GetWidth ( ) + 1 )
slotButton.Name : SetWidth ( slotButton.Name : GetWidth ( ) - 1 )
slotButton.ItemLevel : SetWidth ( slotButton.Name : GetWidth ( ) + 1 )
slotButton.ItemLevel : SetWidth ( slotButton.Name : GetWidth ( ) - 1 )
slotButton : UpdateGradientSize ( ) ;
end
end
function SettingFunctions . UseCameraTransition ( state , db )
if state == nil then
state = db [ " CameraTransition " ] ;
end
CameraMover : SetBlend ( state ) ;
end
function SettingFunctions . EnableCameraSafeMode ( state , db )
if state == nil then
state = db [ " CameraSafeMode " ] ;
end
CVarTemp.cameraSafeMode = state ;
end
function SettingFunctions . SetDefaultZoomClose ( state , db )
if state == nil then
state = db [ " UseBustShot " ] ;
end
if state then
CAM_DISTANCE_INDEX = 1 ;
else
CAM_DISTANCE_INDEX = 4 ;
end
end
function SettingFunctions . EnableMissingEnchantAlert ( state , db )
if state == nil then
state = db [ " MissingEnchantAlert " ] ;
end
--only enabled when player reach max level
if not NarciAPI.IsPlayerAtMaxLevel ( ) then
state = false ;
end
SHOW_MISSING_ENCHANT_ALERT = state ;
SlotButtonOverlayUtil : SetEnabled ( state ) ;
SlotController : ClearCache ( ) ;
if Narci_Character and Narci_Character : IsShown ( ) then
SlotController : LazyRefresh ( ) ;
end
end
end
--[[
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
--]]