local _ , addon = ...
local TransitionAPI = addon.TransitionAPI ;
local C_Item = C_Item ;
local After = C_Timer.After ;
local GetItemInfo = GetItemInfo ;
local GetItemInfoInstant = GetItemInfoInstant ;
local UIFrameFadeIn = UIFrameFadeIn ;
local UIFrameFadeOut = UIFrameFadeOut ;
local FadeFrame = NarciFadeUI.Fade ;
local PlaySound = PlaySound ;
local _ , _ , _ , tocversion = GetBuildInfo ( ) ;
local find = string.find ;
local match = string.match ;
local strsub = string.sub ;
local strsplit = strsplit ;
local min = math.min ;
local max = math.max ;
local abs = math.abs ;
local floor = math.floor ;
local unpack = unpack ;
local tinsert = table.insert ;
local TEXT_LOCALE = GetLocale ( ) ;
local Narci = Narci ;
local NarciAPI = NarciAPI ;
local SecureContainer = CreateFrame ( " Frame " , " NarciSecureFrameContainer " ) ;
SecureContainer : Hide ( ) ;
------------------------
--Redirect API for 9.0--
------------------------
tocversion = tonumber ( tocversion ) ;
ExpansionTransitionBackdropTemplateMixin = { } ;
if BackdropTemplateMixin then
ExpansionTransitionBackdropTemplateMixin = CreateFromMixins ( BackdropTemplateMixin ) ;
end
--GetSlotVisualID
local IGNORED_MOG_SLOT = {
[ 11 ] = true ,
[ 12 ] = true ,
[ 13 ] = true ,
[ 14 ] = true ,
} ;
local function IsSlotValidForTransmog ( slotID )
return ( slotID ) and ( not IGNORED_MOG_SLOT [ slotID ] ) and slotID ~= 2
end
NarciAPI.IsSlotValidForTransmog = IsSlotValidForTransmog ;
local function NarciAPI_GetSlotVisualID ( slotID )
if IGNORED_MOG_SLOT [ slotID ] then
--slotID = 2 ~ Use neck to show right shoulder
return 0 , 0 ;
end
local isSecondaryAppearance ;
if slotID == 2 then
isSecondaryAppearance = true ; --Enum.TransmogModification.Secondary
slotID = 3 ;
end
local itemLocation = ItemLocation : CreateFromEquipmentSlot ( slotID ) ;
if not itemLocation or not C_Item.DoesItemExist ( itemLocation ) then
return 0 , 0 ;
end
local transmogLocation = CreateFromMixins ( TransmogLocationMixin ) ;
local transmogType = 0 ;
local modification = 0 ;
if slotID == 3 then
--Shoulders
local itemTransmogInfo = C_Item.GetAppliedItemTransmogInfo ( itemLocation ) ;
local hasSecondaryAppearance ;
if itemTransmogInfo then
hasSecondaryAppearance = itemTransmogInfo.secondaryAppearanceID ~= 0 ; --show direction mark
end
if isSecondaryAppearance then
if not hasSecondaryAppearance then
return 0 , 0 ;
end
modification = 1 ; --Enum.TransmogModification : 0 ~ Main, 1 ~ Secondary
end
transmogLocation : Set ( slotID , transmogType , modification ) ;
local baseSourceID , baseVisualID , appliedSourceID , appliedVisualID , pendingSourceID , pendingVisualID , hasPendingUndo , isHideVisual , itemSubclass = C_Transmog.GetSlotVisualInfo ( transmogLocation ) ;
if ( appliedSourceID == 0 ) then
appliedSourceID = baseSourceID ;
appliedVisualID = baseVisualID ;
end
return appliedSourceID , appliedVisualID , hasSecondaryAppearance ;
else
transmogLocation : Set ( slotID , transmogType , modification ) ;
local baseSourceID , baseVisualID , appliedSourceID , appliedVisualID , pendingSourceID , pendingVisualID , hasPendingUndo , isHideVisual , itemSubclass = C_Transmog.GetSlotVisualInfo ( transmogLocation ) ;
if ( appliedSourceID == 0 ) then
appliedSourceID = baseSourceID ;
appliedVisualID = baseVisualID ;
end
return appliedSourceID , appliedVisualID ;
end
end
--/script for i =1, 17 do if C_Transmog.CanHaveSecondaryAppearanceForSlotID(i) then print(i) end end
--/script C_Transmog.GetSlotVisualInfo( CreateFromMixins(TransmogLocationMixin):Set(3, 0, 0) )
--/dump C_Item.GetAppliedItemTransmogInfo(ItemLocation:CreateFromEquipmentSlot(3))
--/dump C_Transmog.GetSlotVisualInfo((CreateFromMixins(TransmogLocationMixin)):Set(3, 0, 0));
NarciAPI.GetSlotVisualID = NarciAPI_GetSlotVisualID ;
--------------------
----API Datebase----
--------------------
--[[
function GetArtifactVisualModID ( colorID )
colorID = colorID or 42 ;
local PRINT = false ;
local baseSourceID , baseVisualID , appliedSourceID , appliedVisualID , pendingSourceID , pendingVisualID , hasPendingUndo , hideVisual = C_Transmog.GetSlotVisualInfo ( 16 , 0 ) ;
if not appliedSourceID or appliedSourceID == 0 then
appliedSourceID = baseSourceID ;
end
local categoryID , visualID , canEnchant , icon , _ , itemLink , transmogLink , _ = C_TransmogCollection.GetAppearanceSourceInfo ( appliedSourceID )
local sourceInfo = C_TransmogCollection.GetSourceInfo ( appliedSourceID )
if sourceInfo and PRINT then
for k , v in pairs ( sourceInfo ) do
print ( k .. " " .. tostring ( v ) )
end
else
print ( sourceInfo.itemModID ) ;
end
itemID = sourceInfo.itemID or 127829 ;
itemLink = " \124 cffe5cc80 \124 Hitem: " .. itemID .. " ::::::::120::16777472::2::: " .. colorID .. " ::::::::::::: \124 h[ " .. ( sourceInfo.name or " " ) .. " ] \124 h \124 r "
DEFAULT_CHAT_FRAME : AddMessage ( itemLink )
end
--]]
-----Color API------
local mapColors = {
--[0] = { 35, 96, 147}, --default Blue 0.1372, 0.3765, 0.5765
[ 0 ] = { 78 , 78 , 78 } , --Default Black
[ 1 ] = { 121 , 31 , 35 } , --Orgrimmar
[ 2 ] = { 49 , 176 , 107 } , --Zuldazar
[ 3 ] = { 187 , 161 , 134 } , --Vol'dun
[ 4 ] = { 89 , 140 , 123 } , --Tiragarde Sound
[ 5 ] = { 127 , 164 , 114 } , --Stormsong
[ 6 ] = { 156 , 165 , 153 } , --Drustvar
[ 7 ] = { 42 , 63 , 79 } , --Halls of Shadow
--[UiMapID] = {r, g, b}
--Shadowlands
[ 1970 ] = { 137 , 218 , 247 } , --Zereth Mortis
[ 1670 ] = { 76 , 86 , 109 } , --Oribos
[ 1533 ] = { 197 , 185 , 172 } , --Bastion
[ 1707 ] = { 193 , 199 , 210 } , --Elysian Hold
[ 1708 ] = { 168 , 188 , 232 } , --Sanctum of Binding
[ 1701 ] = { 57 , 66 , 154 } , --Heart of the Forest
[ 1565 ] = { 57 , 66 , 154 } , --Ardenweald
[ 1536 ] = { 25 , 97 , 85 } , --Maldraxxus
[ 1698 ] = { 25 , 97 , 85 } , --Seat of the Primus
[ 1525 ] = { 48 , 96 , 153 } , --Revendreth
[ 1911 ] = { 53 , 80 , 115 } , --Torghast Entrance
[ 1912 ] = { 53 , 80 , 115 } , --Runecrafter
--Major City--
[ 84 ] = { 129 , 144 , 155 } , --Stormwind City
[ 85 ] = { 121 , 52 , 55 } , --Orgrimmar
[ 86 ] = { 121 , 31 , 35 } , --Orgrimmar - Cleft of Shadow
[ 463 ] = { 163 , 99 , 89 } , --Echo Isles
[ 87 ] = { 102 , 64 , 58 } , --Ironforge
[ 27 ] = { 151 , 198 , 213 } , --Dun Morogh
[ 469 ] = { 151 , 198 , 213 } , --New Tinkertown
[ 88 ] = { 115 , 140 , 113 } , --Thunder Bluff
[ 89 ] = { 121 , 31 , 35 } , --Darnassus R.I.P.
[ 90 ] = { 42 , 63 , 79 } , --Undercity
[ 110 ] = { 172 , 58 , 54 } , --Silvermoon City
[ 202 ] = { 78 , 78 , 78 } , --Gilneas City
[ 217 ] = { 78 , 78 , 78 } , --Ruins of Gilneas
[ 627 ] = { 102 , 58 , 64 } , --Dalaran Broken Isles
[ 111 ] = { 88 , 108 , 91 } , --Shattrath City
-- TBC --
[ 107 ] = { 181 , 151 , 93 } , --Nagrand Outland
[ 109 ] = { 96 , 48 , 108 } , --Netherstorm
[ 102 ] = { 61 , 77 , 162 } , --Zangarmash
[ 105 ] = { 123 , 104 , 80 } , --Blade's Edge Mountains
-- MOP --
[ 378 ] = { 120 , 107 , 81 } , --The Wandering Isle
[ 371 ] = { 95 , 132 , 78 } , --The Jade Forrest
[ 379 ] = { 90 , 119 , 156 } , --Kun-Lai Summit
-- LEG --
[ 641 ] = { 70 , 128 , 116 } , --Val'sharah
-- BFA --
[ 81 ] = { 98 , 84 , 77 } , --Silithus
[ 1473 ] = { 168 , 136 , 90 } , --Chamber of Heart
[ 1163 ] = { 89 , 140 , 123 } , --Dazar'alor - The Great Seal
[ 1164 ] = { 89 , 140 , 123 } , --Dazar'alor - Hall of Chroniclers
[ 1165 ] = { 89 , 140 , 123 } , --Dazar'alor
[ 862 ] = { 89 , 140 , 123 } , --Zuldazar
[ 864 ] = { 187 , 161 , 134 } , --Vol'dun
[ 863 ] = { 113 , 173 , 183 } , --Nazmir
[ 895 ] = { 89 , 140 , 123 } , --Tiragarde Sound
[ 1161 ] = { 89 , 140 , 123 } , --Boralus
[ 942 ] = { 127 , 164 , 114 } , --Stormsong
[ 896 ] = { 156 , 165 , 153 } , --Drustvar
[ 1462 ] = { 16 , 156 , 192 } , --Mechagon
[ 1355 ] = { 41 , 74 , 127 } , --Nazjatar
[ 249 ] = { 180 , 149 , 121 } , --Uldum Normal
[ 1527 ] = { 180 , 149 , 121 } , --Uldum Assault
[ 390 ] = { 150 , 117 , 94 } , --Eternal Blossoms Normal
[ 1530 ] = { 150 , 117 , 94 } , --Eternal Blossoms Assault --{105, 71, 156}
[ " NZ " ] = { 105 , 71 , 156 } , --During Assault: N'Zoth Purple Skybox
[ 1580 ] = { 105 , 71 , 156 } , --Ny'alotha - Vision of Destiny
[ 1581 ] = { 105 , 71 , 156 } , --Ny'alotha - Annex of Prophecy
[ 1582 ] = { 105 , 71 , 156 } , --Ny'alotha - Ny'alotha
[ 1590 ] = { 105 , 71 , 156 } , --Ny'alotha - The Hive
[ 1591 ] = { 105 , 71 , 156 } , --Ny'alotha - Terrace of Desolation
[ 1592 ] = { 105 , 71 , 156 } , --Ny'alotha - The Ritual Chamber
[ 1593 ] = { 105 , 71 , 156 } , --Ny'alotha - Twilight Landing
[ 1594 ] = { 105 , 71 , 156 } , --Ny'alotha - Maw of Gor'ma
[ 1595 ] = { 105 , 71 , 156 } , --Ny'alotha - Warren of Decay
[ 1596 ] = { 105 , 71 , 156 } , --Ny'alotha - Chamber of Rebirth
[ 1597 ] = { 105 , 71 , 156 } , --Ny'alotha - Locus of Infinite Truths
--Allied Race Starting Zone--
[ 124 ] = { 87 , 56 , 132 } , --DK
[ 1186 ] = { 117 , 26 , 22 } , --Dark Iron
[ 971 ] = { 65 , 57 , 124 } , --Void Elf
--Class Hall
[ 625 ] = { 42 , 63 , 79 } , --Dalaran, Broken Isles Halls of Shadow
[ 626 ] = { 42 , 63 , 79 } , --Hall of Shadow
[ 715 ] = { 149 , 180 , 146 } , --Emerald Dreamway
[ 747 ] = { 70 , 128 , 116 } , --The Dreamgrove
--Frequently Visited
[ 198 ] = { 78 , 78 , 78 } , --Hyjal
} ;
NarciThemeUtil = { } ;
NarciThemeUtil.colorIndex = 0 ;
function NarciThemeUtil : GetColorTable ( )
local R , G , B = unpack ( mapColors [ self.colorIndex ] ) ;
return { R / 255 , G / 255 , B / 255 }
end
function NarciThemeUtil : GetColor ( )
local R , G , B = unpack ( mapColors [ self.colorIndex ] ) ;
return R / 255 , G / 255 , B / 255
end
function NarciThemeUtil : GetColorIndex ( )
return self.colorIndex
end
function NarciThemeUtil : SetColorIndex ( index )
if index and mapColors [ index ] then
self.colorIndex = index
else
self.colorIndex = 0 ;
end
return self : GetColorTable ( )
end
----------------------------------------------------------------------
local function NarciAPI_ConvertHexColorToRGB ( hexColor , includeHex )
local r = tonumber ( strsub ( hexColor , 1 , 2 ) , 16 ) / 255 ;
local g = tonumber ( strsub ( hexColor , 3 , 4 ) , 16 ) / 255 ;
local b = tonumber ( strsub ( hexColor , 5 , 6 ) , 16 ) / 255 ;
if includeHex then
return { r , g , b , hexColor } ;
else
return { r , g , b } ;
end
end
local function RGB2HSV ( r , g , b )
local Cmax = max ( r , g , b ) ;
local Cmin = min ( r , g , b ) ;
local dif = Cmax - Cmin ;
local Hue = 0 ;
local Brightness = floor ( 100 * ( Cmax / 255 ) + 0.5 ) / 100 ;
local Stauration = 0 ;
if Cmax ~= 0 then Stauration = floor ( 100 * ( dif / Cmax ) + 0.5 ) / 100 ; end ;
if dif ~= 0 then
if r == Cmax and g >= b then
Hue = ( g - b ) / dif + 0 ;
elseif r == Cmax and g < b then
Hue = ( g - b ) / dif + 6 ;
elseif g == Cmax then
Hue = ( b - r ) / dif + 2 ;
elseif b == Cmax then
Hue = ( r - g ) / dif + 4 ;
end
end
return floor ( 60 * Hue + 0.5 ) , Stauration , Brightness
end
local function RGBRatio2HSV ( r , g , b )
return RGB2HSV ( 255 * r , 255 * g , 255 * b )
end
local function HSV2RGB ( h , s , v )
local Cmax = 255 * v ;
local Cmin = Cmax * ( 1 - s ) ;
local i = floor ( h / 60 ) ;
local dif = h % 60 ;
local Cmid = ( Cmax - Cmin ) * dif / 60 ;
local r , g , b ;
if i == 0 or i == 6 then
r , g , b = Cmax , Cmin + Cmid , Cmin ;
elseif i == 1 then
r , g , b = Cmax - Cmid , Cmax , Cmin ;
elseif i == 2 then
r , g , b = Cmin , Cmax , Cmin + Cmid ;
elseif i == 3 then
r , g , b = Cmin , Cmax - Cmid , Cmax ;
elseif i == 4 then
r , g , b = Cmin + Cmid , Cmin , Cmax ;
else
r , g , b = Cmax , Cmin , Cmax - Cmid ;
end
r , g , b = floor ( r + 0.5 ) / 255 , floor ( g + 0.5 ) / 255 , floor ( b + 0.5 ) / 255 ;
return r , g , b
end
NarciAPI.ConvertHexColorToRGB = NarciAPI_ConvertHexColorToRGB ;
NarciAPI.RGB2HSV = RGB2HSV ;
NarciAPI.RGBRatio2HSV = RGBRatio2HSV ;
NarciAPI.HSV2RGB = HSV2RGB ;
Narci_FontColor = {
[ " Brown " ] = { 0.85098 , 0.80392 , 0.70588 , " |cffd9cdb4 " } ,
[ " DarkGrey " ] = { 0.42 , 0.42 , 0.42 , " |cff6b6b6b " } ,
[ " LightGrey " ] = { 0.72 , 0.72 , 0.72 , " |cffb8b8b8 " } ,
[ " White " ] = { 0.88 , 0.88 , 0.88 , " |cffe0e0e0 " } ,
[ " Good " ] = { 0.4862 , 0.7725 , 0.4627 , " |cff7cc576 " } ,
[ " Bad " ] = { 1 , 0.3137 , 0.3137 , 0.3137 , " |cffff5050 " } ,
[ " Corrupt " ] = { 0.584 , 0.428 , 0.82 , " |cff946dd1 " } ,
} ;
local customQualityColors = {
[ 0 ] = " 9d9d9d " , --Poor
[ 1 ] = " ffffff " , --Common
[ 2 ] = " 1eff00 " , --Uncommon
[ 3 ] = " 699eff " , --Rare 0070dd 699eff
[ 4 ] = " b953ff " , --Epic a335ee
[ 5 ] = " ff8000 " , --Legend
[ 6 ] = " e6cc80 " , --Artifact
[ 7 ] = " 00ccff " , --Heirloom
[ 8 ] = " 00ccff " ,
[ 9 ] = " ffffff " ,
} ;
for index , hex in pairs ( customQualityColors ) do
customQualityColors [ index ] = NarciAPI_ConvertHexColorToRGB ( hex , true ) ;
end
local function GetCustomQualityColor ( itemQuality )
if ( not itemQuality ) or ( not customQualityColors [ itemQuality ] ) then
itemQuality = 1 ;
end
return customQualityColors [ itemQuality ] [ 1 ] , customQualityColors [ itemQuality ] [ 2 ] , customQualityColors [ itemQuality ] [ 3 ] ;
end
NarciAPI.GetItemQualityColor = GetCustomQualityColor ;
local function GetCustomQualityColorByItemID ( itemID )
local itemQuality = C_Item.GetItemQualityByID ( itemID ) ;
return GetCustomQualityColor ( itemQuality ) ;
end
NarciAPI.GetItemQualityColorByItemID = GetCustomQualityColorByItemID ;
local function GetCustomQualityHexColor ( itemQuality )
if ( not itemQuality ) or ( not customQualityColors [ itemQuality ] ) then
itemQuality = 1 ;
end
return customQualityColors [ itemQuality ] [ 4 ]
end
NarciAPI.GetItemQualityHexColor = GetCustomQualityHexColor ;
NarciAPI.GetItemQualityColorTable = function ( )
local newTable = { } ;
for k , v in pairs ( customQualityColors ) do
newTable [ k ] = v ;
end
return newTable ;
end
local gemBorderTexture = {
filePrefix = " Interface/AddOns/Narcissus/Art/GemBorder/Dark/ " ,
[ 0 ] = " White " , --Empty
[ 1 ] = " Primary " , --Kraken's Eye
[ 2 ] = " Green " ,
[ 3 ] = " Primary " , --Prismatic
[ 4 ] = " Primary " , --Meta
[ 5 ] = " Orange " , --Orange
[ 6 ] = " Purple " ,
[ 7 ] = " Yellow " , --Yellow
[ 8 ] = " Blue " , --Blue
[ 9 ] = " Yellow " , --Empty
[ 10 ] = " Red " , --Red
[ 11 ] = " White " , --Artifact
[ 12 ] = " Crystallic " ,
} ;
local specialGemBoder = {
[ 153714 ] = 10 ,
[ 173125 ] = 10 ,
[ 153715 ] = 2 ,
[ 169220 ] = 2 ,
[ 173126 ] = 2 ,
[ 168636 ] = 1 ,
[ 168637 ] = 1 ,
[ 168638 ] = 1 ,
[ 153707 ] = 1 ,
[ 153708 ] = 1 ,
[ 153709 ] = 1 ,
[ 189723 ] = 12 ,
[ 189722 ] = 12 ,
[ 189732 ] = 12 ,
[ 189560 ] = 12 ,
[ 189763 ] = 12 ,
[ 189724 ] = 12 ,
[ 189725 ] = 12 ,
[ 189726 ] = 12 ,
[ 189762 ] = 12 ,
[ 189727 ] = 12 ,
[ 189728 ] = 12 ,
[ 189729 ] = 12 ,
[ 189730 ] = 12 ,
[ 189731 ] = 12 ,
[ 189764 ] = 12 ,
[ 189733 ] = 12 ,
[ 189734 ] = 12 ,
[ 189760 ] = 12 ,
[ 189761 ] = 12 ,
[ 189735 ] = 12 ,
} ;
local function GetGemBorderTexture ( itemSubClassID , itemID )
local index = ( itemID and specialGemBoder [ itemID ] ) or itemSubClassID or 0 ;
return gemBorderTexture.filePrefix .. gemBorderTexture [ index ] , index
end
local function SetBorderTheme ( theme )
--1.1.2 Override
theme = " Dark " ;
if theme == " Bright " then
gemBorderTexture.filePrefix = " Interface/AddOns/Narcissus/Art/GemBorder/Bright/ " ;
elseif theme == " Dark " then
gemBorderTexture.filePrefix = " Interface/AddOns/Narcissus/Art/GemBorder/Dark/ " ;
end
end
NarciAPI.SetBorderTheme = SetBorderTheme ;
NarciAPI.GetGemBorderTexture = GetGemBorderTexture ;
--------------------
------Item API------
--------------------
local function GetItemEnchantID ( itemLink )
if itemLink then
local _ , _ , _ , linkType , linkID , enchantID = strsplit ( " :|H " , itemLink ) ;
return tonumber ( enchantID ) or 0 ;
else
return 0
end
end
NarciAPI.GetItemEnchantID = GetItemEnchantID ;
local PrimaryStatsList = {
[ LE_UNIT_STAT_STRENGTH ] = NARCI_STAT_STRENGTH ,
[ LE_UNIT_STAT_AGILITY ] = NARCI_STAT_AGILITY ,
[ LE_UNIT_STAT_INTELLECT ] = NARCI_STAT_INTELLECT ,
} ;
local function NarciAPI_GetPrimaryStats ( )
--Return name and value
local currentSpec = GetSpecialization ( ) or 1 ;
local _ , _ , _ , _ , _ , primaryStat = GetSpecializationInfo ( currentSpec ) ;
primaryStat = primaryStat or 1 ;
local value = UnitStat ( " player " , primaryStat ) ;
local name = PrimaryStatsList [ primaryStat ] ;
return name , value ;
end
NarciAPI.GetPrimaryStats = NarciAPI_GetPrimaryStats ;
local GemInfo = Narci.GemData ;
local EnchantInfo = Narci.EnchantData ;
local DoesItemExist = C_Item.DoesItemExist ;
local GetCurrentItemLevel = C_Item.GetCurrentItemLevel ;
local GetItemLink = C_Item.GetItemLink
local GetItemStats = GetItemStats ;
local GetItemGem = GetItemGem ;
function NarciAPI_GetItemStats ( itemLocation )
local statsTable = { } ;
statsTable.gems = 0 ;
if not itemLocation or not DoesItemExist ( itemLocation ) then
statsTable.prim = 0 ;
statsTable.stamina = 0 ;
statsTable.crit = 0 ;
statsTable.haste = 0 ;
statsTable.mastery = 0 ;
statsTable.versatility = 0 ;
statsTable.corruption = 0 ;
statsTable.GemIcon = " " ;
statsTable.GemPos = " " ;
statsTable.EnchantPos = " " ;
statsTable.EnchantSpellID = nil ;
statsTable.ilvl = 0 ;
return statsTable ;
end
local ItemLevel = GetCurrentItemLevel ( itemLocation )
local itemLink = GetItemLink ( itemLocation )
local stats = GetItemStats ( itemLink ) or { } ;
local prim = stats [ " ITEM_MOD_AGILITY_SHORT " ] or stats [ " ITEM_MOD_STRENGTH_SHORT " ] or stats [ " ITEM_MOD_INTELLECT_SHORT " ] or 0 ;
local stamina = stats [ " ITEM_MOD_STAMINA_SHORT " ] or 0 ;
local crit = stats [ " ITEM_MOD_CRIT_RATING_SHORT " ] or 0 ;
local haste = stats [ " ITEM_MOD_HASTE_RATING_SHORT " ] or 0 ;
local mastery = stats [ " ITEM_MOD_MASTERY_RATING_SHORT " ] or 0 ;
local versatility = stats [ " ITEM_MOD_VERSATILITY " ] or 0 ;
local corruption = stats [ " ITEM_MOD_CORRUPTION " ] or 0 ;
statsTable.prim = prim ;
statsTable.stamina = stamina ;
statsTable.crit = crit ;
statsTable.haste = haste ;
statsTable.mastery = mastery ;
statsTable.versatility = versatility ;
statsTable.corruption = corruption ;
statsTable.ilvl = ItemLevel ;
--Calculate bonus from Gems and Enchants--
local gemIndex = 1 ; --BFA 1 gem for each item.
local gemName , gemLink = GetItemGem ( itemLink , gemIndex ) ;
if gemLink then
local gemID = GetItemInfoInstant ( gemLink ) ;
local _ , _ , _ , _ , GemIcon , _ , itemSubClassID = GetItemInfoInstant ( gemLink ) ;
statsTable.GemIcon = GemIcon
statsTable.gems = 1 ;
if GemInfo [ gemID ] then
local info = GemInfo [ gemID ]
statsTable.GemPos = GemInfo [ 1 ] ;
if info [ 1 ] == " crit " then
statsTable.crit = statsTable.crit + info [ 2 ] ;
elseif info [ 1 ] == " haste " then
statsTable.haste = statsTable.haste + info [ 2 ] ;
elseif info [ 1 ] == " mastery " then
statsTable.mastery = statsTable.mastery + info [ 2 ] ;
elseif info [ 1 ] == " versatility " then
statsTable.versatility = statsTable.versatility + info [ 2 ] ;
elseif info [ 1 ] == " AGI " or info [ 1 ] == " STR " or info [ 1 ] == " INT " then
statsTable.prim = statsTable.prim + info [ 2 ] ;
statsTable.GemPos = " prim " ;
end
end
end
local enchantID = GetItemEnchantID ( itemLink ) ;
if enchantID ~= 0 and EnchantInfo [ enchantID ] then
local data = EnchantInfo [ enchantID ]
statsTable.EnchantPos = data [ 1 ] ;
if data [ 1 ] == " crit " then
statsTable.crit = statsTable.crit + data [ 2 ] ;
elseif data [ 1 ] == " haste " then
statsTable.haste = statsTable.haste + data [ 2 ] ;
elseif data [ 1 ] == " mastery " then
statsTable.mastery = statsTable.mastery + data [ 2 ] ;
elseif data [ 1 ] == " versatility " then
statsTable.versatility = statsTable.versatility + data [ 2 ] ;
elseif data [ 1 ] == " AGI " or data [ 1 ] == " STR " or data [ 1 ] == " INT " then
statsTable.prim = statsTable.prim + data [ 2 ] ;
statsTable.EnchantPos = " prim " ;
elseif data [ 1 ] == " stamina " then
statsTable.stamina = statsTable.stamina + data [ 2 ] ;
statsTable.EnchantPos = " stamina " ;
end
statsTable.EnchantSpellID = data [ 3 ] ;
end
return statsTable ;
end
function NarciAPI_GetItemStatsFromSlot ( slotID )
local itemLocation = ItemLocation : CreateFromEquipmentSlot ( slotID ) ;
local itemLink = C_Item.GetItemLink ( itemLocation )
return GetItemStats ( itemLink ) ;
end
local function GetItemBagPosition ( itemID )
for bagID = 0 , ( NUM_BAG_SLOTS or 4 ) do
for slotID = 1 , GetContainerNumSlots ( bagID ) do
if ( GetContainerItemID ( bagID , slotID ) == itemID ) then
return bagID , slotID
end
end
end
end
NarciAPI.GetItemBagPosition = GetItemBagPosition ;
--------------------
---Formating API----
--------------------
local function NarciAPI_FormatLargeNumbers ( value )
value = tonumber ( value ) or 0 ;
local formatedNumber = " "
if value >= 1000 and value < 1000000 then
formatedNumber = strsub ( value , 1 , - 4 ) .. " , " .. strsub ( value , - 3 ) ;
elseif value >= 1000000 and value < 1000000000 then
formatedNumber = strsub ( value , 1 , - 7 ) .. " , " .. strsub ( value , - 6 , - 4 ) .. " , " .. strsub ( value , - 3 ) ;
else
formatedNumber = tostring ( value )
end
return formatedNumber
end
NarciAPI.FormatLargeNumbers = NarciAPI_FormatLargeNumbers ;
local RemoveTextBeforeColon ;
if TEXT_LOCALE == " zhCN " or TEXT_LOCALE == " zhTW " then
function RemoveTextBeforeColon ( text )
if find ( text , " : " ) then
return match ( text , " : (.+) " ) ;
elseif find ( text , " : " ) then
return match ( text , " :(.+) " ) ;
else
return text
end
end
else
function RemoveTextBeforeColon ( text )
if find ( text , " : " ) then
text = match ( text , " :%s*(.+) " ) ;
end
if find ( text , " - " ) then
text = match ( text , " - (.+) " ) ;
end
return text
--return string.gsub(text, "^.+[:-]%s*", ""); --May not working on Russian?
end
end
NarciAPI.RemoveTextBeforeColon = RemoveTextBeforeColon ;
--------------------
---Fade Frame API---
--------------------
local function SetFade_finishedFunc ( frame )
if frame.fadeInfo . mode == " OUT " then
frame : Hide ( ) ;
elseif frame.fadeInfo . mode == " IN " then
frame : Show ( ) ;
end
end
function NarciAPI_FadeFrame ( frame , time , mode )
if mode == " IN " then
UIFrameFadeIn ( frame , time , frame : GetAlpha ( ) , 1 ) ;
elseif mode == " OUT " then
if not frame : IsShown ( ) then
return ;
end
UIFrameFadeOut ( frame , time , frame : GetAlpha ( ) , 0 ) ;
elseif mode == " Forced_IN " then
UIFrameFadeIn ( frame , time , 0 , 1 ) ;
elseif mode == " Forced_OUT " then
UIFrameFadeOut ( frame , time , 1 , 0 ) ;
end
if not frame.fadeInfo then
return ;
end
frame.fadeInfo . finishedArg1 = frame ;
frame.fadeInfo . finishedFunc = SetFade_finishedFunc
end
------------------------------------------------------------------
--------------------
---UI Element API---
--------------------
NarciUIMixin = { } ;
function NarciUIMixin : Highlight ( state )
if state then
self.Border . Highlight : SetAlpha ( 1 ) ;
self.Border . Normal : SetAlpha ( 0 ) ;
else
self.Border . Highlight : SetAlpha ( 0 ) ;
self.Border . Normal : SetAlpha ( 1 ) ;
end
end
function NarciUIMixin : SetColor ( r , g , b )
if self.Color then
self.Color : SetColorTexture ( r / 255 , g / 255 , b / 255 ) ;
end
end
local SCREEN_WIDTH , SCREEN_HEIGHT = GetPhysicalScreenSize ( ) ; --Assume players don't change screen resolution (triggers DISPLAY_SIZE_CHANGED)
local function GetPixelForWidget ( widget , pixelSize )
local scale = widget : GetEffectiveScale ( ) ;
if pixelSize then
return pixelSize * ( 768 / SCREEN_HEIGHT ) / scale
else
return ( 768 / SCREEN_HEIGHT ) / scale
end
end
NarciAPI.GetPixelForWidget = GetPixelForWidget ;
local function GetPixelByScale ( scale , pixelSize )
if pixelSize then
return pixelSize * ( 768 / SCREEN_HEIGHT ) / scale
else
return ( 768 / SCREEN_HEIGHT ) / scale
end
end
NarciAPI.GetPixelByScale = GetPixelByScale ;
local function GetTexturePixelSize ( texture )
local scale = texture : GetEffectiveScale ( ) ;
local w , h = texture : GetSize ( ) ;
local pixel = ( 768 / SCREEN_HEIGHT ) / scale ;
return w / pixel , h / pixel
end
NarciAPI.GetTexturePixelSize = GetTexturePixelSize ;
function NarciAPI_OptimizeBorderThickness ( self )
if not self.HasOptimized then
local point , relativeTo , relativePoint , xOfs , yOfs = self : GetPoint ( )
local uiScale = self : GetEffectiveScale ( ) ;
local rate = ( 768 / SCREEN_HEIGHT ) / uiScale ;
local borderWeight = 2.0 ;
local weight = borderWeight * rate ;
local weight2 = weight * math.sqrt ( 2 ) ;
self.Border : SetPoint ( " TOPLEFT " , self , " TOPLEFT " , weight , - weight )
self.Border : SetPoint ( " BOTTOMRIGHT " , self , " BOTTOMRIGHT " , - weight , weight )
if self.ThumbBorder then
self.ThumbBorder : SetPoint ( " TOPLEFT " , self.VirtualThumb , - weight2 , weight2 )
self.ThumbBorder : SetPoint ( " BOTTOMRIGHT " , self.VirtualThumb , weight2 , - weight2 )
end
if self.Marks then
for i = 1 , # self.Marks do
self.Marks [ i ] : SetWidth ( weight ) ;
end
end
self.HasOptimized = true ;
end
end
function NarciAPI_SliderWithSteps_OnLoad ( self )
self.oldValue = - 1208 ;
self.Marks = { } ;
local width = self : GetWidth ( ) ;
local step = self : GetValueStep ( ) ;
local sliderMin , sliderMax = self : GetMinMaxValues ( ) ;
local range = sliderMax - sliderMin ;
local num_Gap = floor ( ( range / step ) + 0.5 ) ;
if num_Gap == 0 then return ; end ;
local tex ;
local markOffset = 5 ;
width = width - 2 * markOffset ;
local pixel = GetPixelForWidget ( self ) ;
for i = 1 , ( num_Gap + 1 ) do
tex = self : CreateTexture ( nil , " BACKGROUND " , nil , 1 ) ;
tex : SetSize ( 2 * pixel , 20 * pixel ) ;
tex : SetColorTexture ( 0.25 , 0.25 , 0.25 ) ;
tex : SetPoint ( " CENTER " , self , " LEFT " , markOffset + ( i - 1 ) * width / num_Gap , 0 ) ;
tinsert ( self.Marks , tex ) ;
end
--self.VirtualThumb:SetTexture("Interface/AddOns/Narcissus/Art/BasicShapes/Diamond", nil, nil, "TRILINEAR");
end
-----Smooth Scroll-----
local function SmoothScrollContainer_OnUpdate ( self , elapsed )
local value = self.scrollBar : GetValue ( ) ;
local step = max ( abs ( value - self.endValue ) * ( self.speedRatio ) * ( elapsed * 60 ) , self.minOffset ) ; --if the step (Δy) is too small, the fontstring will jitter. --Consider elapsed -- scroll duration should be constant regardless of FPS
local remainedStep ;
if ( self.delta == 1 ) then
--Up
remainedStep = min ( self.endValue - value , 0 ) ;
if - remainedStep <= ( self.minOffset ) then
self : Hide ( ) ;
self.scrollBar : SetValue ( min ( self.maxVal , self.endValue ) ) ;
if self.onScrollFinishedFunc then
self.onScrollFinishedFunc ( ) ;
end
else
self.scrollBar : SetValue ( max ( 0 , value - step ) ) ;
end
else
remainedStep = max ( self.endValue - value , 0 ) ;
if remainedStep <= ( self.minOffset ) then
self : Hide ( ) ;
self.scrollBar : SetValue ( min ( self.maxVal , self.endValue ) ) ;
if self.onScrollFinishedFunc then
self.onScrollFinishedFunc ( ) ;
end
else
self.scrollBar : SetValue ( min ( self.maxVal , value + step ) ) ;
end
end
end
local function NarciAPI_SmoothScroll_OnMouseWheel ( self , delta , stepSize )
if ( not self.scrollBar : IsVisible ( ) ) then
if self.parentScrollFunc then
self.parentScrollFunc ( delta ) ;
else
return ;
end
end
local ScrollContainer = self.SmoothScrollContainer ;
stepSize = stepSize or self.stepSize or self.buttonHeight ;
ScrollContainer.stepSize = stepSize ;
ScrollContainer.maxVal = self.range ;
--self.scrollBar:SetValueStep(0.01);
ScrollContainer.delta = delta ;
local current = self.scrollBar : GetValue ( ) ;
if not ( ( current <= 0.1 and delta > 0 ) or ( current >= self.range - 0.1 and delta < 0 ) ) then
ScrollContainer : Show ( )
else
return ;
end
local deltaRatio = ScrollContainer.deltaRatio or 1 ;
if IsShiftKeyDown ( ) then
deltaRatio = 2 * deltaRatio ;
end
local endValue = floor ( ( 100 * min ( max ( 0 , ScrollContainer.endValue - delta * deltaRatio * self.buttonHeight ) , self.range ) + 0.5 ) / 100 ) ;
ScrollContainer.endValue = endValue ;
if self.positionFunc then
local isTop = endValue <= 0.1 ;
local isBottom = endValue >= self.range - 1 ;
self.positionFunc ( endValue , delta , self.scrollBar , isTop , isBottom ) ;
end
end
local function SetScrollRange ( scrollFrame , range )
range = max ( range , 0 ) ;
scrollFrame.scrollBar : SetMinMaxValues ( 0 , range ) ;
scrollFrame.scrollBar : SetShown ( range ~= 0 ) ;
scrollFrame.range = range ;
end
function NarciAPI_SmoothScroll_Initialization ( scrollFrame , updatedList , updateFunc , deltaRatio , speedRatio , minOffset , positionFunc , onScrollFinishedFunc )
if updateFunc then
scrollFrame.update = updateFunc ;
end
if positionFunc then
scrollFrame.positionFunc = positionFunc ;
end
if updatedList then
scrollFrame.updatedList = updatedList ;
end
local parentName = scrollFrame : GetName ( ) ;
local frameName = parentName and ( parentName .. " SmoothScrollContainer " ) or nil ;
local SmoothScrollContainer = CreateFrame ( " Frame " , frameName , scrollFrame ) ;
SmoothScrollContainer : Hide ( ) ;
--local scale = match(GetCVar( "gxWindowedResolution" ), "%d+x(%d+)" );
local uiScale = scrollFrame : GetEffectiveScale ( ) ;
local pixel = ( 768 / SCREEN_HEIGHT ) / uiScale ;
local scrollBar = scrollFrame.scrollBar ;
scrollBar : SetValue ( 0 ) ;
scrollBar : SetValueStep ( 0.001 ) ;
SmoothScrollContainer.stepSize = 0 ;
SmoothScrollContainer.delta = 0 ;
SmoothScrollContainer.animationDuration = 0 ;
SmoothScrollContainer.endValue = 0 ;
SmoothScrollContainer.maxVal = 0 ;
SmoothScrollContainer.deltaRatio = deltaRatio or 1 ;
SmoothScrollContainer.speedRatio = speedRatio or 0.5 ;
SmoothScrollContainer.minOffset = minOffset or pixel ;
SmoothScrollContainer.scrollBar = scrollFrame.scrollBar ;
SmoothScrollContainer : SetScript ( " OnUpdate " , SmoothScrollContainer_OnUpdate ) ;
SmoothScrollContainer : SetScript ( " OnShow " , function ( self )
self.endValue = self : GetParent ( ) . scrollBar : GetValue ( ) ;
end ) ;
SmoothScrollContainer : SetScript ( " OnHide " , function ( self )
self : Hide ( ) ;
end ) ;
scrollFrame.SmoothScrollContainer = SmoothScrollContainer ;
scrollFrame : SetScript ( " OnMouseWheel " , NarciAPI_SmoothScroll_OnMouseWheel ) ; --a position-related function
if onScrollFinishedFunc then
SmoothScrollContainer.onScrollFinishedFunc = onScrollFinishedFunc ;
end
scrollFrame.SetScrollRange = SetScrollRange ;
end
function NarciAPI_ApplySmoothScrollToScrollFrame ( scrollFrame , deltaRatio , speedRatio , positionFunc , buttonHeight , range , parentScrollFunc , onScrollFinishedFunc )
scrollFrame.buttonHeight = buttonHeight or floor ( scrollFrame : GetHeight ( ) + 0.5 ) ;
scrollFrame.range = range or 0 ;
scrollFrame.scrollBar : SetMinMaxValues ( 0 , range or 0 )
scrollFrame.scrollBar : SetScript ( " OnValueChanged " , function ( self , value )
scrollFrame : SetVerticalScroll ( value ) ;
if self.onValueChangedFunc then
self.onValueChangedFunc ( value ) ;
end
end )
NarciAPI_SmoothScroll_Initialization ( scrollFrame , nil , nil , deltaRatio , speedRatio , nil , positionFunc , onScrollFinishedFunc ) ;
scrollFrame.parentScrollFunc = parentScrollFunc ;
end
function NarciAPI_ApplySmoothScrollToBlizzardUI ( scrollFrame , deltaRatio , speedRatio , positionFunc )
NarciAPI_SmoothScroll_Initialization ( scrollFrame , nil , nil , deltaRatio , speedRatio , nil , positionFunc ) ;
end
-----Create A List of Button----
--[[
function NarciAPI_BuildButtonList ( self , buttonTemplate , buttonNameTable , initialOffsetX , initialOffsetY , initialPoint , initialRelative , offsetX , offsetY , point , relativePoint )
local button , buttonHeight , buttons , numButtons ;
local parentName = self : GetName ( ) ;
local buttonName = parentName and ( parentName .. " Button " ) or nil ;
initialPoint = initialPoint or " TOPLEFT " ;
initialRelative = initialRelative or " TOPLEFT " ;
initialOffsetX = initialOffsetX or 0 ;
initialOffsetY = initialOffsetY or 0 ;
point = point or " TOPLEFT " ;
relativePoint = relativePoint or " BOTTOMLEFT " ;
offsetX = offsetX or 0 ;
offsetY = offsetY or 0 ;
if ( self.buttons ) then
buttons = self.buttons ;
buttonHeight = buttons [ 1 ] : GetHeight ( ) ;
else
button = CreateFrame ( " BUTTON " , buttonName and ( buttonName .. 1 ) or nil , self , buttonTemplate ) ;
buttonHeight = button : GetHeight ( ) ;
button : SetPoint ( initialPoint , self , initialRelative , initialOffsetX , initialOffsetY ) ;
button : SetID ( 0 ) ;
buttons = { }
button.Name : SetText ( buttonNameTable [ 1 ] )
tinsert ( buttons , button ) ;
end
local numButtons = # buttonNameTable ;
for i = 2 , numButtons do
button = CreateFrame ( " BUTTON " , buttonName and ( buttonName .. i ) or nil , self , buttonTemplate ) ;
button : SetPoint ( point , buttons [ i - 1 ] , relativePoint , offsetX , offsetY ) ;
button : SetID ( i - 1 ) ;
button.Name : SetText ( buttonNameTable [ i ] )
tinsert ( buttons , button ) ;
end
self.buttons = buttons ;
end
--]]
-----Language Adaptor-----
local function LanguageDetector ( str )
local len = string.len ( str )
local i = 1
while i <= len do
local c = string.byte ( str , i )
local shift = 1
if ( c > 0 and c <= 127 ) then
shift = 1
elseif c == 195 then
shift = 2 --Latin/Greek
elseif ( c >= 208 and c <= 211 ) then
shift = 2
return " RU " --RU included
elseif ( c >= 224 and c <= 227 ) then
shift = 3 --JP
return " JP "
elseif ( c >= 228 and c <= 233 ) then
shift = 3 --CN
return " CN "
elseif ( c >= 234 and c <= 237 ) then
shift = 3 --KR
return " KR "
elseif ( c >= 240 and c <= 244 ) then
shift = 4 --Unknown invalid
end
i = i + shift
end
return " RM "
end
local function GetFirstLetterLanguage ( str )
local c = string.byte ( str , 1 ) ;
if ( c > 0 and c <= 127 ) then
return " RM "
elseif c == 195 then
return " RM " --Latin/Greek
elseif ( c >= 208 and c <= 211 ) then
return " RU "
elseif ( c >= 224 and c <= 227 ) then
return " JP "
elseif ( c >= 228 and c <= 233 ) then
return " CN "
elseif ( c >= 234 and c <= 237 ) then
return " KR "
elseif ( c >= 240 and c <= 244 ) then
return " CN " --Unknown invalid
end
end
NarciAPI.LanguageDetector = LanguageDetector ;
--[[
function LDTest ( string )
local str = string
local lenInByte = # str
for i = 1 , lenInByte do
local char = strsub ( str , i , i )
local curByte = string.byte ( str , i )
print ( char .. " " .. curByte )
end
return " roman "
end
local Eng = " abcdefghijklmnopqrstuvwxyz " --abcdefghijklmnopqrstuvwxyz Z~90 z~122 1-1
local DE = " äöüß " --195 1-2
local CN = " 乀氺 " --228 229 230 233 HEX E4-E9 Hexadecimal UTF-8 CJK
local KR = " 제 " --237 236 235 234 1-3 EB-ED
local RU = " ѱӧ " --D0400-D04C0 208 209 210 211 1-2
local FR = " ÀÃÇÊÉÕàãçêõáéíóúà " --1-2 195 C3 -PR
local JP = " ひらがな " --1-3 227 E3 Kana
--LDTest("繁體繁体")
--local language = LanguageDetector("繁體中文")
--print("Str is: "..language)
--]]
local PlayerNameFont = {
[ " CN " ] = " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " ,
[ " RM " ] = " Interface \\ AddOns \\ Narcissus \\ Font \\ SemplicitaPro-Semibold.otf " ,
[ " RU " ] = " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSans-Medium.ttf " ,
[ " KR " ] = " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " ,
[ " JP " ] = " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " ,
}
local EditBoxFont = {
[ " CN " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 8 } ,
[ " RM " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ SourceSansPro-Semibold.ttf " , 9 } ,
[ " RU " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSans-Medium.ttf " , 8 } ,
[ " KR " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 8 } ,
[ " JP " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 8 } ,
}
local NormalFont12 = {
[ " CN " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 11 } ,
[ " RM " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ SourceSansPro-Semibold.ttf " , 12 } ,
[ " RU " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSans-Medium.ttf " , 11 } ,
[ " KR " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 11 } ,
[ " JP " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 11 } ,
}
local ActorNameFont = {
[ " CN " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 8 } ,
[ " RM " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ SourceSansPro-Semibold.ttf " , 9 } ,
[ " RU " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSans-Medium.ttf " , 8 } ,
[ " KR " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 8 } ,
[ " JP " ] = { " Interface \\ AddOns \\ Narcissus \\ Font \\ NotoSansCJKsc-Medium.otf " , 8 } ,
}
local function SmartSetActorName ( fontstring , text )
--Automatically apply different font based on given text languange. Change text color after this step.
if not fontstring then return ; end ;
fontstring : SetText ( text ) ;
local language = LanguageDetector ( text ) ;
if language and ActorNameFont [ language ] then
fontstring : SetFont ( ActorNameFont [ language ] [ 1 ] , ActorNameFont [ language ] [ 2 ] , " " ) ;
end
end
local function SmartFontType ( self , fontTable )
local str = self : GetText ( ) ;
local language = LanguageDetector ( str ) ;
--print(str.." Language is: "..Language);
local height = self : GetHeight ( ) ;
if language and fontTable [ language ] then
self : SetFont ( fontTable [ language ] , height , " " ) ;
end
end
local function SmartEditBoxFont ( self , extraHeight )
local str = self : GetText ( ) ;
local language = LanguageDetector ( str ) ;
if language and EditBoxFont [ language ] then
local height = extraHeight or 0 ;
self : SetFont ( EditBoxFont [ language ] [ 1 ] , EditBoxFont [ language ] [ 2 ] + height , " " ) ;
end
end
local function NarciAPI_SmartFontType ( fontString )
SmartFontType ( fontString , PlayerNameFont ) ;
end
local function SmartSetName ( fontString , str )
local language = LanguageDetector ( str ) ;
if language and NormalFont12 [ language ] then
fontString : SetFont ( NormalFont12 [ language ] [ 1 ] , NormalFont12 [ language ] [ 2 ] , " " ) ;
end
fontString : SetText ( str ) ;
end
NarciAPI.SmartSetActorName = SmartSetActorName ;
NarciAPI.SmartFontType = NarciAPI_SmartFontType ;
NarciAPI.SmartSetName = SmartSetName ;
function NarciAPI_SmartEditBoxType ( self , isUserInput , extraHeight )
SmartEditBoxFont ( self , extraHeight ) ;
end
--[[
function NarciAPI_EditBox_OnLanguageChanged ( self , language )
SmartEditBoxFont ( self ) ;
end
--]]
-----Filter Shared Functions-----
function NarciAPI_LetterboxAnimation ( command )
local frame = Narci_FullScreenMask ;
frame : StopAnimating ( ) ;
if command == " IN " then
frame : Show ( ) ;
frame.BottomMask . animIn : Play ( ) ;
frame.TopMask . animIn : Play ( ) ;
elseif command == " OUT " then
frame.BottomMask . animOut : Play ( ) ;
frame.TopMask . animOut : Play ( ) ;
else
if NarcissusDB.LetterboxEffect then
frame : Show ( ) ;
frame.BottomMask . animIn : Play ( ) ;
frame.TopMask . animIn : Play ( ) ;
else
frame : Hide ( ) ;
end
end
end
-----Format Normalization-----
local function SplitTooltipByLineBreak ( str )
local str1 , _ , str2 = strsplit ( " \n " , str ) ;
return str1 or " " , str2 or " " ;
end
NARCI_CRIT_TOOLTIP , NARCI_CRIT_TOOLTIP_FORMAT = SplitTooltipByLineBreak ( CR_CRIT_TOOLTIP ) ;
_ , NARCI_HASTE_TOOLTIP_FORMAT = SplitTooltipByLineBreak ( STAT_HASTE_BASE_TOOLTIP ) ;
NARCI_VERSATILITY_TOOLTIP_FORMAT_1 , NARCI_VERSATILITY_TOOLTIP_FORMAT_2 = SplitTooltipByLineBreak ( CR_VERSATILITY_TOOLTIP ) ;
-----Delayed Tooltip-----
local DelayedTP = CreateFrame ( " Frame " ) ;
DelayedTP : Hide ( ) ;
DelayedTP : SetScript ( " OnShow " , function ( self )
self.t = 0 ; --Total time after ShowDelayedTooltip gets called
--self.ScanTime = 0; --Cursor scanning time
--self.CursorX, self.CursorY = GetCursorPosition(); --Cursor position
end )
DelayedTP : SetScript ( " OnHide " , function ( self )
self.t = 0 ;
--self.ScanTime = 0;
end )
DelayedTP : SetScript ( " OnUpdate " , function ( self , elapsed )
self.t = self.t + elapsed ;
--self.ScanTime = self.ScanTime + elapsed;
if self.t >= 0.6 then
if self.focus and self.focus == GetMouseFocus ( ) then
NarciGameTooltip : ClearAllPoints ( ) ;
NarciGameTooltip : SetPoint ( self.point , self.relativeTo , self.relativePoint , self.ofsx , self.ofsy ) ;
FadeFrame ( NarciGameTooltip , 0.15 , 1 , 0 ) ;
self.focus = nil ;
end
self : Hide ( ) ;
end
end )
function NarciAPI_ShowDelayedTooltip ( point , relativeTo , relativePoint , ofsx , ofsy )
local tp = DelayedTP ;
tp : Hide ( ) ;
if point then
tp.focus = GetMouseFocus ( ) ;
tp.point , tp.relativeTo , tp.relativePoint , tp.ofsx , tp.ofsy = point , relativeTo , relativePoint , ofsx , ofsy ;
tp : Show ( ) ;
else
tp.focus = nil ;
FadeFrame ( NarciGameTooltip , 0 , 0 ) ;
end
end
-----Run Delayed Function-----
local DelayedFunc = CreateFrame ( " Frame " ) ;
DelayedFunc : Hide ( ) ;
DelayedFunc.delay = 0 ;
DelayedFunc.t = 0 ;
DelayedFunc : SetScript ( " OnHide " , function ( self )
self.focus = nil ;
self.t = 0 ;
end )
DelayedFunc : SetScript ( " OnUpdate " , function ( self , elapsed )
self.t = self.t + elapsed ;
if self.t >= self.delay then
if self.focus == GetMouseFocus ( ) then
self.func ( ) ;
end
self : Hide ( ) ;
end
end )
function NarciAPI_RunDelayedFunction ( frame , delay , func )
DelayedFunc : Hide ( ) ;
if func and type ( func ) == " function " then
delay = delay or 0 ;
DelayedFunc.focus = frame ;
DelayedFunc.delay = delay ;
DelayedFunc.func = func ;
DelayedFunc : Show ( ) ;
end
end
-----Alert Frame-----
if BackdropTemplateMixin then
NarciAlertFrameMixin = CreateFromMixins ( BackdropTemplateMixin ) ;
else
NarciAlertFrameMixin = { } ;
end
function NarciAlertFrameMixin : AddShakeAnimation ( frame )
if frame.animError then return ; end ;
local ag = frame : CreateAnimationGroup ( ) ;
local a1 = ag : CreateAnimation ( " Translation " ) ;
a1 : SetOrder ( 1 ) ;
a1 : SetOffset ( 4 , 0 ) ;
a1 : SetDuration ( 0.05 ) ;
local a2 = ag : CreateAnimation ( " Translation " ) ;
a2 : SetOrder ( 2 ) ;
a2 : SetOffset ( - 8 , 0 ) ;
a2 : SetDuration ( 0.1 ) ;
local a3 = ag : CreateAnimation ( " Translation " ) ;
a3 : SetOrder ( 3 ) ;
a3 : SetOffset ( 8 , 0 ) ;
a3 : SetDuration ( 0.1 ) ;
local a4 = ag : CreateAnimation ( " Translation " ) ;
a4 : SetOrder ( 4 ) ;
a4 : SetOffset ( - 4 , 0 ) ;
a4 : SetDuration ( 0.05 ) ;
ag : SetScript ( " OnPlay " , function ( )
PlaySound ( 138528 ) ; --Mechagon_HK8_Lockon
end ) ;
frame.animError = ag ;
end
function NarciAlertFrameMixin : SetAnchor ( frame , offsetY , AddErrorAnimation )
if frame.RegisterErrorEvent then
frame : RegisterErrorEvent ( ) ;
After ( 0.5 , function ( )
frame : UnregisterErrorEvent ( ) ;
end )
else
frame : RegisterEvent ( " UI_ERROR_MESSAGE " ) ;
After ( 0.5 , function ( )
frame : UnregisterEvent ( " UI_ERROR_MESSAGE " ) ;
end )
end
self : Hide ( ) ;
self : ClearAllPoints ( ) ;
self : SetScale ( Narci_Character : GetEffectiveScale ( ) )
local y = offsetY or - 12 ;
self : SetPoint ( " BOTTOM " , frame , " TOP " , 0 , y ) ;
self : SetFrameLevel ( 50 )
self.anchor = frame ;
if AddErrorAnimation then
self : AddShakeAnimation ( frame ) ;
end
end
function NarciAlertFrameMixin : AddMessage ( msg , UseErrorAnimation )
self.Text : SetText ( msg ) ;
self : SetHeight ( self.Background : GetHeight ( ) ) ;
FadeFrame ( self , 0.2 , 1 ) ;
local anchorFrame = self.anchor ;
if anchorFrame then
if anchorFrame.animError and UseErrorAnimation then
anchorFrame.animError : Play ( ) ;
end
anchorFrame : UnregisterEvent ( " UI_ERROR_MESSAGE " ) ;
end
end
------------------------
--Filled Bar Animation--
------------------------
--Corruption Bar
--[[
local cos = math.cos ;
local pi = math.pi ;
local function inOutSine ( t , b , c , d )
return - c / 2 * ( cos ( pi * t / d ) - 1 ) + b
end
local FluidAnim = CreateFrame ( " Frame " ) ;
FluidAnim : Hide ( ) ;
FluidAnim.d = 0.5 ;
FluidAnim.d1 = 0.25 ;
FluidAnim.d2 = 0.5 ;
local function FluidLevel ( self , elapsed )
self.t = self.t + elapsed ;
local height = inOutSine ( self.t , self.startHeight , self.endHeight - self.startHeight , self.d ) ;
if self.t >= self.d then
height = self.endHeight ;
self : Hide ( ) ;
end
self.Fluid : SetHeight ( height ) ;
end
local function FluidUp ( self , elapsed )
self.t = self.t + elapsed ;
local height ;
if self.t <= self.d1 then
height = inOutSine ( self.t , self.startHeight , 84 - self.startHeight , self.d1 ) ;
elseif self.t < self.d3 then
if not self.colorChanged then
self.colorChanged = true ;
self.Fluid : SetColorTexture ( self.r , self.g , self.b ) ;
end
height = inOutSine ( self.t - self.d1 , 0.01 , self.endHeight , self.d2 ) ;
else
height = self.endHeight ;
self : Hide ( ) ;
end
self.Fluid : SetHeight ( height ) ;
end
local function FluidDown ( self , elapsed )
self.t = self.t + elapsed ;
local height ;
if self.t <= self.d1 then
height = inOutSine ( self.t , self.startHeight , 0.01 - self.startHeight , self.d1 ) ;
elseif self.t < self.d3 then
if not self.colorChanged then
self.colorChanged = true ;
self.Fluid : SetColorTexture ( self.r , self.g , self.b ) ;
end
height = inOutSine ( self.t - self.d1 , 84 , self.endHeight - 84 , self.d2 ) ;
else
height = self.endHeight ;
self : Hide ( ) ;
end
self.Fluid : SetHeight ( height ) ;
end
FluidAnim : SetScript ( " OnShow " , function ( self )
self.t = 0 ;
self.colorChanged = false ;
end ) ;
function NarciAPI_SmoothFluid ( bar , newHeight , newLevel , r , g , b )
local FluidAnim = FluidAnim ;
FluidAnim : Hide ( ) ;
FluidAnim.endHeight = newHeight ;
FluidAnim.Fluid = bar ;
FluidAnim.r , FluidAnim.g , FluidAnim.b = r , g , b ;
local oldLevel = FluidAnim.oldCorruptionLevel or newLevel ;
FluidAnim.oldCorruptionLevel = newLevel ;
local t1 , t2 ;
local h = FluidAnim.Fluid : GetHeight ( ) ;
FluidAnim.startHeight = h ;
if newLevel == oldLevel then
FluidAnim : SetScript ( " OnUpdate " , FluidLevel ) ;
FluidAnim.d = max ( abs ( h - FluidAnim.endHeight ) / 84 , 0.35 ) ;
bar : SetColorTexture ( r , g , b ) ;
elseif newLevel < oldLevel then
FluidAnim : SetScript ( " OnUpdate " , FluidDown ) ;
t1 = math.max ( h / 84 , 0 ) ;
t2 = math.max ( ( 84 - FluidAnim.endHeight ) / 84 , 0.4 ) ;
FluidAnim.d1 = t1
FluidAnim.d2 = t2
FluidAnim.d3 = t1 + t2 ;
else
FluidAnim : SetScript ( " OnUpdate " , FluidUp ) ;
t1 = math.max ( ( 84 - h ) / 84 , 0 ) ;
t2 = math.max ( FluidAnim.endHeight / 84 , 0.4 ) ;
FluidAnim.d1 = t1
FluidAnim.d2 = t2
FluidAnim.d3 = t1 + t2 ;
end
After ( 0 , function ( )
FluidAnim : Show ( ) ;
end )
return t1
end
local EyeballTexture = " Interface \\ AddOns \\ Narcissus \\ ART \\ Widgets \\ CorruptionSystem \\ Eyeball-Orange " ;
local CorruptionColor = " |cfff57f20 " ;
local FluidColors = { 0.847 , 0.349 , 0.145 } ;
function NarciAPI_GetEyeballColor ( )
return EyeballTexture , CorruptionColor , FluidColors [ 1 ] , FluidColors [ 2 ] , FluidColors [ 3 ] ;
end
function NarciAPI_SetEyeballColor ( index )
if index == 4 then
EyeballTexture = " Interface \\ AddOns \\ Narcissus \\ ART \\ Widgets \\ CorruptionSystem \\ Eyeball-Blue " ;
CorruptionColor = " |cff83c7e7 " ;
FluidColors = { 0.596 , 0.73 , 0.902 } ;
elseif index == 2 then
EyeballTexture = " Interface \\ AddOns \\ Narcissus \\ ART \\ Widgets \\ CorruptionSystem \\ Eyeball-Purple " ;
CorruptionColor = " |cfff019ff " ;
FluidColors = { 0.87 , 0.106 , 0.949 } ;
elseif index == 3 then
EyeballTexture = " Interface \\ AddOns \\ Narcissus \\ ART \\ Widgets \\ CorruptionSystem \\ Eyeball-Green " ;
CorruptionColor = " |cff8cdacd " ;
FluidColors = { 0.56 , 0.855 , 0.757 } ;
else
index = 1 ;
EyeballTexture = " Interface \\ AddOns \\ Narcissus \\ ART \\ Widgets \\ CorruptionSystem \\ Eyeball-Orange " ;
CorruptionColor = " |cfff57f20 " ;
FluidColors = { 0.847 , 0.349 , 0.145 } ;
end
NarcissusDB.EyeColor = index ;
local Preview = Narci_EyeColorPreview ;
local ColorButtons = Preview : GetParent ( ) . ColorButtons ;
Preview : SetTexCoord ( 0.25 * ( index - 1 ) , 0.25 * index , 0 , 1 ) ;
for i = 1 , # ColorButtons do
--ColorButtons[i]Highlight(false);
end
--ColorButtons[index]:Highlight(true);
Narci : SetItemLevel ( ) ;
end
--]]
--------------------
--UI 3D Animation---
--------------------
Narci.AnimSequenceInfo =
{ [ " Controller " ] = {
[ " TotalFrames " ] = 30 ,
[ " cX " ] = 0.205078125 ,
[ " cY " ] = 0.1171875 ,
[ " Column " ] = 4 ,
[ " Row " ] = 8 ,
} ,
[ " Heart " ] = {
[ " TotalFrames " ] = 28 ,
[ " cX " ] = 0.25 ,
[ " cY " ] = 0.140625 ,
[ " Column " ] = 4 ,
[ " Row " ] = 7 ,
} ,
[ " ActorPanel " ] = {
[ " TotalFrames " ] = 26 ,
[ " cX " ] = 0.4296875 ,
[ " cY " ] = 0.056640625 ,
[ " Column " ] = 2 ,
[ " Row " ] = 17 ,
} ,
}
function NarciAPI_PlayAnimationSequence ( index , SequenceInfo , Texture )
local Frames = SequenceInfo [ " TotalFrames " ] ;
local cX , cY = SequenceInfo [ " cX " ] , SequenceInfo [ " cY " ] ;
local col , row = SequenceInfo [ " Column " ] , SequenceInfo [ " Row " ]
if index > Frames or index < 1 then
return false ;
end
local n = math.modf ( ( index - 1 ) / row ) + 1 ;
local m = index % row
if m == 0 then
m = row ;
end
local left , right = ( n - 1 ) * cX , n * cX ;
local top , bottom = ( m - 1 ) * cY , m * cY ;
Texture : SetTexCoord ( left , right , top , bottom ) ;
Texture : SetAlpha ( 1 ) ;
Texture : Show ( ) ;
return true ;
end
--------------------
-----Play Voice-----
--------------------
local ERROR_NOTARGET , ALERT_INCOMING ;
do
local _ , _ , raceID = UnitRace ( " player " ) ;
local genderID = UnitSex ( " player " ) or 2 ;
raceID = raceID or 1 ;
genderID = genderID - 1 ; --(2→1) Male (3→2) Female
if raceID == 25 or raceID == 26 then
--Pandaren faction
raceID = 24 ;
elseif raceID == 52 or raceID == 70 then
raceID = 52 ;
end
if raceID == 37 then --Mechagnome
IGNORED_MOG_SLOT [ 8 ] = true ; --feet
IGNORED_MOG_SLOT [ 9 ] = true ; --wrist
IGNORED_MOG_SLOT [ 10 ] = true ; --hands
elseif raceID == 52 then --Dracthyr
end
local VOICE_BY_RACE = {
--[raceID] = { [gender] = {Error_NoTarget, ALERT_INCOMING} }
[ 1 ] = { [ 1 ] = { 1906 , 2669 , } ,
[ 2 ] = { 2030 , 2681 , } } , --1 Human
[ 2 ] = { [ 1 ] = { 2317 , 2693 , } ,
[ 2 ] = { 2372 , 2705 , } } , --2 Orc
[ 3 ] = { [ 1 ] = { 1614 , 2717 , } ,
[ 2 ] = { 1684 , 2729 , } } , --3 Dwarf
[ 4 ] = { [ 1 ] = { 56231 , 56311 , } ,
[ 2 ] = { 56096 , 56174 , } } , --4 NE
[ 5 ] = { [ 1 ] = { 2085 , 2765 , } ,
[ 2 ] = { 2205 , 2777 , } } , --5 UD
[ 6 ] = { [ 1 ] = { 2459 , 2789 , } ,
[ 2 ] = { 2458 , 2802 , } } , --6 Tauren
[ 7 ] = { [ 1 ] = { 1741 , 2827 , } ,
[ 2 ] = { 1796 , 2839 , } } , --7 Gnome
[ 8 ] = { [ 1 ] = { 1851 , 2851 , } ,
[ 2 ] = { 1961 , 2863 , } } , --8 Troll
[ 9 ] = { [ 1 ] = { 19109 , 19137 , } ,
[ 2 ] = { 19218 , 19246 } } , --9 Goblin
[ 10 ] = { [ 1 ] = { 9597 , 9664 , } ,
[ 2 ] = { 9598 , 9624 , } } , --10 BloodElf
[ 11 ] = { [ 1 ] = { 9463 , 9714 , } ,
[ 2 ] = { 9514 , 9689 , } } , --11 Goat
[ 22 ] = { [ 1 ] = { 18991 , 19346 , } ,
[ 2 ] = { 18719 , 19516 , } } , --22 Worgen
[ 24 ] = { [ 1 ] = { 28846 , 28924 , } ,
[ 2 ] = { 29899 , 29812 , } } , --24 Pandaren
[ 27 ] = { [ 1 ] = { 96356 , 96383 , } ,
[ 2 ] = { 96288 , 96315 , } } , --27 Nightborne
[ 28 ] = { [ 1 ] = { 95931 , 95844 , } ,
[ 2 ] = { 95510 , 95543 , } } , --28 Highmountain Tauren
[ 29 ] = { [ 1 ] = { 95636 , 95665 , } ,
[ 2 ] = { 95806 , 95857 , } } , --29 Void Elf
[ 30 ] = { [ 1 ] = { 96220 , 96247 , } ,
[ 2 ] = { 96152 , 96179 , } } , --30 Light-forged
[ 31 ] = { [ 1 ] = { 127289 , 1273128 , } ,
[ 2 ] = { 126915 , 126944 , } } , --31 Zandalari
[ 32 ] = { [ 1 ] = { 127102 , 127131 , } ,
[ 2 ] = { 127008 , 127037 , } } , --32 Kul'Tiran
[ 34 ] = { [ 1 ] = { 101933 , 101962 , } ,
[ 2 ] = { 101859 , 101888 , } } , --36 Dark Iron Dwarf
[ 35 ] = { [ 1 ] = { 144073 , 144111 , } ,
[ 2 ] = { 143981 , 144019 , } } , --35 Vulpera
[ 36 ] = { [ 1 ] = { 110370 , 110399 , } ,
[ 2 ] = { 110295 , 110324 , } } , --36 Mag'har
[ 37 ] = { [ 1 ] = { 143863 , 143892 , } ,
[ 2 ] = { 144223 , 144275 , } } , --37 Mechagnome!!!!
[ 52 ] = { [ 1 ] = { 212644 , 212598 , } ,
[ 2 ] = { 212644 , 212688 , } } , --52 Dracthyr
} ;
if VOICE_BY_RACE [ raceID ] then
ERROR_NOTARGET = VOICE_BY_RACE [ raceID ] [ genderID ] [ 1 ] ;
ALERT_INCOMING = VOICE_BY_RACE [ raceID ] [ genderID ] [ 2 ] ;
end
ERROR_NOTARGET = ERROR_NOTARGET or 2030 ;
ALERT_INCOMING = ALERT_INCOMING or 2669 ;
wipe ( VOICE_BY_RACE ) ;
end
function Narci : PlayVoice ( name )
if name == " ERROR " then
PlaySound ( ERROR_NOTARGET , " Dialog " ) ;
elseif name == " DANGER " then
PlaySound ( ALERT_INCOMING , " Dialog " ) ;
end
end
--Time
--C_DateAndTime.GetCurrentCalendarTime
local ActorIDByRace = {
--local GenderID = UnitSex(unit); 2 Male 3 Female
--[raceID] = {male actorID, female actorID, bustOffsetZ_M, bustOffsetZ_F},
[ 2 ] = { 483 , 483 } , -- Orc bow
[ 3 ] = { 471 , nil } , -- Dwarf
[ 5 ] = { 472 , 487 } , -- UD 0.9585 seems small
[ 6 ] = { 449 , 484 } , -- Tauren
[ 7 ] = { 450 , 450 } , -- Gnome
[ 8 ] = { 485 , 486 } , -- Troll 0.9414 too high?
[ 9 ] = { 476 , 477 } , -- Goblin
[ 11 ] = { 475 , 501 } , -- Goat
[ 22 ] = { 474 , 500 } , -- Worgen
[ 24 ] = { 473 , 473 } , -- Pandaren
[ 28 ] = { 490 , 491 } , -- Highmountain Tauren
[ 30 ] = { 488 , 489 } , -- Lightforged Draenei
[ 31 ] = { 492 , 492 } , -- Zandalari
[ 32 ] = { 494 , 497 } , -- Kul'Tiran
[ 34 ] = { 499 , nil } , -- Dark Iron Dwarf
[ 35 ] = { 924 , 923 } , -- Vulpera
[ 36 ] = { 495 , 498 } , -- Mag'har
[ 37 ] = { 929 , 931 } , -- Mechagnome
[ 52 ] = { 1554 , 1554 } , -- Dracthyr
[ 70 ] = { 1554 , 1554 } , -- Dracthyr
} ;
--Re-check this↑ table every major patch
--[[
function Narci_FindActorIDBy ( name )
local id = 500 ;
local info , tag ;
local find = string.find ;
while id < 2000 do
id = id + 1 ;
info = C_ModelInfo.GetModelSceneActorInfoByID ( id ) ;
if info then
tag = info.scriptTag ;
if tag and find ( tag , name ) then
print ( id , tag ) ;
--return
end
end
end
end
--]]
local ZoomDistanceByRace = {
--[raceID] = {male Zoom, female Zoom, bustOffsetZ_M, bustOffsetZ_F},
[ 1 ] = { 2.4 , 2 } , -- Human
[ 2 ] = { 2.5 , 2 } , -- Orc bow
[ 3 ] = { 2.5 , 2 } , -- Dwarf
[ 4 ] = { 2.2 , 2.1 } , -- Night Elf
[ 5 ] = { 2.5 , 2 } , -- UD
[ 6 ] = { 3 , 2.5 } , -- Tauren
[ 7 ] = { 2.6 , 2.8 } , -- Gnome
[ 8 ] = { 2.5 , 2 } , -- Troll
[ 9 ] = { 2.9 , 2.9 } , -- Goblin
[ 10 ] = { 2 , 2 } , -- Blood Elf
[ 11 ] = { 2.4 , 2 } , -- Goat
[ 22 ] = { 2.8 , 2 } , -- Worgen
[ 24 ] = { 2.9 , 2.4 } , -- Pandaren
[ 27 ] = { 2 , 2 } , -- Nightborne
--[29] = {2, 2}, -- Void Elf
--[28] = {2, 2}, -- Highmountain Tauren
--[30] = {2, 2}, -- Lightforged Draenei
[ 31 ] = { 2.2 , 2 } , -- Zandalari
[ 32 ] = { 2.4 , 2.3 } , -- Kul'Tiran
--[34] = {2, 2}, -- Dark Iron Dwarf
[ 35 ] = { 2.6 , 2.1 } , -- Vulpera
--[36] = {2, 2}, -- Mag'har
--[37] = {2, 2}, -- Mechagnome
}
function NarciAPI_GetCameraZoomDistanceByUnit ( unit )
if not UnitExists ( unit ) or not UnitIsPlayer ( unit ) or not CanInspect ( unit , false ) then return ; end
local _ , _ , raceID = UnitRace ( unit ) ;
local genderID = UnitSex ( unit ) ;
if raceID == 25 or raceID == 26 then --Pandaren A|H
raceID = 24 ;
elseif raceID == 29 then
raceID = 10 ;
elseif raceID == 37 then
raceID = 7 ;
elseif raceID == 30 then
raceID = 11 ;
elseif raceID == 28 then
raceID = 6 ;
elseif raceID == 34 then
raceID = 3 ;
elseif raceID == 36 then
raceID = 2 ;
elseif raceID == 22 then
if unit == " player " then
local _ , inAlternateForm = HasAlternateForm ( ) ;
if not inAlternateForm then
--Wolf
raceID = 22 ;
else
raceID = 1 ;
end
end
end
if not ( raceID and genderID ) then
return 2
elseif ZoomDistanceByRace [ raceID ] then
return ZoomDistanceByRace [ raceID ] [ genderID - 1 ] or 2 ;
else
return 2
end
end
local DEFAULT_ACTOR_INFO_ID = 438 ;
local PanningYOffsetByRace = {
--[raceID] = { { male = {offsetY1 when frame maximiazed, offsetY2} }, {female = ...} }
[ 0 ] = { --default
{ - 290 , - 110 } ,
} ,
[ 4 ] = { --NE
{ - 317 , - 117 } ,
{ - 282 , - 115.5 } ,
} ,
[ 10 ] = { --BE
{ - 282 , - 110 } ,
{ - 290 , - 116 } ,
}
--/dump DressUpFrame.ModelScene:GetActiveCamera().panningYOffset
}
PanningYOffsetByRace [ 29 ] = PanningYOffsetByRace [ 10 ] ;
local function GetPanningYOffset ( raceID , genderID )
genderID = genderID - 1 ;
if PanningYOffsetByRace [ raceID ] and PanningYOffsetByRace [ raceID ] [ genderID ] then
return PanningYOffsetByRace [ raceID ] [ genderID ]
else
return PanningYOffsetByRace [ 0 ] [ 1 ]
end
end
local GetModelSceneActorInfoByID = C_ModelInfo.GetModelSceneActorInfoByID ;
function NarciAPI_GetActorInfoByUnit ( unit )
if not UnitExists ( unit ) or not UnitIsPlayer ( unit ) or not CanInspect ( unit , false ) then return nil , PanningYOffsetByRace [ 0 ] [ 1 ] ; end
local _ , _ , raceID = UnitRace ( unit ) ;
local genderID = UnitSex ( unit ) ;
if raceID == 25 or raceID == 26 then --Pandaren A|H
raceID = 24
end
local actorInfoID ;
if not ( raceID and genderID ) then
actorInfoID = DEFAULT_ACTOR_INFO_ID ; --438
elseif ActorIDByRace [ raceID ] then
actorInfoID = ActorIDByRace [ raceID ] [ genderID - 1 ] or DEFAULT_ACTOR_INFO_ID ;
else
actorInfoID = DEFAULT_ACTOR_INFO_ID ; --438
end
return GetModelSceneActorInfoByID ( actorInfoID ) , GetPanningYOffset ( raceID , genderID )
end
NarciModelSceneActorMixin = CreateFromMixins ( ModelSceneActorMixin ) ;
function NarciModelSceneActorMixin : OnAnimFinished ( )
if self.oneShot then
--self:Hide();
if self.finalSequence then
self : SetAnimation ( 0 , 0 , 0 , self.finalSequence ) ;
else
self : Hide ( ) ;
end
end
if self.onfinishedCallback then
self.onfinishedCallback ( ) ;
end
end
function NarciAPI_SetupModelScene ( modelScene , modelFileID , zoomDistance , view , actorIndex , UseTransit )
local pi = math.pi ;
local model = modelScene ;
local actorTag ;
if not actorIndex then
actorTag = " narciEffectActor " ;
else
actorTag = " narciEffectActor " .. actorIndex
end
local actor = model [ actorTag ] ;
if not actor then
local actorID = 156 ; --effect C_ModelInfo.GetModelSceneActorInfoByID(156)
local actorInfo = C_ModelInfo.GetModelSceneActorInfoByID ( actorID ) ;
--actor = model:AcquireAndInitializeActor(actorInfo);
actor = model : CreateActor ( nil , " NarciModelSceneActorTemplate " ) ;
actor : SetYaw ( pi ) ;
model [ actorTag ] = actor ;
local parentFrame = model : GetParent ( ) ;
if parentFrame then
model : SetFrameLevel ( parentFrame : GetFrameLevel ( ) + 1 or 20 ) ;
else
model : SetFrameLevel ( 20 ) ;
end
end
--local cameraTag = "NarciUI";
local camera = model.narciCamera ;
if not camera then
camera = CameraRegistry : CreateCameraByType ( " OrbitCamera " ) ;
if camera then
model.narciCamera = camera ;
model : AddCamera ( camera ) ;
local modelSceneCameraInfo = C_ModelInfo.GetModelSceneCameraInfoByID ( 114 ) ;
camera : ApplyFromModelSceneCameraInfo ( modelSceneCameraInfo , 1 , 1 ) ; --1 ~ CAMERA_TRANSITION_TYPE_IMMEDIATE / CAMERA_MODIFICATION_TYPE_DISCARD
end
end
model : SetActiveCamera ( camera ) ;
if modelFileID then
actor : SetModelByFileID ( modelFileID ) ;
end
if zoomDistance then
if UseTransit then
--change camera.targetInterpolationAmount for smoothing time --:GetTargetInterpolationAmount() :SetTargetInterpolationAmount(value)
camera : SetZoomDistance ( 1 ) ;
camera : SnapAllInterpolatedValues ( ) ;
After ( 0 , function ( )
camera : SetZoomDistance ( zoomDistance ) ;
end ) ;
else
camera : SetZoomDistance ( zoomDistance ) ;
camera : SynchronizeCamera ( ) ;
end
end
if view then
local pitch , yaw ;
if type ( view ) == " string " then
view = strupper ( view ) ;
if view == " FRONT " then
pitch = 0 ;
yaw = pi ;
elseif view == " BACK " then
pitch = 0 ;
yaw = 0 ;
elseif view == " TOP " then
pitch = pi / 2 ;
yaw = pi ;
elseif view == " BOTTOM " then
pitch = - pi / 2 ;
yaw = pi ;
elseif view == " LEFT " then
pitch = 0 ;
yaw = - pi / 2 ;
elseif view == " RIGHT " then
pitch = 0 ;
yaw = pi / 2 ;
else
return ;
end
elseif type ( view ) == " table " then
pitch = view [ 1 ] ;
yaw = view [ 2 ] ;
if not ( pitch and yaw ) then
return ;
end
end
actor : SetPitch ( pitch ) ;
actor : SetYaw ( yaw ) ;
end
return actor , camera
--[[
if rollDegree then
actor : SetRoll ( rad ( - rollDegree ) ) --Clockwise
end
--]]
end
--[[
ScriptAnimatedEffectController : GetCurrentEffectID ( )
/ dump ScriptedAnimationEffectsUtil.GetEffectByID ( ) 101 Center Rune Wind Cyan
effect = { visual ( fileID ) , visualScale , animationSpeed , ... }
fileID , effectID :
3483475 --Black Swirl 52
984698 --Center Rune Wind Cyan 101
3655832 --Circle Rune Effect 73
3656114 --69
--]]
------------------------------------------------------------------------------
local function ReAnchorFrame ( frame )
--maintain frame top position when changing its height
local oldCenterX = frame : GetCenter ( ) ;
--local oldBottom = frame:GetBottom();
local oldTop = frame : GetTop ( ) ;
local screenWidth = WorldFrame : GetWidth ( ) ;
local screenHeight = WorldFrame : GetHeight ( ) ;
local scale = frame : GetEffectiveScale ( ) ;
if not scale or scale == 0 then
scale = 1 ;
end
local width = frame : GetWidth ( ) / 2 ;
frame : ClearAllPoints ( ) ;
--frame:SetPoint("BOTTOMRIGHT", nil, "BOTTOMRIGHT", oldCenterX + width - screenWidth / scale , oldBottom);
frame : SetPoint ( " TOPRIGHT " , nil , " TOPRIGHT " , oldCenterX + width - screenWidth / scale , oldTop - screenHeight / scale ) ;
end
local function ParserButton_ShowTooltip ( self )
if self.itemLink then
local frame = self : GetParent ( ) ;
local tp = frame.tooltip ;
--GameTooltip_SetBackdropStyle(TP, GAME_TOOLTIP_BACKDROP_STYLE_CORRUPTED_ITEM);
tp : SetOwner ( self , " ANCHOR_NONE " ) ;
tp : SetPoint ( " TOP " , frame.ItemString , " BOTTOM " , 0 , - 14 ) ;
tp : SetHyperlink ( self.itemLink ) ;
tp : SetMinimumWidth ( 254 / 0.8 ) ;
tp : Show ( ) ;
frame : SetHeight ( max ( floor ( tp : GetHeight ( ) - 260 ) , 0 ) + 400 ) ;
ReAnchorFrame ( frame ) ;
end
end
local function ParserButton_GetCursor ( self )
local infoType , itemID , itemLink = GetCursorInfo ( ) ;
self.Highlight : Hide ( )
if not ( infoType and infoType == " item " ) then return end
self.itemLink = itemLink ;
local itemName , _ , itemQuality , itemLevel , _ , _ , _ , _ , itemEquipLoc , itemIcon = GetItemInfo ( itemLink ) ;
local itemString = match ( itemLink , " item:([%-?%d:]+) " ) ;
local enchantID = GetItemEnchantID ( itemLink ) ;
local r , g , b = GetCustomQualityColor ( itemQuality ) ;
--Show info
self.ItemIcon : SetTexture ( itemIcon ) ;
local frame = self : GetParent ( ) ;
frame.ItemName : SetText ( itemName ) ;
frame.ItemName : SetTextColor ( r , g , b ) ;
frame.ItemString : SetText ( itemString ) ;
frame.Pointer : Hide ( ) ;
ParserButton_ShowTooltip ( self ) ;
ClearCursor ( ) ;
end
--[[
function Narci_ItemParser_OnLoad ( self )
self : SetUserPlaced ( false )
self : ClearAllPoints ( ) ;
self : SetPoint ( " CENTER " , UIParent , " CENTER " , 0 , 0 ) ;
self : RegisterForDrag ( " LeftButton " ) ;
self : SetScript ( " OnShow " , ReAnchorFrame ) ;
self.ItemButton : SetScript ( " OnReceiveDrag " , ParserButton_GetCursor ) ;
self.ItemButton : SetScript ( " OnClick " , ParserButton_GetCursor ) ;
self.ItemButton : SetScript ( " OnEnter " , ParserButton_ShowTooltip ) ;
local locale = TEXT_LOCALE ;
local version , build , date , tocversion = GetBuildInfo ( ) ;
self.ClientInfo : SetText ( locale .. " " .. version .. " . " .. build .. " " .. NARCI_VERSION_INFO ) ;
local tooltip = CreateFrame ( " GameTooltip " , " Narci_ItemParserTooltip " , self , " GameTooltipTemplate " ) ;
tooltip : Hide ( ) ;
self.tooltip = tooltip ;
local scale = 0.8 ;
local tooltipScale = 0.8 ;
self : SetScale ( 0.8 ) ;
tooltip : SetScale ( tooltipScale ) ;
end
--]]
----------------------------
-----Item Import/Export-----
----------------------------
local WOWHEAD_ENCODING = " 0zMcmVokRsaqbdrfwihuGINALpTjnyxtgevElBCDFHJKOPQSUWXYZ123456789 " ; --version: 9 WH.calc.hash.getEncoding(9)
local WOWHEAD_DELIMITER = 8 ; --WH.calc.hash.getDelimiter(9)
local COMPRESSION_INDICATOR = 7 ; --WH.calc.hash.getZeroDelimiterCompressionIndicator(9) :7 + single letter
local WOWHEAD_MAXCODING_INDEX = 58 --WH.calc.hash.getMaxEncodingIndex(a); //9 ~ 58
local WOWHEAD_CUSTOMIZATION = " 0zJ89b " ;
local EncodeValue = { }
for i = 0 , # WOWHEAD_ENCODING do
EncodeValue [ i ] = strsub ( WOWHEAD_ENCODING , i + 1 , i + 1 ) ;
end
local EquipmentOrderToCharacterSlot = {
[ 1 ] = 1 ,
[ 2 ] = 3 ,
[ 3 ] = 15 ,
[ 4 ] = 5 ,
[ 5 ] = 4 ,
[ 6 ] = 19 ,
[ 7 ] = 9 ,
[ 8 ] = 10 ,
[ 9 ] = 6 ,
[ 10 ] = 7 ,
[ 11 ] = 8 ,
[ 12 ] = 16 ,
[ 13 ] = 17 ,
} ;
local CharacterSlotToEquipmentOrder = { }
for k , v in pairs ( EquipmentOrderToCharacterSlot ) do
CharacterSlotToEquipmentOrder [ v ] = tostring ( k ) ;
v = tostring ( v ) ;
end
local function EncodeLongValue ( number )
local m = WOWHEAD_MAXCODING_INDEX ;
if number <= m then
return EncodeValue [ number ] ;
end
local floor = floor ;
local shortValues = { number } ;
local v = 0 ;
while ( shortValues [ 1 ] > m ) do
v = floor ( shortValues [ 1 ] / m ) ;
tinsert ( shortValues , shortValues [ 1 ] - m * v ) ;
shortValues [ 1 ] = v ;
end
local str = EncodeValue [ shortValues [ 1 ] ] ;
for i = # shortValues , 2 , - 1 do
if shortValues [ 2 ] ~= " 0 " then
str = str .. EncodeValue [ shortValues [ i ] ]
else
str = str .. " 7 "
end
end
return str
end
local function EncodeItemlist ( itemlist , unitInfo )
if not itemlist or type ( itemlist ) ~= " table " or itemlist == { } then return " " ; end
--itemlist = {[slot] = {itemID, bonusID}}
local raceID , genderID , classID ;
if unitInfo then
raceID , genderID , classID = unitInfo.raceID , unitInfo.genderID , unitInfo.classID ;
else
local _ ;
local unit = " player " ;
_ , _ , raceID = UnitRace ( unit ) ;
genderID = UnitSex ( unit ) ;
_ , _ , classID = UnitClass ( unit ) ;
end
if not ( raceID and genderID and classID ) then
local _ ;
local unit = " player " ;
_ , _ , raceID = UnitRace ( unit ) ;
_ , _ , classID = UnitClass ( unit ) ;
genderID = UnitSex ( unit ) or 2 ;
raceID = raceID or 1 ;
classID = classID or 1 ;
end
genderID = genderID - 2 ; --Male 2 → 0 Female 3 → 1
local wowheadLink = " https://www.wowhead.com/dressing-room#s " .. EncodeValue [ raceID ] .. EncodeValue [ genderID ] .. EncodeValue [ classID ] .. WOWHEAD_CUSTOMIZATION .. WOWHEAD_DELIMITER ;
local segment , slot , item ;
local blanks = 0 ;
for i = 1 , # EquipmentOrderToCharacterSlot do
--item = { itemID, bonusID }
slot = EquipmentOrderToCharacterSlot [ i ]
item = itemlist [ slot ] ;
if item and item [ 1 ] then
segment = EncodeLongValue ( item [ 1 ] )
if # segment < 3 then
segment = " 7 " .. CharacterSlotToEquipmentOrder [ slot ] .. segment
end
item [ 2 ] = item [ 2 ] or 0 ; --bonusID
if slot == 16 and item [ 2 ] > 0 and item [ 2 ] < 99 then
local offHand = itemlist [ 17 ] ;
if offHand and offHand [ 1 ] then
segment = segment .. WOWHEAD_DELIMITER .. " 0 " .. WOWHEAD_DELIMITER .. EncodeLongValue ( offHand [ 1 ] ) .. WOWHEAD_DELIMITER .. " 7c " .. EncodeValue [ item [ 2 ] ] ;
else
segment = segment .. WOWHEAD_DELIMITER .. " 7V " .. EncodeValue [ item [ 2 ] ] ;
end
wowheadLink = wowheadLink .. segment ;
break ;
else
segment = segment .. WOWHEAD_DELIMITER .. EncodeLongValue ( item [ 2 ] ) .. WOWHEAD_DELIMITER ;
end
wowheadLink = wowheadLink .. segment ;
else
blanks = blanks + 1 ;
wowheadLink = wowheadLink .. " 7M "
end
end
return wowheadLink
end
NarciAPI.EncodeItemlist = EncodeItemlist ;
--------------------
----Model Widget----
--------------------
local function NarciAPI_InitializeModelLight ( model )
--Model: DressUpModel/Cinematic Model/...
--Not ModelScene
--model:SetLight(true, false, - 0.44699833180028 , 0.72403680806459 , -0.52532198881773, 0.8, 172/255, 172/255, 172/255, 1, 0.8, 0.8, 0.8);
TransitionAPI.SetModelLight ( model , true , false , - 0.44699833180028 , 0.72403680806459 , - 0.52532198881773 , 0.8 , 172 / 255 , 172 / 255 , 172 / 255 , 1 , 0.8 , 0.8 , 0.8 ) ;
end
NarciAPI.InitializeModelLight = NarciAPI_InitializeModelLight ;
--------------------
--------Time--------
--------------------
function NarciAPI_FormatTime ( seconds )
seconds = seconds or 0 ;
local hour = floor ( seconds / 3600 ) ;
local minute = floor ( ( seconds - 3600 * hour ) / 60 ) ;
local second = mod ( seconds , 60 ) ;
if hour > 0 then
return hour .. " h " .. minute .. " m " .. second .. " s " ;
elseif minute > 0 then
return minute .. " m " .. second .. " s " ;
else
return second .. " s " ;
end
end
----------------------------
----UI Animation Generic----
----------------------------
function NarciAPI_CreateAnimationFrame ( duration , frameName )
local frame = CreateFrame ( " Frame " , frameName ) ;
frame : Hide ( ) ;
frame.total = 0 ;
frame.duration = duration ;
frame : SetScript ( " OnHide " , function ( self )
self.total = 0 ;
end ) ;
return frame ;
end
function NarciAPI_CreateFadingFrame ( parentObject )
local animFade = NarciAPI_CreateAnimationFrame ( 0.2 ) ;
animFade.timeFactor = 1 ;
parentObject.animFade = animFade ;
animFade : SetScript ( " OnUpdate " , function ( frame , elapsed )
frame.t = frame.t + elapsed ;
if frame.t > 0 then
local alpha = frame.fromAlpha ;
alpha = alpha + frame.timeFactor * elapsed ;
frame.fromAlpha = alpha ;
if alpha >= 1 then
alpha = 1 ;
frame : Hide ( ) ;
elseif alpha <= 0 then
alpha = 0 ;
frame : Hide ( ) ;
end
parentObject : SetAlpha ( alpha ) ;
end
end ) ;
function parentObject : FadeOut ( duration , delay )
delay = delay or 0 ;
animFade.t = - delay ;
duration = duration or 0.15 ;
if duration == 0 then
animFade : Hide ( ) ;
parentObject : SetAlpha ( 0 ) ;
return
end
local alpha = parentObject : GetAlpha ( ) ;
animFade.fromAlpha = alpha ;
animFade.timeFactor = - 1 / duration ;
if alpha == 0 then
animFade : Hide ( ) ;
else
animFade : Show ( ) ;
end
end
function parentObject : FadeIn ( duration , delay )
delay = delay or 0 ;
animFade.t = - delay ;
duration = duration or 0.2 ;
if duration == 0 then
animFade : Hide ( ) ;
parentObject : SetAlpha ( 1 ) ;
return
end
local alpha = parentObject : GetAlpha ( ) ;
animFade.fromAlpha = alpha ;
animFade.timeFactor = 1 / duration ;
parentObject : Show ( ) ;
if alpha ~= 1 then
animFade : Show ( ) ;
end
end
return animFade
end
----------------------------
-------Frame Template-------
----------------------------
NarciFrameMixin = CreateFromMixins ( ExpansionTransitionBackdropTemplateMixin ) ;
function NarciFrameMixin : ShowFrame ( state )
self : SetShown ( state ) ;
if state then
self : SetAlpha ( 1 ) ;
else
self : SetAlpha ( 0 ) ;
end
end
function NarciFrameMixin : HideFrame ( )
self : ShowFrame ( false ) ;
end
function NarciFrameMixin : ToggleFrame ( )
if self : IsShown ( ) then
self : ShowFrame ( false ) ;
else
self : ShowFrame ( true ) ;
end
end
function NarciFrameMixin : SetHeaderText ( text , r , g , b )
self.Header : SetText ( text ) ;
self.Header : SetTextColor ( r or 0.4 , g or 0.4 , b or 0.4 ) ;
end
function NarciFrameMixin : SetSizeAndAnchor ( x , y , point , relativeTo , relativePoint , offsetX , offsetY )
if x then x = max ( x , 40 ) end ;
if y then y = max ( y , 40 ) end ;
if x then
if y then
self : SetSize ( x , y ) ;
else
self : SetWidth ( x ) ;
end
else
self : SetHeight ( y ) ;
end
self : ClearAllPoints ( ) ;
self : SetPoint ( point , relativeTo , relativePoint , offsetX , offsetY ) ;
end
function NarciFrameMixin : SetRelativeFrameLevel ( offset )
local parent = self : GetParent ( ) ;
if parent then
local parentLevel = parent : GetFrameLevel ( ) or 0 ;
self : SetFrameStrata ( parent : GetFrameStrata ( ) ) ;
self : SetFrameLevel ( max ( parentLevel + offset , 0 ) ) ;
end
end
function NarciFrameMixin : HideWhenParentIsHidden ( state )
if state then
self : SetScript ( " OnHide " , function ( self )
self : HideFrame ( ) ;
end ) ;
local parent = self : GetParent ( ) ;
if parent and not parent : IsVisible ( ) then
self : HideFrame ( ) ;
end
else
self : SetScript ( " OnHide " , nil ) ;
end
end
-------------------------------------------
local DelayedFadeIn = NarciAPI_CreateAnimationFrame ( 1 ) ;
DelayedFadeIn : SetScript ( " OnUpdate " , function ( self , elapsed )
self.total = self.total + elapsed ;
if self.total >= self.duration then
self : Hide ( ) ;
if self.anchor == GetMouseFocus ( ) then
FadeFrame ( self.object , 0.25 , 1 ) ;
end
end
end ) ;
NarciHotkeyNotificationMixin = { } ;
function NarciHotkeyNotificationMixin : SetKey ( hotkey , mouseButton , description , alwaysShown , enableListener )
local ICON_HEIGHT = 20 ;
self.alwaysShown = alwaysShown ;
self.enableListener = enableListener ;
self.Label : SetText ( description ) ;
if description then
self.GradientM : Show ( ) ;
self.GradientR : Show ( ) ;
else
self.GradientM : Hide ( ) ;
self.GradientR : Hide ( ) ;
end
if alwaysShown then
self : SetAlpha ( 1 ) ;
else
self : SetAlpha ( 0 ) ;
end
local width = self.Label : GetWidth ( ) ;
if hotkey then
self.KeyIcon : SetTexture ( " Interface/AddOns/Narcissus/Art/Keyboard/Key " , nil , nil , " TRILINEAR " ) ;
self.KeyIcon : Show ( ) ;
if string.lower ( hotkey ) == " alt " then
hotkey = NARCI_MODIFIER_ALT ;
end
self.KeyLabel : SetText ( hotkey ) ;
self.KeyLabel : SetShadowColor ( 0 , 0 , 0 ) ;
self.KeyLabel : SetShadowOffset ( 0 , 1.4 ) ;
local texWidth ;
if string.len ( hotkey ) > 5 then
texWidth = 146 ;
self.KeyIcon : SetTexCoord ( 0 , texWidth / 256 , 0.25 , 0.5 ) ;
self.isLongButton = true
else
texWidth = 118 ;
self.isLongButton = nil ;
self.KeyIcon : SetTexCoord ( 0 , texWidth / 256 , 0 , 0.25 ) ;
end
self.keyTexCoord = texWidth / 256 ;
self.KeyIcon : SetSize ( texWidth / 64 * ICON_HEIGHT , ICON_HEIGHT ) ;
width = width + texWidth / 64 * ICON_HEIGHT ;
end
if mouseButton then
self.key = mouseButton ;
self.MouseIcon : SetTexture ( " Interface/AddOns/Narcissus/Art/Keyboard/Mouse " , nil , nil , " TRILINEAR " ) ;
self.MouseIcon : Show ( ) ;
self.MouseIcon : SetSize ( ICON_HEIGHT , ICON_HEIGHT ) ;
if mouseButton == " LeftButton " then
self.MouseIcon : SetTexCoord ( 0 , 0.25 , 0 , 1 ) ;
elseif mouseButton == " RightButton " then
self.MouseIcon : SetTexCoord ( 0.25 , 0.5 , 0 , 1 ) ;
elseif mouseButton == " MiddleButton " then
self.MouseIcon : SetTexCoord ( 0.5 , 0.75 , 0 , 1 ) ;
elseif mouseButton == " MouseWheel " then
self.MouseIcon : SetTexCoord ( 0.75 , 1 , 0 , 1 ) ;
end
if hotkey then
self.KeyIcon : ClearAllPoints ( ) ;
self.KeyIcon : SetPoint ( " RIGHT " , self.MouseIcon , " LEFT " , 0 , 0 ) ;
width = width + ICON_HEIGHT ;
end
end
self : SetWidth ( width ) ;
end
function NarciHotkeyNotificationMixin : ShowTooltip ( )
DelayedFadeIn : Hide ( ) ;
DelayedFadeIn.anchor = GetMouseFocus ( ) ;
DelayedFadeIn.object = self ;
DelayedFadeIn : Show ( ) ;
end
function NarciHotkeyNotificationMixin : FadeIn ( )
DelayedFadeIn : Hide ( ) ;
FadeFrame ( self , 0.25 , 1 ) ;
end
function NarciHotkeyNotificationMixin : FadeOut ( )
DelayedFadeIn : Hide ( ) ;
FadeFrame ( self , 0.25 , 0 ) ;
end
function NarciHotkeyNotificationMixin : JustHide ( )
DelayedFadeIn : Hide ( ) ;
FadeFrame ( self , 0 , 0 ) ;
end
function NarciHotkeyNotificationMixin : OnShow ( )
if self.enableListener then
self : RegisterEvent ( " GLOBAL_MOUSE_UP " ) ;
end
end
function NarciHotkeyNotificationMixin : OnHide ( )
if not self.alwaysShown then
DelayedFadeIn : Hide ( ) ;
self : Hide ( ) ;
self : SetAlpha ( 0 ) ;
end
if self.enableListener then
self : UnregisterEvent ( " GLOBAL_MOUSE_UP " ) ;
end
end
function NarciHotkeyNotificationMixin : OnEvent ( event , key )
if key == self.key then
self : UnregisterEvent ( " GLOBAL_MOUSE_UP " ) ;
self : FadeOut ( ) ;
end
print ( event ) ;
end
function NarciHotkeyNotificationMixin : SetHighlight ( state )
if self.keyTexCoord then
local texCoordY ;
if self.isLongButton then
texCoordY = 0.25 ;
else
texCoordY = 0 ;
end
if state then
texCoordY = texCoordY + 0.5 ;
self.KeyIcon : SetTexCoord ( 0 , self.keyTexCoord , texCoordY + 0.25 , texCoordY ) ;
self.KeyLabel : SetPoint ( " CENTER " , 0 , - 1 ) ;
self.KeyLabel : SetTextColor ( 0.72 , 0.72 , 0.72 ) ;
else
self.KeyIcon : SetTexCoord ( 0 , self.keyTexCoord , texCoordY , texCoordY + 0.25 ) ;
self.KeyLabel : SetPoint ( " CENTER " , 0 , 0 ) ;
self.KeyLabel : SetTextColor ( 0.6 , 0.6 , 0.6 ) ;
end
end
end
NarciQuickFavoriteButtonMixin = { } ;
function NarciQuickFavoriteButtonMixin : SetIconSize ( size )
self.iconSize = size ;
self.Icon : SetSize ( size , size ) ;
self.Bling : SetSize ( size , size ) ;
self.Icon : SetTexCoord ( 0.5 , 0.75 , 0.25 , 0.5 ) ;
self.favTooltip = Narci.L [ " Favorites Add " ] ;
self.unfavTooltip = Narci.L [ " Favorites Remove " ] ;
self.isFav = false ;
end
function NarciQuickFavoriteButtonMixin : SetFavorite ( isFavorite )
if isFavorite then
self.isFav = true ;
self.Icon : SetTexCoord ( 0.75 , 1 , 0.25 , 0.5 ) ;
self.Icon : SetAlpha ( 1 ) ;
else
self.isFav = false ;
self.Icon : SetTexCoord ( 0.5 , 0.75 , 0.25 , 0.5 ) ;
self.Icon : SetAlpha ( 0.4 ) ;
end
end
function NarciQuickFavoriteButtonMixin : PlayVisual ( )
self : StopAnimating ( ) ;
if self.isFav then
self.Icon : SetTexCoord ( 0.75 , 1 , 0.25 , 0.5 ) ;
self.parent . Star : Show ( ) ;
self.Bling . animIn : Play ( ) ;
else
self.Icon : SetTexCoord ( 0.5 , 0.75 , 0.25 , 0.5 ) ;
self.parent . Star : Hide ( ) ;
end
end
function NarciQuickFavoriteButtonMixin : OnEnter ( )
self.Icon : SetAlpha ( 1 ) ;
if self.isFav then
NarciTooltip : NewText ( self.unfavTooltip , nil , nil , 1 ) ;
else
NarciTooltip : NewText ( self.favTooltip , nil , nil , 1 ) ;
end
end
function NarciQuickFavoriteButtonMixin : OnLeave ( )
NarciTooltip : FadeOut ( ) ;
if not self.isFav then
self.Icon : SetAlpha ( 0.6 ) ;
end
end
function NarciQuickFavoriteButtonMixin : OnHide ( )
self : StopAnimating ( ) ;
end
function NarciQuickFavoriteButtonMixin : OnMouseDown ( )
self.Icon : SetSize ( self.iconSize - 2 , self.iconSize - 2 ) ;
NarciTooltip : FadeOut ( ) ;
end
function NarciQuickFavoriteButtonMixin : OnMouseUp ( )
self.Icon : SetSize ( self.iconSize , self.iconSize ) ;
end
function NarciQuickFavoriteButtonMixin : OnDoubleClick ( )
end
-----------------------------------------------------------
NarciDarkRoundButtonMixin = { } ;
function NarciDarkRoundButtonMixin : OnLoad ( )
self.Background : SetTexture ( " Interface \\ AddOns \\ Narcissus \\ Art \\ Buttons \\ Button-Round " , nil , nil , " TRILINEAR " ) ;
end
function NarciDarkRoundButtonMixin : SetLabelText ( label )
self.Label : SetText ( " " ) ;
self.Label : SetText ( label ) ;
local textWidth = self.Label : GetWidth ( ) ;
self.effectiveWidth = floor ( self : GetWidth ( ) + textWidth + 2 + 2 ) ;
end
function NarciDarkRoundButtonMixin : Initialize ( groupIndex , label , tooltip , onClickFunc )
self : SetLabelText ( label ) ;
if tooltip then
self.tooltip = tooltip ;
end
if groupIndex then
self.groupIndex = groupIndex ;
local parent = self : GetParent ( ) ;
if not parent.buttonGroups then
parent.buttonGroups = { } ;
end
if not parent.buttonGroups [ groupIndex ] then
parent.buttonGroups [ groupIndex ] = { } ;
end
tinsert ( parent.buttonGroups [ groupIndex ] , self ) ;
end
if onClickFunc then
self.onClickFunc = onClickFunc ;
end
end
function NarciDarkRoundButtonMixin : GetEffectiveWidth ( )
return self.effectiveWidth or self : GetWidth ( )
end
function NarciDarkRoundButtonMixin : GetGroupEffectiveWidth ( )
if self.groupIndex then
local buttons = self : GetParent ( ) . buttonGroups [ self.groupIndex ] ;
local width = 0 ;
local maxWidth = 0 ;
for i = 1 , # buttons do
width = buttons [ i ] : GetEffectiveWidth ( ) ;
if width > maxWidth then
maxWidth = width ;
end
end
return maxWidth
else
return self : GetEffectiveWidth ( ) ;
end
end
function NarciDarkRoundButtonMixin : Select ( )
self.SelectedIcon : Show ( ) ;
self.isSelected = true ;
end
function NarciDarkRoundButtonMixin : Deselect ( )
self.SelectedIcon : Hide ( ) ;
self.isSelected = nil ;
end
function NarciDarkRoundButtonMixin : UpdateVisual ( )
if self.groupIndex then
local buttons = self : GetParent ( ) . buttonGroups [ self.groupIndex ] ;
for i = 1 , # buttons do
buttons [ i ] : Deselect ( )
end
end
self : Select ( ) ;
end
function NarciDarkRoundButtonMixin : OnClick ( )
self : UpdateVisual ( ) ;
if self.onClickFunc then
self.onClickFunc ( ) ;
end
end
function NarciDarkRoundButtonMixin : OnMouseDown ( )
self.PushedHighlight : Show ( ) ;
end
function NarciDarkRoundButtonMixin : OnMouseUp ( )
self.PushedHighlight : Hide ( ) ;
end
function NarciDarkRoundButtonMixin : UpdateGroupHitBox ( )
if self.groupIndex then
local maxWidth = self : GetGroupEffectiveWidth ( ) ;
local buttons = self : GetParent ( ) . buttonGroups [ self.groupIndex ] ;
for i = 1 , # buttons do
buttons [ i ] : SetHitRectInsets ( 0 , buttons [ i ] : GetWidth ( ) - maxWidth , 0 , 0 ) ;
end
return maxWidth
end
end
NarciDarkSquareButtonMixin = { } ;
function NarciDarkSquareButtonMixin : OnLoad ( )
self.Background : SetTexture ( " Interface \\ AddOns \\ Narcissus \\ Art \\ Buttons \\ Button-RoundedSquare " , nil , nil , " TRILINEAR " ) ;
end
function NarciDarkSquareButtonMixin : Initialize ( groupIndex , icon , texCoord , tooltip , onClickFunc )
if tooltip then
self.tooltip = tooltip ;
end
if icon then
self.Icon : SetTexture ( icon , nil , nil , " TRILINEAR " ) ;
if texCoord then
self.Icon : SetTexCoord ( unpack ( texCoord ) ) ;
end
end
if groupIndex then
self.groupIndex = groupIndex ;
local parent = self : GetParent ( ) ;
if not parent.buttonGroups then
parent.buttonGroups = { } ;
end
if not parent.buttonGroups [ groupIndex ] then
parent.buttonGroups [ groupIndex ] = { } ;
end
tinsert ( parent.buttonGroups [ groupIndex ] , self ) ;
end
if onClickFunc then
self.onClickFunc = onClickFunc ;
end
end
function NarciDarkSquareButtonMixin : OnClick ( )
self : UpdateVisual ( ) ;
if self.onClickFunc then
self.onClickFunc ( ) ;
end
end
function NarciDarkSquareButtonMixin : UpdateVisual ( )
if self.groupIndex then
local button ;
local buttons = self : GetParent ( ) . buttonGroups [ self.groupIndex ] ;
for i = 1 , # buttons do
button = buttons [ i ] ;
if self ~= button then
button : Deselect ( ) ;
end
end
end
self : Select ( ) ;
end
function NarciDarkSquareButtonMixin : OnEnter ( )
self.Icon : SetAlpha ( 1 ) ;
end
function NarciDarkSquareButtonMixin : OnLeave ( )
if not self.isSelected then
self.Icon : SetAlpha ( 0.5 ) ;
end
end
function NarciDarkSquareButtonMixin : OnMouseDown ( )
self.PushedHighlight : Show ( ) ;
end
function NarciDarkSquareButtonMixin : OnMouseUp ( )
self.PushedHighlight : Hide ( ) ;
end
function NarciDarkSquareButtonMixin : Select ( )
self.Background : SetTexCoord ( 0.25 , 0.5 , 0 , 1 ) ;
self.Icon : SetAlpha ( 1 ) ;
self.isSelected = true ;
end
function NarciDarkSquareButtonMixin : Deselect ( )
self.Background : SetTexCoord ( 0 , 0.25 , 0 , 1 ) ;
self.Icon : SetAlpha ( 0.5 ) ;
self.isSelected = nil ;
end
-----------------------------------------------------------
--Clipboard
NarciClipboardMixin = { } ;
function NarciClipboardMixin : OnLoad ( )
self.Tooltip : SetText ( Narci.L [ " Copied " ] ) ;
end
function NarciClipboardMixin : SetText ( text )
self.EditBox : SetText ( text ) ;
end
function NarciClipboardMixin : SetFocus ( )
self.EditBox : SetFocus ( ) ;
end
function NarciClipboardMixin : ClearFocus ( )
self.EditBox : ClearFocus ( ) ;
end
function NarciClipboardMixin : ShowClipboard ( )
self : Show ( ) ;
self.EditBox : Show ( ) ;
self : StopAnimating ( ) ;
self.Tooltip : SetAlpha ( 0 ) ;
end
function NarciClipboardMixin : HasFocus ( )
return self.EditBox . hasFocus ;
end
function NarciClipboardMixin : ReAnchorTooltipToObject ( object )
if object then
self.Tooltip : ClearAllPoints ( ) ;
self.Tooltip : SetPoint ( " CENTER " , object , " CENTER " , 0 , 0 ) ;
end
end
NarciNonEditableEditBoxMixin = { } ;
function NarciNonEditableEditBoxMixin : OnLoad ( )
end
function NarciNonEditableEditBoxMixin : OnEditFocusGained ( )
self.hasFocus = true ;
self : SelectText ( ) ;
end
function NarciNonEditableEditBoxMixin : OnEditFocusLost ( )
self.hasFocus = nil ;
self : Quit ( ) ;
end
function NarciNonEditableEditBoxMixin : SelectText ( )
self : SetCursorPosition ( self.defaultCursorPosition or 0 ) ;
self : HighlightText ( ) ;
end
function NarciNonEditableEditBoxMixin : OnHide ( )
self : StopAnimating ( ) ;
end
function NarciNonEditableEditBoxMixin : Quit ( )
self : ClearFocus ( ) ;
if self.onQuitFunc then
self.onQuitFunc ( ) ;
end
end
function NarciNonEditableEditBoxMixin : OnTextChanged ( isUserInput )
if isUserInput then
self : Quit ( ) ;
end
end
function NarciNonEditableEditBoxMixin : OnKeyDown ( key , down )
local keys = CreateKeyChordStringUsingMetaKeyState ( key ) ;
if keys == " CTRL-C " or key == " COMMAND-C " then
self.hasCopied = true ;
After ( 0 , function ( )
self : GetParent ( ) . Tooltip.good : Play ( ) ;
self : Hide ( ) ;
end ) ;
end
end
NarciChamferedFrameMixin = { } ;
function NarciChamferedFrameMixin : SetBackgroundColor ( r , g , b , a )
if not self.backgroundAtlas then
self.backgroundAtlas = {
self.BackgroundTopLeft , self.BackgroundTop , self.BackgroundTopRight ,
self.BackgroundMiddleLeft , self.BackgroundMiddle , self.BackgroundMiddleRight ,
self.BackgroundBottomLeft , self.BackgroundBottom , self.BackgroundBottomRight ,
} ;
end
a = a or 1 ;
for i = 1 , # self.backgroundAtlas do
self.backgroundAtlas [ i ] : SetVertexColor ( r , g , b ) ;
self.backgroundAtlas [ i ] : SetAlpha ( a ) ;
end
end
function NarciChamferedFrameMixin : SetBorderColor ( r , g , b , a )
if not self.borderAtlas then
self.borderAtlas = {
self.BorderTopLeft , self.BorderTop , self.BorderTopRight ,
self.BorderMiddleLeft , self.BorderMiddle , self.BorderMiddleRight ,
self.BorderBottomLeft , self.BorderBottom , self.BorderBottomRight ,
} ;
end
a = a or 1 ;
for i = 1 , # self.borderAtlas do
self.borderAtlas [ i ] : SetVertexColor ( r , g , b ) ;
self.borderAtlas [ i ] : SetAlpha ( a ) ;
end
end
function NarciChamferedFrameMixin : SetOffset ( value )
--positive value expand the frame background
self.BackgroundTopLeft : SetPoint ( " TOPLEFT " , self , " TOPLEFT " , - value , value ) ;
self.BorderTopLeft : SetPoint ( " TOPLEFT " , self , " TOPLEFT " , - value , value ) ;
self.BackgroundTopRight : SetPoint ( " TOPRIGHT " , self , " TOPRIGHT " , value , value ) ;
self.BorderTopRight : SetPoint ( " TOPRIGHT " , self , " TOPRIGHT " , value , value ) ;
self.BackgroundBottomLeft : SetPoint ( " BOTTOMLEFT " , self , " BOTTOMLEFT " , - value , - value ) ;
self.BorderBottomLeft : SetPoint ( " BOTTOMLEFT " , self , " BOTTOMLEFT " , - value , - value ) ;
self.BackgroundBottomRight : SetPoint ( " BOTTOMRIGHT " , self , " BOTTOMRIGHT " , value , - value ) ;
self.BorderBottomRight : SetPoint ( " BOTTOMRIGHT " , self , " BOTTOMRIGHT " , value , - value ) ;
end
function NarciChamferedFrameMixin : Toggle ( )
self : SetShown ( not self : IsShown ( ) ) ;
end
function NarciChamferedFrameMixin : HideWhenParentIsHidden ( state )
if state then
self : SetScript ( " OnHide " , function ( )
self : Hide ( )
end ) ;
else
self : SetScript ( " OnHide " , nil ) ;
end
end
-----------------------------------------------------------
NarciLanguageUtil = { } ;
NarciLanguageUtil.wowheadLinkPrefix = {
[ " default " ] = " www " ,
[ " deDE " ] = " de " ,
[ " esES " ] = " es " ,
[ " esMX " ] = " es " ,
[ " frFR " ] = " fr " ,
[ " itIT " ] = " it " ,
[ " ptBR " ] = " pt " ,
[ " ruRU " ] = " ru " ,
[ " koKR " ] = " ko " ,
[ " zhCN " ] = " cn " ,
[ " zhTW " ] = " cn " ,
} ;
NarciLanguageUtil.wowheadLinkPrefix . primary = NarciLanguageUtil.wowheadLinkPrefix [ TEXT_LOCALE ] or " www " ;
function NarciLanguageUtil : GetWowheadLink ( specificLanguage )
local prefix ;
if specificLanguage then
prefix = self.wowheadLinkPrefix [ tostring ( specificLanguage ) ] or " www " ;
else
prefix = self.wowheadLinkPrefix . primary ;
end
return ( " https:// " .. prefix .. " .wowhead.com/ " ) ;
end
local function GetAllSelectedTalentIDsAndIcons ( ignorePlayerLevel )
local talentInfo = { }
local maxTiers ;
if ignorePlayerLevel then
maxTiers = 7 ;
else
maxTiers = GetMaxTalentTier ( ) ; --based on the character's level
end
local talentGroup = GetActiveSpecGroup ( ) ;
local _ , _ , classID = UnitClass ( " player " ) ;
talentInfo.classID = classID ;
if not talentGroup then
talentInfo.talentGroup = false ;
return ;
else
talentInfo.talentGroup = talentGroup ;
end
local column , tierUnlockLevel , talentID , iconTexture , selected ;
for tier = 1 , maxTiers do
_ , column , tierUnlockLevel = GetTalentTierInfo ( tier , talentGroup ) ;
if column then
talentID , _ , iconTexture , selected = GetTalentInfo ( tier , column , talentGroup ) ;
talentInfo [ tier ] = { talentID , iconTexture , tierUnlockLevel } ;
else
talentInfo [ tier ] = { false , 134400 } ; --Question Mark Icon
end
end
return talentInfo
end
NarciAPI.GetAllSelectedTalentIDsAndIcons = GetAllSelectedTalentIDsAndIcons ;
local round = function ( number , digit )
digit = digit or 0 ;
local a = 10 ^ digit ;
return math.floor ( number * a + 0.5 ) / a
end
local function CreateColor ( r , g , b )
return round ( r / 255 , 4 ) , round ( g / 255 , 4 ) , round ( b / 255 , 4 ) ;
end
NarciAPI.CreateColor = CreateColor ;
local timeStartNarcissus ;
local function UpdateSessionTime ( )
local t = time ( ) ;
if timeStartNarcissus then
local session = t - timeStartNarcissus ;
local timeSpent = NarciStatisticsDB.TimeSpentInNarcissus ;
if not timeSpent or type ( timeSpent ) ~= " number " then
timeSpent = 0 ;
end
NarciStatisticsDB.TimeSpentInNarcissus = timeSpent + session ;
timeStartNarcissus = nil ;
else
timeStartNarcissus = t ;
end
end
NarciAPI.UpdateSessionTime = UpdateSessionTime ;
local function UpdateScreenshotsCounter ( )
if Narci.isActive then
local numTaken = NarciStatisticsDB.ScreenshotsTakenInNarcissus ;
if not numTaken or type ( numTaken ) ~= " number " then
numTaken = 0 ;
end
NarciStatisticsDB.ScreenshotsTakenInNarcissus = numTaken + 1 ;
end
end
NarciAPI.UpdateScreenshotsCounter = UpdateScreenshotsCounter ;
local function GetClassColorByClassID ( classID )
local classInfo = classID and C_CreatureInfo.GetClassInfo ( classID ) ;
if classInfo then
return C_ClassColor.GetClassColor ( classInfo.classFile ) ;
end
end
local function WrapNameWithClassColor ( name , classID , specID , showIcon , offsetY )
local classInfo = C_CreatureInfo.GetClassInfo ( classID ) ;
if classInfo then
local color = GetClassColorByClassID ( classID ) ;
if color then
if specID and showIcon then
local str = color : WrapTextInColorCode ( name ) ;
local _ , _ , _ , icon , role = GetSpecializationInfoByID ( specID ) ;
if icon then
offsetY = offsetY or 0 ;
str = " |T " .. icon .. " :12:12:-1: " .. offsetY .. " :64:64:4:60:4:60|t " .. str ;
end
return str
else
return color : WrapTextInColorCode ( name ) ;
end
else
return name
end
else
return name
end
end
NarciAPI.GetClassColorByClassID = GetClassColorByClassID ;
NarciAPI.WrapNameWithClassColor = WrapNameWithClassColor ;
local function GetOutfitSlashCommand ( )
local playerActor = DressUpFrame.ModelScene : GetPlayerActor ( ) ;
local itemTransmogInfoList = playerActor and playerActor : GetItemTransmogInfoList ( ) ;
local slashCommand = TransmogUtil.CreateOutfitSlashCommand ( itemTransmogInfoList ) ;
return slashCommand
end
NarciAPI.GetOutfitSlashCommand = GetOutfitSlashCommand ;
NarciAPI.GetScreenPixelSize = function ( )
return 768 / SCREEN_HEIGHT
end
local UtilityModel , ValidDisplayIDs ;
local function DoesCreatureDisplayIDExist ( id )
if not id then return end ;
if not UtilityModel then
ValidDisplayIDs = { } ;
UtilityModel = CreateFrame ( " CinematicModel " , nil , UIParent ) ;
UtilityModel : SetKeepModelOnHide ( true ) ;
UtilityModel : SetSize ( 2 , 2 ) ;
UtilityModel : SetPoint ( " TOP " , UIParent , " BOTTOM " , 0 , - 3 ) ;
UtilityModel : SetScript ( " OnModelLoaded " , function ( self )
local displayID = self : GetDisplayInfo ( ) ;
if displayID and displayID ~= 0 then
ValidDisplayIDs [ displayID ] = true ;
self.displayID = nil ;
end
self : ClearModel ( ) ;
end ) ;
UtilityModel : Hide ( ) ;
end
if ValidDisplayIDs [ id ] ~= nil then
return ValidDisplayIDs [ id ] ;
else
UtilityModel : ClearModel ( ) ;
UtilityModel : SetDisplayInfo ( id ) ;
end
end
NarciAPI.DoesCreatureDisplayIDExist = DoesCreatureDisplayIDExist ;
local function PixelPerfectDriver_Update ( self )
local scale = self : GetParent ( ) : GetEffectiveScale ( ) ;
if scale == self.scale then
return
else
self.scale = scale ;
end
local p = 768 / SCREEN_HEIGHT / scale ;
for i , tex in ipairs ( self.textures ) do
if tex.w then
tex : SetWidth ( p * tex.w ) ;
end
if tex.h then
tex : SetHeight ( p * tex.h ) ;
end
end
end
local function AddPixelPerfectTexture ( frame , texture , pixelWidth , pixelHeight )
if not frame.pixelDriver then
frame.pixelDriver = CreateFrame ( " Frame " , nil , frame ) ;
frame.pixelDriver . textures = { } ;
frame.pixelDriver : SetScript ( " OnShow " , PixelPerfectDriver_Update ) ;
end
texture.w = pixelWidth ;
texture.h = pixelHeight ;
--[[
for i , obj in ipairs ( frame.pixelDriver . textures ) do
if obj == texture then
return
end
end
--]]
tinsert ( frame.pixelDriver . textures , texture ) ;
end
NarciAPI.AddPixelPerfectTexture = AddPixelPerfectTexture ;
local function IsPlayerAtMaxLevel ( )
local playerLevel = UnitLevel ( " player " ) or 0 ;
local maxPlayerLevel ;
if GetMaxLevelForLatestExpansion then
maxPlayerLevel = GetMaxLevelForLatestExpansion ( ) ;
else
local expansionLevel = GetExpansionLevel ( ) or 0 ;
maxPlayerLevel = GetMaxLevelForExpansionLevel ( expansionLevel ) ;
end
return playerLevel >= maxPlayerLevel ;
end
NarciAPI.IsPlayerAtMaxLevel = IsPlayerAtMaxLevel ;
--[[
/ script DEFAULT_CHAT_FRAME : AddMessage ( " \124 Hitem:narcissus:0: \124 h[Test Link] \124 h \124 r " ) ;
function TestFX ( modelFileID , zoomDistance , view )
NarciAPI_SetupModelScene ( TestScene , modelFileID , zoomDistance , view ) ;
end
--]]
--/run TestFX(3152608, nil, ) 122972
--/run TestFX(1011653, 8, "
--/run TestFX(3004122, 8, "LEFT") --Eyeball
--Shake Frame SoulbindViewerMixin:Shake() Bliizard Blizzard_SoulbindsViewer.lua
--Debug
--[[
local DebugUtil = NarciAPI_CreateAnimationFrame ( 1 , " NarciDebug " ) ;
DebugUtil : SetScript ( " OnUpdate " , function ( self , elapsed )
self.total = self.total + elapsed ;
if self.total >= self.duration then
self : Hide ( ) ;
self.isAdding = nil ;
print ( " AVG: " .. self.sum / self.numNumber ) ;
end
end ) ;
function DebugUtil : RestartTimer ( )
self.total = 0 ;
self : Show ( ) ;
end
function DebugUtil : CalculateAverage ( number )
if not number then return end ;
if self.isAdding then
self.sum = self.sum + number ;
self.numNumber = self.numNumber + 1 ;
else
self.sum = number ;
self.numNumber = 1 ;
self.isAdding = true ;
self : RestartTimer ( ) ;
end
end
--]]