· 6 years ago · Aug 17, 2019, 12:40 AM
1--> Library NickTag is a small library for share individual nicknames and avatars.
2
3--> Basic Functions:
4-- NickTag:SetNickname (name) -> set the player nick name, after set nicktag will broadcast the nick over addon guild channel.
5--
6
7local major, minor = "NickTag-1.0", 11
8local NickTag, oldminor = LibStub:NewLibrary (major, minor)
9
10if (not NickTag) then
11 return
12end
13
14--> fix for old nicktag version
15if (_G.NickTag) then
16 if (_G.NickTag.OnEvent) then
17 _G.NickTag:UnregisterComm ("NickTag")
18 _G.NickTag.OnEvent = nil
19 end
20end
21
22------------------------------------------------------------------------------------------------------------------------------------------------------
23--> constants
24
25 local CONST_INDEX_NICKNAME = 1
26 local CONST_INDEX_AVATAR_PATH = 2
27 local CONST_INDEX_AVATAR_TEXCOORD = 3
28 local CONST_INDEX_BACKGROUND_PATH = 4
29 local CONST_INDEX_BACKGROUND_TEXCOORD = 5
30 local CONST_INDEX_BACKGROUND_COLOR = 6
31 local CONST_INDEX_REVISION = 7
32
33 local CONST_COMM_FULLPERSONA = 1
34
35 --[[global]] NICKTAG_DEFAULT_AVATAR = [[Interface\EncounterJournal\UI-EJ-BOSS-Default]]
36 --[[global]] NICKTAG_DEFAULT_BACKGROUND = [[Interface\PetBattles\Weather-ArcaneStorm]]
37 --[[global]] NICKTAG_DEFAULT_BACKGROUND_CORDS = {0.129609375, 1, 1, 0}
38
39------------------------------------------------------------------------------------------------------------------------------------------------------
40--> library stuff
41
42 _G.NickTag = NickTag --> nicktag object over global container
43
44 local pool = {default = true} --> pointer to the cache pool and the default pool if no cache
45 NickTag.debug = false
46
47 LibStub:GetLibrary ("AceComm-3.0"):Embed (NickTag)
48 LibStub:GetLibrary ("AceSerializer-3.0"):Embed (NickTag)
49 LibStub:GetLibrary ("AceTimer-3.0"):Embed (NickTag)
50 local CallbackHandler = LibStub:GetLibrary ("CallbackHandler-1.0")
51 NickTag.callbacks = NickTag.callbacks or CallbackHandler:New (NickTag)
52
53 NickTag.embeds = NickTag.embeds or {}
54 local embed_functions = {
55 "SetNickname",
56 "SetNicknameAvatar",
57 "SetNicknameBackground",
58 "GetNickname",
59 "GetNicknameAvatar",
60 "GetNicknameBackground",
61 "GetNicknameTable",
62 "NickTagSetCache",
63 "ResetPlayerPersona"
64 }
65 function NickTag:Embed (target)
66 for k, v in pairs (embed_functions) do
67 target[v] = self[v]
68 end
69 self.embeds [target] = true
70 return target
71 end
72
73 function NickTag:Msg (...)
74 if (NickTag.debug) then
75 print ("|cFFFFFF00NickTag:|r", ...)
76 end
77 end
78
79 local enUS = LibStub("AceLocale-3.0"):NewLocale ("NickTag-1.0", "enUS", true)
80 if (enUS) then
81 enUS ["STRING_ERROR_1"] = "Your nickname is too long, max of 12 characters is allowed."
82 enUS ["STRING_ERROR_2"] = "Only letters and two spaces are allowed."
83 enUS ["STRING_ERROR_3"] = "You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."
84 enUS ["STRING_ERROR_4"] = "Name isn't a valid string."
85 enUS ["STRING_INVALID_NAME"] = "Invalid Name"
86 end
87
88 local ptBR = LibStub("AceLocale-3.0"):NewLocale ("NickTag-1.0", "ptBR")
89 if (ptBR) then
90 ptBR ["STRING_ERROR_1"] = "Seu apelido esta muito longo, o maximo permitido sao 12 caracteres."
91 ptBR ["STRING_ERROR_2"] = "Apenas letras, numeros e espacos sao permitidos no apelido."
92 ptBR ["STRING_ERROR_3"] = "Voce nao pode usar a mesma letra mais de 2 vezes consecutivas, dois espacos consecutivos ou mais de 2 espacos."
93 ptBR ["STRING_ERROR_4"] = "Nome nao eh uma string valida."
94 ptBR ["STRING_INVALID_NAME"] = "Nome Invalido"
95 end
96
97 NickTag.background_pool = {
98 {[[Interface\PetBattles\Weather-ArcaneStorm]], "Arcane Storm", {0.129609375, 1, 1, 0}},
99 {[[Interface\PetBattles\Weather-Blizzard]], "Blizzard", {0.068704154, 1, 1, 0}},
100 {[[Interface\PetBattles\Weather-BurntEarth]], "Burnt Earth", {0.087890625, 0.916015625, 1, 0}},
101 {[[Interface\PetBattles\Weather-Darkness]], "Darkness", {0.080078125, 0.931640625, 1, 0}},
102 {[[Interface\PetBattles\Weather-Moonlight]], "Moonlight", {0.02765625, 0.94359375, 1, 0}},
103 {[[Interface\PetBattles\Weather-Moonlight]], "Moonlight (reverse)", {0.94359375, 0.02765625, 1, 0}},
104 {[[Interface\PetBattles\Weather-Mud]], "Mud", {0.068359375, 0.94359375, 1, 0}},
105 {[[Interface\PetBattles\Weather-Rain]], "Rain", {0.078125, 0.970703125, 1, 0}},
106 {[[Interface\PetBattles\Weather-Sandstorm]], "Sand Storm", {0.048828125, 0.947265625, 1, 0}},
107 {[[Interface\PetBattles\Weather-StaticField]], "Static Field", {0.1171875, 0.953125, 1, 0}},
108 {[[Interface\PetBattles\Weather-Sunlight]], "Sun Light", {0.1772721, 0.953125, 1, 0}},
109 {[[Interface\PetBattles\Weather-Windy]], "Windy", {0.9453125, 0.07421875, 0.8203125, 0}}
110 }
111
112 NickTag.avatar_pool = {
113 {[[Interface\EncounterJournal\UI-EJ-BOSS-Arcanist Doan]], "Arcanist Doan"},
114 {[[Interface\EncounterJournal\UI-EJ-BOSS-Archbishop Benedictus]], "Archbishop Benedictus"},
115 {[[Interface\EncounterJournal\UI-EJ-BOSS-Argent Confessor Paletress]], "Argent Confessor Paletress"},
116 {[[Interface\EncounterJournal\UI-EJ-BOSS-Armsmaster Harlan]], "Armsmaster Harlan"},
117 {[[Interface\EncounterJournal\UI-EJ-BOSS-Asira Dawnslayer]], "Asira Dawnslayer"},
118 {[[Interface\EncounterJournal\UI-EJ-BOSS-Baelog]], "Baelog"},
119 {[[Interface\EncounterJournal\UI-EJ-BOSS-Baron Ashbury]], "Baron Ashbury"},
120 {[[Interface\EncounterJournal\UI-EJ-BOSS-Baron Silverlaine]], "Baron Silverlaine"},
121 {[[Interface\EncounterJournal\UI-EJ-BOSS-Blood Guard Porung]], "Blood Guard Porung"},
122 {[[Interface\EncounterJournal\UI-EJ-BOSS-Bronjahm]], "Bronjahm"},
123 {[[Interface\EncounterJournal\UI-EJ-BOSS-Brother Korloff]], "Brother Korloff"},
124 {[[Interface\EncounterJournal\UI-EJ-BOSS-Captain Skarloc]], "Captain Skarloc"},
125 {[[Interface\EncounterJournal\UI-EJ-BOSS-Chief Ukorz Sandscalp]], "Chief Ukorz Sandscalp"},
126 {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Kolurg]], "Commander Kolurg"},
127 {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Malor]], "Commander Malor"},
128 {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Sarannis]], "Commander Sarannis"},
129 {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Springvale]], "Commander Springvale"},
130 {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Stoutbeard]], "Commander Stoutbeard"},
131 {[[Interface\EncounterJournal\UI-EJ-BOSS-Corla, Herald of Twilight]], "Corla, Herald of Twilight"},
132 {[[Interface\EncounterJournal\UI-EJ-BOSS-Cyanigosa]], "Cyanigosa"},
133 {[[Interface\EncounterJournal\UI-EJ-BOSS-Darkmaster Gandling]], "Darkmaster Gandling"},
134 {[[Interface\EncounterJournal\UI-EJ-BOSS-Doctor Theolen Krastinov]], "Doctor Theolen Krastinov"},
135 {[[Interface\EncounterJournal\UI-EJ-BOSS-DoomRel]], "DoomRel"},
136 {[[Interface\EncounterJournal\UI-EJ-BOSS-Eadric the Pure]], "Eadric the Pure"},
137 {[[Interface\EncounterJournal\UI-EJ-BOSS-Emperor Thaurissan]], "Emperor Thaurissan"},
138 {[[Interface\EncounterJournal\UI-EJ-BOSS-Empyreal Queens]], "Lu'lin"},
139 {[[Interface\EncounterJournal\UI-EJ-BOSS-Exarch Maladaar]], "Exarch Maladaar"},
140 {[[Interface\EncounterJournal\UI-EJ-BOSS-Fineous Darkvire]], "Fineous Darkvire"},
141 {[[Interface\EncounterJournal\UI-EJ-BOSS-Galdarah]], "Galdarah"},
142 {[[Interface\EncounterJournal\UI-EJ-BOSS-Garajal the Spiritbinder]], "Garajal the Spiritbinder"},
143 {[[Interface\EncounterJournal\UI-EJ-BOSS-Garrosh Hellscream]], "Garrosh Hellscream"},
144 {[[Interface\EncounterJournal\UI-EJ-BOSS-General Nazgrim]], "General Nazgrim"},
145 {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Champions-Alliance]], "Grand Champions-Alliance"},
146 {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Champions-Horde]], "Grand Champions-Horde"},
147 {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Magus Telestra]], "Grand Magus Telestra"},
148 {[[Interface\EncounterJournal\UI-EJ-BOSS-HateRel]], "HateRel"},
149 {[[Interface\EncounterJournal\UI-EJ-BOSS-Hazzarah]], "Hazzarah"},
150 {[[Interface\EncounterJournal\UI-EJ-BOSS-Hearthsinger Forresten]], "Hearthsinger Forresten"},
151 {[[Interface\EncounterJournal\UI-EJ-BOSS-Helix Gearbreaker]], "Helix Gearbreaker"},
152 {[[Interface\EncounterJournal\UI-EJ-BOSS-High Botanist Freywinn]], "High Botanist Freywinn"},
153 {[[Interface\EncounterJournal\UI-EJ-BOSS-High Inquisitor Whitemane]], "High Inquisitor Whitemane"},
154 {[[Interface\EncounterJournal\UI-EJ-BOSS-High Interrogator Gerstahn]], "High Interrogator Gerstahn"},
155 {[[Interface\EncounterJournal\UI-EJ-BOSS-High Justice Grimstone]], "High Justice Grimstone"},
156 {[[Interface\EncounterJournal\UI-EJ-BOSS-Houndmaster Braun]], "Houndmaster Braun"},
157 {[[Interface\EncounterJournal\UI-EJ-BOSS-Houndmaster Loksey]], "Houndmaster Loksey"},
158 {[[Interface\EncounterJournal\UI-EJ-BOSS-Hydromancer Velratha]], "Hydromancer Velratha"},
159 {[[Interface\EncounterJournal\UI-EJ-BOSS-Illyanna Ravenoak]], "Illyanna Ravenoak"},
160 {[[Interface\EncounterJournal\UI-EJ-BOSS-Ingvar the Plunderer]], "Ingvar the Plunderer"},
161 {[[Interface\EncounterJournal\UI-EJ-BOSS-Instructor Galford]], "Instructor Galford"},
162 {[[Interface\EncounterJournal\UI-EJ-BOSS-Instructor Malicia]], "Instructor Malicia"},
163 {[[Interface\EncounterJournal\UI-EJ-BOSS-Interrogator Vishas]], "Interrogator Vishas"},
164 {[[Interface\EncounterJournal\UI-EJ-BOSS-Isiset]], "Isiset"},
165 {[[Interface\EncounterJournal\UI-EJ-BOSS-JainaProudmoore]], "Jaina Proudmoore"},
166 {[[Interface\EncounterJournal\UI-EJ-BOSS-Jandice Barov]], "Jandice Barov"},
167 {[[Interface\EncounterJournal\UI-EJ-BOSS-Kaelthas Sunstrider]], "Kaelthas Sunstrider"},
168 {[[Interface\EncounterJournal\UI-EJ-BOSS-Kelidan the Breaker]], "Kelidan the Breaker"},
169 {[[Interface\EncounterJournal\UI-EJ-BOSS-Krick]], "Krick"},
170 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lady Anacondra]], "Lady Anacondra"},
171 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lady Illucia Barov]], "Lady Illucia Barov"},
172 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lethtendris]], "Lethtendris"},
173 {[[Interface\EncounterJournal\UI-EJ-BOSS-Loken]], "Loken"},
174 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Alexei Barov]], "Lord Alexei Barov"},
175 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Aurius Rivendare]], "Lord Aurius Rivendare"},
176 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Cobrahn]], "Lord Cobrahn"},
177 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Pythas]], "Lord Pythas"},
178 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Serpentis]], "Lord Serpentis"},
179 {[[Interface\EncounterJournal\UI-EJ-BOSS-Lorgus Jett]], "Lorgus Jett"},
180 {[[Interface\EncounterJournal\UI-EJ-BOSS-Mage Lord Urom]], "Mage Lord Urom"},
181 {[[Interface\EncounterJournal\UI-EJ-BOSS-Magister Kalendris]], "Magister Kalendris"},
182 {[[Interface\EncounterJournal\UI-EJ-BOSS-Magistrate Barthilas]], "Magistrate Barthilas"},
183 {[[Interface\EncounterJournal\UI-EJ-BOSS-Maiden of Grief]], "Maiden of Grief"},
184 {[[Interface\EncounterJournal\UI-EJ-BOSS-Maleki the Pallid]], "Maleki the Pallid"},
185 {[[Interface\EncounterJournal\UI-EJ-BOSS-Nethermancer Sepethrea]], "Nethermancer Sepethrea"},
186 {[[Interface\EncounterJournal\UI-EJ-BOSS-Olaf]], "Olaf"},
187 {[[Interface\EncounterJournal\UI-EJ-BOSS-Pathaleon the Calculator]], "Pathaleon the Calculator"},
188 {[[Interface\EncounterJournal\UI-EJ-BOSS-Prince Tortheldrin]], "Prince Tortheldrin"},
189 {[[Interface\EncounterJournal\UI-EJ-BOSS-Princess Moira Bronzebeard]], "Princess Moira Bronzebeard"},
190 {[[Interface\EncounterJournal\UI-EJ-BOSS-QueenAzshara]], "Queen Azshara"},
191 {[[Interface\EncounterJournal\UI-EJ-BOSS-Randolph Moloch]], "Randolph Moloch"},
192 {[[Interface\EncounterJournal\UI-EJ-BOSS-Renataki]], "Renataki"},
193 {[[Interface\EncounterJournal\UI-EJ-BOSS-Ribbly Screwspigot]], "Ribbly Screwspigot"},
194 {[[Interface\EncounterJournal\UI-EJ-BOSS-Scarlet Commander Mograine]], "Scarlet Commander Mograine"},
195 {[[Interface\EncounterJournal\UI-EJ-BOSS-Selin Fireheart]], "Selin Fireheart"},
196 {[[Interface\EncounterJournal\UI-EJ-BOSS-Siegecrafter Blackfuse]], "Siegecrafter Blackfuse"},
197 {[[Interface\EncounterJournal\UI-EJ-BOSS-Skarvald the Constructor]], "Skarvald the Constructor"},
198 {[[Interface\EncounterJournal\UI-EJ-BOSS-Tribunal of the Ages]], "Tribunal of the Ages"},
199 {[[Interface\EncounterJournal\UI-EJ-BOSS-TyrandeWhisperwind]], "Tyrande Whisperwind"},
200 {[[Interface\EncounterJournal\UI-EJ-BOSS-Twilight Lord Kelris]], "Twilight Lord Kelris"},
201 {[[Interface\EncounterJournal\UI-EJ-BOSS-Vanessa VanCleef]], "Vanessa VanCleef"},
202 {[[Interface\EncounterJournal\UI-EJ-BOSS-Vazruden]], "Vazruden"},
203 {[[Interface\EncounterJournal\UI-EJ-BOSS-Warchief Rend Blackhand]], "Warchief Rend Blackhand"},
204 {[[Interface\EncounterJournal\UI-EJ-BOSS-Willey Hopebreaker]], "Willey Hopebreaker"},
205 {[[Interface\EncounterJournal\UI-EJ-BOSS-Witch Doctor Zumrah]], "Witch Doctor Zumrah"},
206 }
207------------------------------------------------------------------------------------------------------------------------------------------------------
208--> send and receive functions
209
210 function NickTag:OnReceiveComm (prefix, data, channel, source)
211
212 if (not source) then
213 return
214 end
215
216 local _type, serial, arg3, name, realm, version = select (2, NickTag:Deserialize (data))
217
218 --> 0x1: received a full persona
219 if (_type == CONST_COMM_FULLPERSONA) then
220 local receivedPersona = arg3
221 version = name
222
223 if (not receivedPersona or type (receivedPersona) ~= "table") then
224 NickTag:Msg ("FULLPERSONA received but it's invalid ", source)
225 return
226 end
227
228 if (source ~= UnitName ("player") and (version and version == minor) and receivedPersona) then
229
230 local storedPersona = NickTag:GetNicknameTable (source)
231 if (not storedPersona) then
232 storedPersona = NickTag:Create (source)
233 end
234
235 --what's the point of the revision if there's no more revision checks? -- feels deprecated
236 --will leave this as a comment for now, might remove in the future
237 --if (storedPersona [CONST_INDEX_REVISION] < receivedPersona [CONST_INDEX_REVISION]) then
238 storedPersona [CONST_INDEX_REVISION] = receivedPersona [CONST_INDEX_REVISION]
239
240 --> we need to check if the received nickname fit in our rules.
241 local allowNickName = NickTag:CheckName (receivedPersona [CONST_INDEX_NICKNAME])
242 if (allowNickName) then
243 storedPersona [CONST_INDEX_NICKNAME] = receivedPersona [CONST_INDEX_NICKNAME]
244 else
245 storedPersona [CONST_INDEX_NICKNAME] = LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_INVALID_NAME"]
246 end
247
248 storedPersona [CONST_INDEX_NICKNAME] = receivedPersona [CONST_INDEX_NICKNAME]
249
250 --> update the rest
251 --avatar path
252 storedPersona [CONST_INDEX_AVATAR_PATH] = type (receivedPersona [CONST_INDEX_AVATAR_PATH]) == "string" and receivedPersona [CONST_INDEX_AVATAR_PATH] or ""
253
254 --avatar texcoord
255 if (type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD]) == "boolean") then
256 storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = {0, 1, 0, 1}
257
258 elseif (type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD]) == "table") then
259 storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = storedPersona [CONST_INDEX_AVATAR_TEXCOORD] or {}
260 storedPersona [CONST_INDEX_AVATAR_TEXCOORD][1] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][1]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][1] or 0
261 storedPersona [CONST_INDEX_AVATAR_TEXCOORD][2] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][2]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][2] or 1
262 storedPersona [CONST_INDEX_AVATAR_TEXCOORD][3] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][3]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][3] or 0
263 storedPersona [CONST_INDEX_AVATAR_TEXCOORD][4] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][4]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][4] or 1
264 else
265 storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = {0, 1, 0, 1}
266 end
267
268 --background texcoord
269 if (type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD]) == "boolean") then
270 storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = {0, 1, 0, 1}
271
272 elseif (type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD]) == "table") then
273 storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] or {}
274 storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1] or 0
275 storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2] or 1
276 storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3] or 0
277 storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4] or 1
278 else
279 storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = {0, 1, 0, 1}
280 end
281
282 --background path
283 storedPersona [CONST_INDEX_BACKGROUND_PATH] = type (receivedPersona [CONST_INDEX_BACKGROUND_PATH]) == "string" and receivedPersona [CONST_INDEX_BACKGROUND_PATH] or ""
284
285 --background color
286 if (type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR]) == "table") then
287 storedPersona [CONST_INDEX_BACKGROUND_COLOR] = storedPersona [CONST_INDEX_BACKGROUND_COLOR] or {}
288 storedPersona [CONST_INDEX_BACKGROUND_COLOR][1] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][1]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][1] or 1
289 storedPersona [CONST_INDEX_BACKGROUND_COLOR][2] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][2]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][2] or 1
290 storedPersona [CONST_INDEX_BACKGROUND_COLOR][3] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][3]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][3] or 1
291 else
292 storedPersona [CONST_INDEX_BACKGROUND_COLOR] = {1, 1, 1}
293 end
294
295 NickTag:Msg ("FULLPERSONA received and updated for character: ", source, "new nickname: ", receivedPersona [CONST_INDEX_NICKNAME])
296 --end
297 end
298
299 end
300
301 end
302
303 NickTag:RegisterComm ("NickTag", "OnReceiveComm")
304
305 --frame for listening to event
306 NickTag.EventFrame = NickTag.EventFrame or CreateFrame ("frame")
307 NickTag.EventFrame.InfoSendCooldown = 0
308
309 function NickTag.OnEvent (self, event, ...)
310 if (NickTag.EventFrame.InfoSendCooldown > time()) then
311 if (not NickTag.EventFrame.ScheduledSend or NickTag.EventFrame.ScheduledSend._cancelled) then
312 NickTag.EventFrame.ScheduledSend = C_Timer.NewTimer (30, NickTag.SendPersona)
313 end
314 else
315 NickTag:SendPersona()
316 end
317 end
318
319 --when the roster changes or the player enters the game, send the persona to guild mates
320 --send on roster update can only happen every 30 seconds, if is on cooldown, it'll schedule an update
321 NickTag.EventFrame:RegisterEvent ("GROUP_ROSTER_UPDATE")
322 NickTag.EventFrame:RegisterEvent ("PLAYER_LOGIN")
323
324 NickTag.EventFrame:SetScript ("OnEvent", NickTag.OnEvent)
325
326 --send the persona in the guild comm chanel
327 function NickTag:SendPersona()
328
329 --check if the player has a persona
330 local nickTable = NickTag:GetNicknameTable (UnitName ("player"), true)
331 if (not nickTable) then
332 return
333 end
334 NickTag:Msg ("SendPersona() -> broadcast")
335
336 if (NickTag.EventFrame.ScheduledSend and not NickTag.EventFrame.ScheduledSend._cancelled) then
337 NickTag.EventFrame.ScheduledSend:Cancel()
338 end
339 NickTag.EventFrame.ScheduledSend = nil
340 NickTag.EventFrame.InfoSendCooldown = time() + 29
341
342 --> updating my own persona
343 NickTag.send_scheduled = false
344
345 --> auto change nickname if we have an invalid nickname
346 if (NickTag:GetNickname (UnitName ("player")) == LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_INVALID_NAME"]) then
347 nickTable [CONST_INDEX_NICKNAME] = UnitName ("player")
348 end
349
350 --> broadcast over guild channel
351 if (IsInGuild()) then
352 NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_FULLPERSONA, 0, NickTag:GetNicknameTable (UnitName ("player")), minor), "GUILD")
353 end
354
355 end
356
357------------------------------------------------------------------------------------------------------------------------------------------------------
358--> cache stuff
359
360 --> this will clear the information about the player within nicktag cache
361 function NickTag:ResetPlayerPersona()
362 local playerName = UnitName ("player")
363
364 if (playerName) then
365 local playerPersona = NickTag:GetNicknameTable (playerName)
366 if (playerPersona) then
367 playerPersona [CONST_INDEX_NICKNAME] = playerName
368 playerPersona [CONST_INDEX_AVATAR_PATH] = false
369 playerPersona [CONST_INDEX_AVATAR_TEXCOORD] = false
370 playerPersona [CONST_INDEX_BACKGROUND_PATH] = false
371 playerPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = false
372 playerPersona [CONST_INDEX_BACKGROUND_COLOR] = false
373 playerPersona [CONST_INDEX_REVISION] = playerPersona [CONST_INDEX_REVISION] + 1
374
375 C_Timer.After (1, NickTag.SendPersona)
376 end
377 end
378 end
379
380 --> reset cache
381 function NickTag:ResetCache()
382
383 local playerName = UnitName ("player")
384
385 if (playerName) then
386 local player = NickTag:GetNicknameTable (playerName)
387 if (player and pool.last_version == minor) then
388 for thisPlayerName, _ in pairs (pool) do
389 if (thisPlayerName ~= playerName) then
390 pool [thisPlayerName] = nil
391 end
392 end
393 --vardump (pool)
394 else
395 table.wipe (pool)
396 end
397
398 pool.nextreset = time() + (60*60*24*15) --> 15 days or 1296000 seconds
399 pool.last_version = minor
400 else
401 --> sometimes player guid isn't available right after logon, so, just schedule until it become available.
402 NickTag:ScheduleTimer ("ResetCache", 0.3)
403 end
404 end
405
406 function NickTag:NickTagSetCache (_table)
407 if (not pool.default) then
408 return table.wipe (_table)
409 end
410
411 pool = _table
412
413 if (not pool.nextreset) then
414 pool.nextreset = time() + (60*60*24*15)
415 end
416 if (not pool.last_version) then
417 pool.last_version = minor
418 end
419 if (pool.last_version < minor) then
420 pool.nextreset = 1
421 end
422 if (time() > pool.nextreset) then
423 NickTag:ResetCache()
424 end
425 end
426
427------------------------------------------------------------------------------------------------------------------------------------------------------
428--> basic functions
429
430 --> trim from from http://lua-users.org/wiki/StringTrim
431 function trim (s)
432 local from = s:match"^%s*()"
433 return from > #s and "" or s:match(".*%S", from)
434 end
435 --
436 local titlecase = function (first, rest)
437 return first:upper()..rest:lower()
438 end
439 --
440 local have_repeated = false
441 local count_spaces = 0
442 local check_repeated = function (char)
443 if (char == " ") then
444 have_repeated = true
445 elseif (string.len (char) > 2) then
446 have_repeated = true
447 elseif (char == " ") then
448 count_spaces = count_spaces + 1
449 end
450 end
451
452
453 --> we need to keep game smooth checking and formating nicknames.
454 --> SetNickname and names comming from other player need to be check.
455 function NickTag:CheckName (name)
456
457 --> as nicktag only work internally in the guild, we think that is not necessary a work filter to avoid people using bad language.
458
459 if (type (name) ~= "string") then
460 return false, LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_ERROR_4"] --> error 4 = name isn't a valid string
461 end
462
463 name = trim (name)
464
465 --> limit nickname to 12 characters, same as wow.
466 local len = string.len (name)
467 if (len > 32) then
468 return false, LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_ERROR_1"] --> error 1 = nickname is too long, max of 12 characters.
469 end
470
471 --> check if contain any non allowed characters, by now only accpet letters, numbers and spaces.
472 --> by default wow do not accetp spaces, but here will allow.
473 --> tested over lua 5.2 and this capture was okey with accents, not sure why inside wow this doesn't work.
474 local notallow = string.find (name, "[^a-zA-Z�������%s]")
475
476 --> check if there is sequencial repeated characters, like "Jasooon" were repeats 3 times the "o" character.
477 --> got this from http://stackoverflow.com/questions/15608299/lua-pattern-matching-repeating-character
478 have_repeated = false
479 count_spaces = 0
480 string.gsub (name, '.', '\0%0%0'):gsub ('(.)%z%1','%1'):gsub ('%z.([^%z]+)', check_repeated)
481
482
483 return true
484 end
485
486 --> set the "player" nickname and schedule for send updated persona
487 function NickTag:SetNickname (name)
488
489 --> check data before
490 assert (type (name) == "string", "NickTag 'SetNickname' expects a string on #1 argument.")
491
492 --> check if the nickname is okey to allowed to use.
493 local okey, errortype = NickTag:CheckName (name)
494
495 --> here we format the text to match titles, e.g converts name like "JASON NICKSHOW" into "Jason Nickshow".
496 name = name
497
498 local playerName = UnitName ("player")
499
500 --> get the full nick table.
501 local nickTable = NickTag:GetNicknameTable (playerName)
502 if (not nickTable) then
503 nickTable = NickTag:Create (playerName, true)
504 end
505
506 --> change the nickname for the player nick table.
507 if (nickTable [CONST_INDEX_NICKNAME] ~= name) then
508 nickTable [CONST_INDEX_NICKNAME] = name
509
510 --increase the table revision
511 NickTag:IncRevision()
512
513 --> send the update for script which need it.
514 NickTag.callbacks:Fire ("NickTag_Update", CONST_INDEX_NICKNAME)
515
516 --> schedule a update for revision and broadcast full persona.
517 --> this is a kind of protection for scripts which call SetNickname, SetColor and SetAvatar one after other, so scheduling here avoid three revisions upgrades and 3 broadcasts to the guild.
518 if (not NickTag.send_scheduled) then
519 NickTag.send_scheduled = true
520 NickTag:ScheduleTimer ("SendPersona", 1)
521 end
522
523 else
524 NickTag:Msg ("SetNickname() name is the same on the pool ", name, nickTable [CONST_INDEX_NICKNAME])
525 end
526
527 return true
528 end
529
530 function NickTag:SetNicknameAvatar (texture, l, r, t, b)
531
532 if (l == nil) then
533 l, r, t, b = 0, 1, 0, 1
534 elseif (type (l) == "table") then
535 l, r, t, b = unpack (l)
536 end
537
538 --> check data before
539 assert (texture and l and r and t and b, "NickTag 'SetNicknameAvatar' bad format. Usage NickTag:SetAvatar (texturepath [, L, R, T, B] or texturepath [, {L, R, T, B}])")
540
541 local playerName = UnitName ("player")
542
543 local nickTable = NickTag:GetNicknameTable (playerName)
544 if (not nickTable) then
545 nickTable = NickTag:Create (playerName, true)
546 end
547
548 if (nickTable [CONST_INDEX_AVATAR_PATH] ~= texture) then
549 nickTable [CONST_INDEX_AVATAR_PATH] = texture
550
551 --increase the table revision
552 NickTag:IncRevision()
553
554 --> by default, CONST_INDEX_AVATAR_TEXCOORD comes as boolean false
555 if (type (nickTable [CONST_INDEX_AVATAR_TEXCOORD]) == "boolean") then
556 nickTable [CONST_INDEX_AVATAR_TEXCOORD] = {}
557 end
558
559 nickTable [CONST_INDEX_AVATAR_TEXCOORD][1] = l
560 nickTable [CONST_INDEX_AVATAR_TEXCOORD][2] = r
561 nickTable [CONST_INDEX_AVATAR_TEXCOORD][3] = t
562 nickTable [CONST_INDEX_AVATAR_TEXCOORD][4] = b
563
564 NickTag.callbacks:Fire ("NickTag_Update", CONST_INDEX_AVATAR_PATH)
565
566 if (not NickTag.send_scheduled) then
567 NickTag.send_scheduled = true
568 NickTag:ScheduleTimer ("SendPersona", 1)
569 end
570 end
571
572 return true
573 end
574
575 --> set the background
576 function NickTag:SetNicknameBackground (path, texcoord, color, silent)
577
578 if (not silent) then
579 assert (type (path) == "string", "NickTag 'SetNicknameBackground' expects a string on #1 argument.")
580 else
581 if (type (path) ~= "string") then
582 return
583 end
584 end
585
586 if (not texcoord) then
587 texcoord = {0, 1, 0, 1}
588 end
589
590 if (not color) then
591 color = {1, 1, 1}
592 end
593
594 local playerName = UnitName ("player")
595
596 local nickTable = NickTag:GetNicknameTable (playerName)
597 if (not nickTable) then
598 nickTable = NickTag:Create (playerName, true)
599 end
600
601 local need_sync = false
602 if (nickTable [CONST_INDEX_BACKGROUND_PATH] ~= path) then
603 nickTable [CONST_INDEX_BACKGROUND_PATH] = path
604 need_sync = true
605 end
606
607 if (nickTable [CONST_INDEX_BACKGROUND_TEXCOORD] ~= texcoord) then
608 nickTable [CONST_INDEX_BACKGROUND_TEXCOORD] = texcoord
609 need_sync = true
610 end
611
612 if (nickTable [CONST_INDEX_BACKGROUND_COLOR] ~= color) then
613 nickTable [CONST_INDEX_BACKGROUND_COLOR] = color
614 need_sync = true
615 end
616
617 if (need_sync) then
618
619 --increase the table revision
620 NickTag:IncRevision()
621
622 NickTag.callbacks:Fire ("NickTag_Update", CONST_INDEX_BACKGROUND_PATH)
623
624 if (not NickTag.send_scheduled) then
625 NickTag.send_scheduled = true
626 NickTag:ScheduleTimer ("SendPersona", 1)
627 end
628 end
629
630 return true
631 end
632
633 function NickTag:GetNickname (playerName, default, silent)
634 if (not silent) then
635 assert (type (playerName) == "string", "NickTag 'GetNickname' expects a string or string on #1 argument.")
636 end
637
638 local _table = pool [playerName]
639 if (not _table) then
640 return default or nil
641 end
642 return _table [CONST_INDEX_NICKNAME] or default or nil
643 end
644
645 --> return the avatar and the texcoord.
646 function NickTag:GetNicknameAvatar (playerName, default, silent)
647 if (not silent) then
648 assert (type (playerName) == "string", "NickTag 'GetNicknameAvatar' expects a string or string on #1 argument.")
649 end
650
651 local _table = pool [playerName]
652
653 if (not _table and default) then
654 return default, {0, 1, 0, 1}
655 elseif (not _table) then
656 return "", {0, 1, 0, 1}
657 end
658 return _table [CONST_INDEX_AVATAR_PATH] or default or "", _table [CONST_INDEX_AVATAR_TEXCOORD] or {0, 1, 0, 1}
659 end
660
661 function NickTag:GetNicknameBackground (playerName, default_path, default_texcoord, default_color, silent)
662 if (not silent) then
663 assert (type (playerName) == "string", "NickTag 'GetNicknameBackground' expects a string or string on #1 argument.")
664 end
665
666 local _table = pool [playerName]
667 if (not _table) then
668 return default_path, default_texcoord, default_color
669 end
670 return _table [CONST_INDEX_BACKGROUND_PATH] or default_path, _table [CONST_INDEX_BACKGROUND_TEXCOORD] or default_texcoord, _table [CONST_INDEX_BACKGROUND_COLOR] or default_color
671 end
672
673 --> get the full nicktag table
674 function NickTag:GetNicknameTable (playerName, silent)
675 --> check data before
676 if (not silent) then
677 assert (type (playerName) == "string", "NickTag 'GetNicknameTable' expects a string on #1 argument.")
678 else
679 if (not playerName or type (playerName) ~= "string") then
680 return
681 end
682 end
683
684 return pool [playerName]
685 end
686
687------------------------------------------------------------------------------------------------------------------------------------------------------
688--> internal functions
689
690 --> create a empty nick table for the player
691 function NickTag:Create (playerName, isSelf)
692 --> check data before
693 assert (type (playerName) == "string", "NickTag 'Create' expects a string on #1 argument.")
694
695 --> check if alredy exists
696 local alredyHave = pool [playerName]
697 if (alredyHave) then
698 return alredyHave
699 end
700
701 --> create the table:
702 local newTable = {
703 UnitName ("player"), --[1] player nickname
704 false, --[2] avatar texture path
705 false, --[3] avatar texture coord
706 false, --[4] background texture path
707 false, --[5] background texcoord
708 false, --[6] background color
709 1 --[7] revision
710 }
711
712 --> if not my persona, set revision to 0, this make always get update after creation
713 if (not isSelf) then
714 newTable [CONST_INDEX_REVISION] = 0
715 end
716
717 pool [playerName] = newTable
718 return newTable
719 end
720
721 --> inc the revision of the player persona after update nick or avatar
722 function NickTag:IncRevision()
723 local playerName = UnitName ("player")
724 local nickTable = NickTag:GetNicknameTable (playerName)
725 if (not nickTable) then
726 nickTable = NickTag:Create (playerName, true)
727 end
728
729 nickTable [CONST_INDEX_REVISION] = nickTable [CONST_INDEX_REVISION] + 1
730
731 return true
732 end
733
734 --> convert GUID into serial number (deprecated, it uses player name - realm name)
735 function NickTag:GetSerial (serial, silent)
736 return 0
737 end
738
739 --> choose avatar window
740do
741 local avatar_pick_frame = CreateFrame ("frame", "AvatarPickFrame", UIParent)
742 avatar_pick_frame:SetFrameStrata ("DIALOG")
743 avatar_pick_frame:SetBackdrop ({bgFile = [[Interface\FrameGeneral\UI-Background-Marble]], edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]], tile = true, tileSize = 256, edgeSize = 32, insets = {left = 11, right = 12, top = 12, bottom = 11}})
744 avatar_pick_frame:SetBackdropColor (.3, .3, .3, .9)
745 avatar_pick_frame:SetWidth (460)
746 avatar_pick_frame:SetHeight (240)
747
748 avatar_pick_frame.selected_avatar = 1
749 avatar_pick_frame.selected_background = 1
750 avatar_pick_frame.selected_color = {1, 1, 1}
751 avatar_pick_frame.selected_texcoord = {0, 1, 0, 1}
752
753 avatar_pick_frame:SetPoint ("center", UIParent, "center", 200, 0)
754 ---
755 local avatar_texture = avatar_pick_frame:CreateTexture ("AvatarPickFrameAvatarPreview", "overlay")
756 avatar_texture:SetPoint ("topleft", avatar_pick_frame, "topleft", 167, -10)
757 avatar_texture:SetTexture ([[Interface\EncounterJournal\UI-EJ-BOSS-Default]])
758 --
759 local background_texture = avatar_pick_frame:CreateTexture ("AvatarPickFrameBackgroundPreview", "artwork")
760 background_texture:SetPoint ("topleft", avatar_pick_frame, "topleft", 167, 2)
761 background_texture:SetWidth (290)
762 background_texture:SetHeight (75)
763 background_texture:SetTexture (NickTag.background_pool[1][1])
764 background_texture:SetTexCoord (unpack (NickTag.background_pool[1][3]))
765 --
766 local name = avatar_pick_frame:CreateFontString ("AvatarPickFrameName", "overlay", "GameFontHighlightHuge")
767 name:SetPoint ("left", avatar_texture, "right", -11, -17)
768 name:SetText (UnitName ("player"))
769 ---
770
771 local OnClickFunction = function (button)
772 if (button.isAvatar) then
773 local avatar = NickTag.avatar_pool [button.IconID]
774 _G.AvatarPickFrameAvatarPreview:SetTexture ( avatar [1] )
775 avatar_pick_frame.selected_avatar = avatar [1]
776 elseif (button.isBackground) then
777 local background = NickTag.background_pool [button.IconID]
778 _G.AvatarPickFrameBackgroundPreview:SetTexture ( background [1] )
779 _G.AvatarPickFrameBackgroundPreview:SetTexCoord (unpack (background [3]))
780 avatar_pick_frame.selected_background = background [1]
781 avatar_pick_frame.selected_texcoord = background [3]
782 end
783 end
784
785 local selectedColor = function()
786 local r, g, b = ColorPickerFrame:GetColorRGB()
787 background_texture:SetVertexColor (r, g, b)
788 avatar_pick_frame.selected_color[1] = r
789 avatar_pick_frame.selected_color[2] = g
790 avatar_pick_frame.selected_color[3] = b
791 end
792
793 local okey = CreateFrame ("button", "AvatarPickFrameAccept", avatar_pick_frame, "OptionsButtonTemplate")
794 okey:SetPoint ("bottomright", avatar_pick_frame, "bottomright", -37, 12)
795 okey:SetText ("Accept")
796 okey:SetFrameLevel (avatar_pick_frame:GetFrameLevel()+2)
797 okey:SetScript ("OnClick", function (self)
798 avatar_pick_frame:Hide()
799 if (avatar_pick_frame.callback) then
800 avatar_pick_frame.callback (avatar_pick_frame.selected_avatar, {0, 1, 0, 1}, avatar_pick_frame.selected_background, avatar_pick_frame.selected_texcoord, avatar_pick_frame.selected_color)
801 end
802 end)
803 local change_color = CreateFrame ("button", "AvatarPickFrameColor", avatar_pick_frame, "OptionsButtonTemplate")
804 change_color:SetPoint ("bottomright", avatar_pick_frame, "bottomright", -205, 12)
805 change_color:SetText ("Color")
806 change_color:SetFrameLevel (avatar_pick_frame:GetFrameLevel()+2)
807
808 change_color:SetScript ("OnClick", function (self)
809 ColorPickerFrame.func = selectedColor
810 ColorPickerFrame.hasOpacity = false
811 ColorPickerFrame:SetParent (avatar_pick_frame)
812 ColorPickerFrame:SetColorRGB (_G.AvatarPickFrameBackgroundPreview:GetVertexColor())
813 ColorPickerFrame:ClearAllPoints()
814 ColorPickerFrame:SetPoint ("left", avatar_pick_frame, "right", 0, -10)
815 ColorPickerFrame:Show()
816 end)
817
818 local buttons = {}
819 for i = 0, 2 do
820 local newbutton = CreateFrame ("button", "AvatarPickFrameAvatarScrollButton"..i+1, avatar_pick_frame)
821 newbutton:SetScript ("OnClick", OnClickFunction)
822 newbutton:SetWidth (128)
823 newbutton:SetHeight (64)
824 newbutton:SetPoint ("topleft", avatar_pick_frame, "topleft", 15, (i*70*-1) - 20)
825 newbutton:SetID (i+1)
826 newbutton.isAvatar = true
827 buttons [#buttons+1] = newbutton
828 end
829
830 local buttonsbg = {}
831 for i = 0, 2 do
832 local newbutton = CreateFrame ("button", "AvatarPickFrameBackgroundScrollButton"..i+1, avatar_pick_frame)
833 newbutton:SetScript ("OnClick", OnClickFunction)
834 newbutton:SetWidth (275)
835 newbutton:SetHeight (60)
836 newbutton:SetPoint ("topleft", avatar_pick_frame, "topleft", 157, (i*50*-1) - 80)
837 newbutton:SetID (i+1)
838 newbutton.isBackground = true
839 buttonsbg [#buttonsbg+1] = newbutton
840 end
841
842 local avatar_list = CreateFrame ("ScrollFrame", "AvatarPickFrameAvatarScroll", avatar_pick_frame, "ListScrollFrameTemplate")
843 avatar_list:SetPoint ("topleft", avatar_pick_frame, "topleft", 10, -10)
844 local background_list = CreateFrame ("ScrollFrame", "AvatarPickFrameBackgroundScroll", avatar_pick_frame, "ListScrollFrameTemplate")
845 background_list:SetPoint ("topleft", avatar_pick_frame, "topleft", 147, -85)
846
847 avatar_list:SetWidth (128)
848 avatar_list:SetHeight (220)
849 background_list:SetWidth (275)
850 background_list:SetHeight (140)
851
852 local avatar_scroll_update = function (self)
853 local numMacroIcons = #NickTag.avatar_pool
854 local macroPopupIcon, macroPopupButton, index, texture
855 local macroPopupOffset = FauxScrollFrame_GetOffset (avatar_list)
856
857 for i = 1, 3 do
858 macroPopupIcon = _G ["AvatarPickFrameAvatarScrollButton"..i]
859 macroPopupButton = _G ["AvatarPickFrameAvatarScrollButton"..i]
860 index = (macroPopupOffset * 1) + i
861
862 texture = NickTag.avatar_pool [index][1]
863 if ( index <= numMacroIcons and texture ) then
864 macroPopupButton:SetNormalTexture (texture)
865 macroPopupButton:SetPushedTexture (texture)
866 macroPopupButton:SetDisabledTexture (texture)
867 macroPopupButton:SetHighlightTexture (texture, "ADD")
868 macroPopupButton.IconID = index
869 macroPopupButton:Show()
870 else
871 macroPopupButton:Hide()
872 end
873 end
874 FauxScrollFrame_Update (avatar_list, numMacroIcons , 3, 64)
875 end
876 local background_scroll_update = function (self)
877 local numMacroIcons = #NickTag.background_pool
878 local macroPopupIcon, macroPopupButton, index, texture
879 local macroPopupOffset = FauxScrollFrame_GetOffset (background_list)
880
881 for i = 1, 3 do
882 macroPopupIcon = _G ["AvatarPickFrameBackgroundScrollButton"..i]
883 macroPopupButton = _G ["AvatarPickFrameBackgroundScrollButton"..i]
884 index = (macroPopupOffset * 1) + i
885
886 texture = NickTag.background_pool [index][1]
887 if ( index <= numMacroIcons and texture ) then
888 macroPopupButton:SetNormalTexture (texture)
889 macroPopupButton:SetPushedTexture (texture)
890 macroPopupButton:SetDisabledTexture (texture)
891 macroPopupButton:SetHighlightTexture (texture, "ADD")
892 macroPopupButton.IconID = index
893 macroPopupButton:Show()
894 else
895 macroPopupButton:Hide()
896 end
897 end
898 FauxScrollFrame_Update (background_list, numMacroIcons , 3, 40)
899 end
900
901 avatar_list:SetScript ("OnVerticalScroll", function (self, offset)
902 FauxScrollFrame_OnVerticalScroll (avatar_list, offset, 64, avatar_scroll_update)
903 end)
904 background_list:SetScript ("OnVerticalScroll", function (self, offset)
905 FauxScrollFrame_OnVerticalScroll (background_list, offset, 40, background_scroll_update)
906 end)
907
908 avatar_scroll_update (avatar_list)
909 background_scroll_update (background_list)
910
911 function avatar_pick_frame:SetAvatar (n)
912 if (type (n) ~= "number") then
913 n = 1
914 end
915 if (n > #NickTag.avatar_pool) then
916 n = 1
917 end
918 local avatar = NickTag.avatar_pool [n]
919 _G.AvatarPickFrameAvatarPreview:SetTexture ( avatar [1] )
920 avatar_pick_frame.selected_avatar = avatar [1]
921 end
922 function avatar_pick_frame:SetBackground (n)
923 if (type (n) ~= "number") then
924 n = 1
925 end
926 if (n > #NickTag.background_pool) then
927 n = 1
928 end
929 local background = NickTag.background_pool [n]
930 _G.AvatarPickFrameBackgroundPreview:SetTexture ( background [1] )
931 _G.AvatarPickFrameBackgroundPreview:SetTexCoord (unpack (background [3]))
932 _G.AvatarPickFrameBackgroundPreview:SetVertexColor (unpack (avatar_pick_frame.selected_color))
933 avatar_pick_frame.selected_background = background [1]
934 end
935 function avatar_pick_frame:SetColor (r, g, b)
936 if (type (r) ~= "number" or r > 1) then
937 r = 1
938 end
939 if (type (g) ~= "number" or g > 1) then
940 g = 1
941 end
942 if (type (b) ~= "number" or b > 1) then
943 b = 1
944 end
945 _G.AvatarPickFrameBackgroundPreview:SetVertexColor (r, g, b)
946 avatar_pick_frame.selected_color[1] = r
947 avatar_pick_frame.selected_color[2] = g
948 avatar_pick_frame.selected_color[3] = b
949 end
950
951 local CONST_INDEX_NICKNAME = 1
952 local CONST_INDEX_AVATAR_PATH = 2
953 local CONST_INDEX_AVATAR_TEXCOORD = 3
954 local CONST_INDEX_BACKGROUND_PATH = 4
955 local CONST_INDEX_BACKGROUND_TEXCOORD = 5
956 local CONST_INDEX_BACKGROUND_COLOR = 6
957
958 avatar_pick_frame:SetScript ("OnShow", function()
959 --get player avatar
960 local avatar = NickTag:GetNicknameTable (UnitGUID ("player"))
961 if (avatar) then
962 _G.AvatarPickFrameName:SetText ( avatar [1] or UnitName ("player"))
963
964 _G.AvatarPickFrameAvatarPreview:SetTexture ( avatar [CONST_INDEX_AVATAR_PATH] or [[Interface\EncounterJournal\UI-EJ-BOSS-Default]] )
965 avatar_pick_frame.selected_avatar = avatar [CONST_INDEX_AVATAR_PATH] or [[Interface\EncounterJournal\UI-EJ-BOSS-Default]]
966
967 _G.AvatarPickFrameAvatarPreview:SetTexCoord ( 0, 1, 0, 1 ) --> always
968
969 _G.AvatarPickFrameBackgroundPreview:SetTexture ( avatar [CONST_INDEX_BACKGROUND_PATH] or [[Interface\PetBattles\Weather-ArcaneStorm]] )
970 avatar_pick_frame.selected_background = avatar [CONST_INDEX_BACKGROUND_PATH] or [[Interface\PetBattles\Weather-ArcaneStorm]]
971
972 if (avatar [CONST_INDEX_BACKGROUND_TEXCOORD]) then
973 _G.AvatarPickFrameBackgroundPreview:SetTexCoord ( unpack (avatar [CONST_INDEX_BACKGROUND_TEXCOORD]) )
974 avatar_pick_frame.selected_texcoord = avatar [CONST_INDEX_BACKGROUND_TEXCOORD]
975 else
976 _G.AvatarPickFrameBackgroundPreview:SetTexCoord ( 0.129609375, 1, 1, 0 )
977 avatar_pick_frame.selected_texcoord = {0.129609375, 1, 1, 0}
978 end
979
980 if (avatar [CONST_INDEX_BACKGROUND_COLOR]) then
981 _G.AvatarPickFrameBackgroundPreview:SetVertexColor ( unpack (avatar [CONST_INDEX_BACKGROUND_COLOR]) )
982 avatar_pick_frame.selected_color = avatar [CONST_INDEX_BACKGROUND_COLOR]
983 else
984 _G.AvatarPickFrameBackgroundPreview:SetVertexColor ( 1, 1, 1 )
985 avatar_pick_frame.selected_color = {1, 1, 1}
986 end
987 else
988 --> if none
989 _G.AvatarPickFrameAvatarPreview:SetTexture ( [[Interface\EncounterJournal\UI-EJ-BOSS-Default]] )
990 avatar_pick_frame.selected_avatar = [[Interface\EncounterJournal\UI-EJ-BOSS-Default]]
991
992 local background = NickTag.background_pool [1]
993
994 if (background) then
995 _G.AvatarPickFrameBackgroundPreview:SetTexture ( background [1] )
996 avatar_pick_frame.selected_background = background [1]
997 _G.AvatarPickFrameBackgroundPreview:SetTexCoord (unpack (background [3]))
998 avatar_pick_frame.selected_texcoord = background [3]
999 _G.AvatarPickFrameBackgroundPreview:SetVertexColor (unpack (avatar_pick_frame.selected_color))
1000 avatar_pick_frame.selected_color = avatar_pick_frame.selected_color
1001 end
1002
1003 end
1004 end)
1005
1006 avatar_pick_frame:Hide()
1007end