Advertisement
Guest User

NickTag-1.0.lua

a guest
Jan 22nd, 2020
1,813
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 43.01 KB | None | 0 0
  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.  
  7. local major, minor = "NickTag-1.0", 11
  8. local NickTag, oldminor = LibStub:NewLibrary (major, minor)
  9.  
  10. if (not NickTag) then
  11.     return
  12. end
  13.  
  14. --> fix for old nicktag version
  15. if (_G.NickTag) then
  16.     if (_G.NickTag.OnEvent) then
  17.         _G.NickTag:UnregisterComm ("NickTag")
  18.         _G.NickTag.OnEvent = nil
  19.     end
  20. end
  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.     local siblingsPools = {} --> pools registered by other addons
  46.     --when this instance was the first to load
  47.     local isMaster = false
  48.  
  49.     NickTag.debug = false
  50.  
  51.     LibStub:GetLibrary ("AceComm-3.0"):Embed (NickTag)
  52.     LibStub:GetLibrary ("AceSerializer-3.0"):Embed (NickTag)
  53.     LibStub:GetLibrary ("AceTimer-3.0"):Embed (NickTag)
  54.     local CallbackHandler = LibStub:GetLibrary ("CallbackHandler-1.0")
  55.     NickTag.callbacks = NickTag.callbacks or CallbackHandler:New (NickTag)
  56.    
  57.     NickTag.embeds = NickTag.embeds or {}
  58.     local embed_functions = {
  59.         "SetNickname",
  60.         "SetNicknameAvatar",
  61.         "SetNicknameBackground",
  62.         "GetNickname",
  63.         "GetNicknameAvatar",
  64.         "GetNicknameBackground",
  65.         "GetNicknameTable",
  66.         "NickTagSetCache",
  67.         "ResetPlayerPersona"
  68.     }
  69.     function NickTag:Embed (target)
  70.         for k, v in pairs (embed_functions) do
  71.             target[v] = self[v]
  72.         end
  73.         self.embeds [target] = true
  74.         return target
  75.     end
  76.    
  77.     function NickTag:Msg (...)
  78.         if (NickTag.debug) then
  79.             print ("|cFFFFFF00NickTag:|r", ...)
  80.         end
  81.     end
  82.    
  83.     local enUS = LibStub("AceLocale-3.0"):NewLocale ("NickTag-1.0", "enUS", true)
  84.     if (enUS) then
  85.         enUS ["STRING_ERROR_1"] = "Your nickname is too long, max of 12 characters is allowed."
  86.         enUS ["STRING_ERROR_2"] = "Only letters and two spaces are allowed."
  87.         enUS ["STRING_ERROR_3"] = "You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."
  88.         enUS ["STRING_ERROR_4"] = "Name isn't a valid string."
  89.         enUS ["STRING_INVALID_NAME"] = "Invalid Name"
  90.     end
  91.    
  92.     local ptBR = LibStub("AceLocale-3.0"):NewLocale ("NickTag-1.0", "ptBR")
  93.     if (ptBR) then
  94.         ptBR ["STRING_ERROR_1"] = "Seu apelido esta muito longo, o maximo permitido sao 12 caracteres."
  95.         ptBR ["STRING_ERROR_2"] = "Apenas letras, numeros e espacos sao permitidos no apelido."
  96.         ptBR ["STRING_ERROR_3"] = "Voce nao pode usar a mesma letra mais de 2 vezes consecutivas, dois espacos consecutivos ou mais de 2 espacos."
  97.         ptBR ["STRING_ERROR_4"] = "Nome nao eh uma string valida."
  98.         ptBR ["STRING_INVALID_NAME"] = "Nome Invalido"
  99.     end
  100.    
  101.     NickTag.background_pool = {
  102.         {[[Interface\PetBattles\Weather-ArcaneStorm]], "Arcane Storm", {0.129609375, 1, 1, 0}},
  103.         {[[Interface\PetBattles\Weather-Blizzard]], "Blizzard", {0.068704154, 1, 1, 0}},
  104.         {[[Interface\PetBattles\Weather-BurntEarth]], "Burnt Earth", {0.087890625, 0.916015625, 1, 0}},
  105.         {[[Interface\PetBattles\Weather-Darkness]], "Darkness", {0.080078125, 0.931640625, 1, 0}},
  106.         {[[Interface\PetBattles\Weather-Moonlight]], "Moonlight", {0.02765625, 0.94359375, 1, 0}},
  107.         {[[Interface\PetBattles\Weather-Moonlight]], "Moonlight (reverse)", {0.94359375, 0.02765625, 1, 0}},
  108.         {[[Interface\PetBattles\Weather-Mud]], "Mud", {0.068359375, 0.94359375, 1, 0}},
  109.         {[[Interface\PetBattles\Weather-Rain]], "Rain", {0.078125, 0.970703125, 1, 0}},
  110.         {[[Interface\PetBattles\Weather-Sandstorm]], "Sand Storm", {0.048828125, 0.947265625, 1, 0}},
  111.         {[[Interface\PetBattles\Weather-StaticField]], "Static Field", {0.1171875, 0.953125, 1, 0}},
  112.         {[[Interface\PetBattles\Weather-Sunlight]], "Sun Light", {0.1772721, 0.953125, 1, 0}},
  113.         {[[Interface\PetBattles\Weather-Windy]], "Windy", {0.9453125, 0.07421875, 0.8203125, 0}}
  114.     }
  115.    
  116.     NickTag.avatar_pool = {
  117.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Arcanist Doan]], "Arcanist Doan"},
  118.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Archbishop Benedictus]], "Archbishop Benedictus"},
  119.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Argent Confessor Paletress]], "Argent Confessor Paletress"},
  120.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Armsmaster Harlan]], "Armsmaster Harlan"},
  121.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Asira Dawnslayer]], "Asira Dawnslayer"},
  122.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Baelog]], "Baelog"},
  123.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Baron Ashbury]], "Baron Ashbury"},
  124.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Baron Silverlaine]], "Baron Silverlaine"},
  125.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Blood Guard Porung]], "Blood Guard Porung"},
  126.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Bronjahm]], "Bronjahm"},
  127.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Brother Korloff]], "Brother Korloff"},
  128.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Captain Skarloc]], "Captain Skarloc"},
  129.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Chief Ukorz Sandscalp]], "Chief Ukorz Sandscalp"},
  130.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Kolurg]], "Commander Kolurg"},
  131.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Malor]], "Commander Malor"},
  132.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Sarannis]], "Commander Sarannis"},
  133.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Springvale]], "Commander Springvale"},
  134.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Commander Stoutbeard]], "Commander Stoutbeard"},
  135.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Corla, Herald of Twilight]], "Corla, Herald of Twilight"},
  136.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Cyanigosa]], "Cyanigosa"},
  137.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Darkmaster Gandling]], "Darkmaster Gandling"},
  138.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Doctor Theolen Krastinov]], "Doctor Theolen Krastinov"},
  139.         {[[Interface\EncounterJournal\UI-EJ-BOSS-DoomRel]], "DoomRel"},
  140.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Eadric the Pure]], "Eadric the Pure"},
  141.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Emperor Thaurissan]], "Emperor Thaurissan"},
  142.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Empyreal Queens]], "Lu'lin"},
  143.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Exarch Maladaar]], "Exarch Maladaar"},
  144.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Fineous Darkvire]], "Fineous Darkvire"},
  145.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Galdarah]], "Galdarah"},
  146.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Garajal the Spiritbinder]], "Garajal the Spiritbinder"},
  147.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Garrosh Hellscream]], "Garrosh Hellscream"},
  148.         {[[Interface\EncounterJournal\UI-EJ-BOSS-General Nazgrim]], "General Nazgrim"},
  149.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Champions-Alliance]], "Grand Champions-Alliance"},
  150.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Champions-Horde]], "Grand Champions-Horde"},
  151.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Grand Magus Telestra]], "Grand Magus Telestra"},
  152.         {[[Interface\EncounterJournal\UI-EJ-BOSS-HateRel]], "HateRel"},
  153.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Hazzarah]], "Hazzarah"},
  154.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Hearthsinger Forresten]], "Hearthsinger Forresten"},
  155.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Helix Gearbreaker]], "Helix Gearbreaker"},
  156.         {[[Interface\EncounterJournal\UI-EJ-BOSS-High Botanist Freywinn]], "High Botanist Freywinn"},
  157.         {[[Interface\EncounterJournal\UI-EJ-BOSS-High Inquisitor Whitemane]], "High Inquisitor Whitemane"},
  158.         {[[Interface\EncounterJournal\UI-EJ-BOSS-High Interrogator Gerstahn]], "High Interrogator Gerstahn"},
  159.         {[[Interface\EncounterJournal\UI-EJ-BOSS-High Justice Grimstone]], "High Justice Grimstone"},
  160.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Houndmaster Braun]], "Houndmaster Braun"},
  161.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Houndmaster Loksey]], "Houndmaster Loksey"},
  162.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Hydromancer Velratha]], "Hydromancer Velratha"},
  163.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Illyanna Ravenoak]], "Illyanna Ravenoak"},
  164.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Ingvar the Plunderer]], "Ingvar the Plunderer"},
  165.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Instructor Galford]], "Instructor Galford"},
  166.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Instructor Malicia]], "Instructor Malicia"},
  167.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Interrogator Vishas]], "Interrogator Vishas"},
  168.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Isiset]], "Isiset"},
  169.         {[[Interface\EncounterJournal\UI-EJ-BOSS-JainaProudmoore]], "Jaina Proudmoore"},
  170.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Jandice Barov]], "Jandice Barov"},
  171.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Kaelthas Sunstrider]], "Kaelthas Sunstrider"},
  172.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Kelidan the Breaker]], "Kelidan the Breaker"},
  173.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Krick]], "Krick"},
  174.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lady Anacondra]], "Lady Anacondra"},
  175.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lady Illucia Barov]], "Lady Illucia Barov"},
  176.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lethtendris]], "Lethtendris"},
  177.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Loken]], "Loken"},
  178.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Alexei Barov]], "Lord Alexei Barov"},
  179.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Aurius Rivendare]], "Lord Aurius Rivendare"},
  180.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Cobrahn]], "Lord Cobrahn"},
  181.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Pythas]], "Lord Pythas"},
  182.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lord Serpentis]], "Lord Serpentis"},
  183.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Lorgus Jett]], "Lorgus Jett"},
  184.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Mage Lord Urom]], "Mage Lord Urom"},
  185.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Magister Kalendris]], "Magister Kalendris"},
  186.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Magistrate Barthilas]], "Magistrate Barthilas"},
  187.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Maiden of Grief]], "Maiden of Grief"},
  188.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Maleki the Pallid]], "Maleki the Pallid"},
  189.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Nethermancer Sepethrea]], "Nethermancer Sepethrea"},
  190.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Olaf]], "Olaf"},
  191.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Pathaleon the Calculator]], "Pathaleon the Calculator"},
  192.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Prince Tortheldrin]], "Prince Tortheldrin"},
  193.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Princess Moira Bronzebeard]], "Princess Moira Bronzebeard"},
  194.         {[[Interface\EncounterJournal\UI-EJ-BOSS-QueenAzshara]], "Queen Azshara"},
  195.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Randolph Moloch]], "Randolph Moloch"},
  196.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Renataki]], "Renataki"},
  197.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Ribbly Screwspigot]], "Ribbly Screwspigot"},
  198.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Scarlet Commander Mograine]], "Scarlet Commander Mograine"},
  199.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Selin Fireheart]], "Selin Fireheart"},
  200.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Siegecrafter Blackfuse]], "Siegecrafter Blackfuse"},
  201.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Skarvald the Constructor]], "Skarvald the Constructor"},
  202.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Tribunal of the Ages]], "Tribunal of the Ages"},
  203.         {[[Interface\EncounterJournal\UI-EJ-BOSS-TyrandeWhisperwind]], "Tyrande Whisperwind"},
  204.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Twilight Lord Kelris]], "Twilight Lord Kelris"},
  205.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Vanessa VanCleef]], "Vanessa VanCleef"},
  206.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Vazruden]], "Vazruden"},
  207.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Warchief Rend Blackhand]], "Warchief Rend Blackhand"},
  208.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Willey Hopebreaker]], "Willey Hopebreaker"},
  209.         {[[Interface\EncounterJournal\UI-EJ-BOSS-Witch Doctor Zumrah]], "Witch Doctor Zumrah"},
  210.     }
  211. ------------------------------------------------------------------------------------------------------------------------------------------------------
  212. --> send and receive functions
  213.  
  214.     function NickTag:OnReceiveComm (prefix, data, channel, source)
  215.    
  216.         if (not source) then
  217.             return
  218.         end
  219.    
  220.         local _type, serial, arg3, name, realm, version =  select (2, NickTag:Deserialize (data))
  221.  
  222.         --> 0x1: received a full persona
  223.         if (_type == CONST_COMM_FULLPERSONA) then
  224.             local receivedPersona = arg3
  225.             version = name
  226.            
  227.             if (not receivedPersona or type (receivedPersona) ~= "table") then
  228.                 NickTag:Msg ("FULLPERSONA received but it's invalid ", source)
  229.                 return
  230.             end
  231.            
  232.             if (source ~= UnitName ("player") and (version and version == minor) and receivedPersona) then
  233.  
  234.                 local storedPersona = NickTag:GetNicknameTable (source)
  235.                 if (not storedPersona) then
  236.                     storedPersona = NickTag:Create (source)
  237.                 end
  238.                
  239.                 storedPersona [CONST_INDEX_REVISION] = receivedPersona [CONST_INDEX_REVISION]
  240.                
  241.                 --> we need to check if the received nickname fit in our rules.
  242.                 local allowNickName = NickTag:CheckName (receivedPersona [CONST_INDEX_NICKNAME])
  243.                 if (allowNickName) then
  244.                     storedPersona [CONST_INDEX_NICKNAME] = receivedPersona [CONST_INDEX_NICKNAME]
  245.                 else
  246.                     storedPersona [CONST_INDEX_NICKNAME] = LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_INVALID_NAME"]
  247.                 end
  248.                
  249.                 storedPersona [CONST_INDEX_NICKNAME] = receivedPersona [CONST_INDEX_NICKNAME]
  250.                
  251.                 --> update the rest
  252.                 --avatar path
  253.                 storedPersona [CONST_INDEX_AVATAR_PATH] = type (receivedPersona [CONST_INDEX_AVATAR_PATH]) == "string" and receivedPersona [CONST_INDEX_AVATAR_PATH] or ""
  254.                
  255.                 --avatar texcoord
  256.                 if (type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD]) == "boolean") then
  257.                     storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = {0, 1, 0, 1}
  258.                    
  259.                 elseif (type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD]) == "table") then
  260.                     storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = storedPersona [CONST_INDEX_AVATAR_TEXCOORD] or {}
  261.                     storedPersona [CONST_INDEX_AVATAR_TEXCOORD][1] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][1]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][1] or 0
  262.                     storedPersona [CONST_INDEX_AVATAR_TEXCOORD][2] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][2]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][2] or 1
  263.                     storedPersona [CONST_INDEX_AVATAR_TEXCOORD][3] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][3]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][3] or 0
  264.                     storedPersona [CONST_INDEX_AVATAR_TEXCOORD][4] = type (receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][4]) == "number" and receivedPersona [CONST_INDEX_AVATAR_TEXCOORD][4] or 1
  265.                 else
  266.                     storedPersona [CONST_INDEX_AVATAR_TEXCOORD] = {0, 1, 0, 1}
  267.                 end
  268.                
  269.                 --background texcoord
  270.                 if (type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD]) == "boolean") then
  271.                     storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = {0, 1, 0, 1}
  272.                    
  273.                 elseif (type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD]) == "table") then
  274.                     storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] or {}
  275.                     storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][1] or 0
  276.                     storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][2] or 1
  277.                     storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][3] or 0
  278.                     storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4] = type (receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_TEXCOORD][4] or 1
  279.                 else
  280.                     storedPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = {0, 1, 0, 1}
  281.                 end                    
  282.                
  283.                 --background path
  284.                 storedPersona [CONST_INDEX_BACKGROUND_PATH] = type (receivedPersona [CONST_INDEX_BACKGROUND_PATH]) == "string" and receivedPersona [CONST_INDEX_BACKGROUND_PATH] or ""
  285.                
  286.                 --background color
  287.                 if (type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR]) == "table") then
  288.                     storedPersona [CONST_INDEX_BACKGROUND_COLOR] = storedPersona [CONST_INDEX_BACKGROUND_COLOR] or {}
  289.                     storedPersona [CONST_INDEX_BACKGROUND_COLOR][1] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][1]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][1] or 1
  290.                     storedPersona [CONST_INDEX_BACKGROUND_COLOR][2] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][2]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][2] or 1
  291.                     storedPersona [CONST_INDEX_BACKGROUND_COLOR][3] = type (receivedPersona [CONST_INDEX_BACKGROUND_COLOR][3]) == "number" and receivedPersona [CONST_INDEX_BACKGROUND_COLOR][3] or 1
  292.                 else
  293.                     storedPersona [CONST_INDEX_BACKGROUND_COLOR] = {1, 1, 1}
  294.                 end
  295.                
  296.                 NickTag:SyncSiblings()
  297.                 NickTag:Msg ("FULLPERSONA received and updated for character: ", source, "new nickname: ", receivedPersona [CONST_INDEX_NICKNAME])
  298.             end
  299.  
  300.         end
  301.  
  302.     end
  303.  
  304.     NickTag:RegisterComm ("NickTag", "OnReceiveComm")
  305.    
  306.     --frame for listening to event
  307.     NickTag.EventFrame = NickTag.EventFrame or CreateFrame ("frame")
  308.     NickTag.EventFrame.InfoSendCooldown = 0
  309.    
  310.     function NickTag.OnEvent (self, event, ...)
  311.         if (NickTag.EventFrame.InfoSendCooldown > time()) then
  312.             if (not NickTag.EventFrame.ScheduledSend or NickTag.EventFrame.ScheduledSend._cancelled) then
  313.                 NickTag.EventFrame.ScheduledSend = C_Timer.NewTimer (30, NickTag.SendPersona)
  314.             end
  315.         else
  316.             NickTag:SendPersona()
  317.         end
  318.     end
  319.    
  320.     --when the roster changes or the player enters the game, send the persona to guild mates
  321.     --send on roster update can only happen every 30 seconds, if is on cooldown, it'll schedule an update
  322.     NickTag.EventFrame:RegisterEvent ("GROUP_ROSTER_UPDATE")
  323.     NickTag.EventFrame:RegisterEvent ("PLAYER_LOGIN")
  324.    
  325.     NickTag.EventFrame:SetScript ("OnEvent", NickTag.OnEvent)
  326.  
  327.     --send the persona in the guild comm chanel
  328.     function NickTag:SendPersona()
  329.  
  330.         --check if the player has a persona
  331.         local nickTable = NickTag:GetNicknameTable (UnitName ("player"), true)
  332.         if (not nickTable) then
  333.             return
  334.         end
  335.         NickTag:Msg ("SendPersona() -> broadcast")
  336.        
  337.         if (NickTag.EventFrame.ScheduledSend and not NickTag.EventFrame.ScheduledSend._cancelled) then
  338.             NickTag.EventFrame.ScheduledSend:Cancel()
  339.         end
  340.         NickTag.EventFrame.ScheduledSend = nil
  341.         NickTag.EventFrame.InfoSendCooldown = time() + 29
  342.        
  343.         --> updating my own persona
  344.         NickTag.send_scheduled = false
  345.        
  346.         --> auto change nickname if we have an invalid nickname
  347.         if (NickTag:GetNickname (UnitName ("player")) == LibStub ("AceLocale-3.0"):GetLocale ("NickTag-1.0")["STRING_INVALID_NAME"]) then
  348.             nickTable [CONST_INDEX_NICKNAME] = UnitName ("player")
  349.         end
  350.  
  351.         --> broadcast over all channels
  352.             NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_FULLPERSONA, 0, NickTag:GetNicknameTable (UnitName ("player")), minor), "PARTY")
  353.         NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_FULLPERSONA, 0, NickTag:GetNicknameTable (UnitName ("player")), minor), "RAID")
  354.         NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_FULLPERSONA, 0, NickTag:GetNicknameTable (UnitName ("player")), minor), "GUILD")
  355.         NickTag:SendCommMessage ("NickTag", NickTag:Serialize (CONST_COMM_FULLPERSONA, 0, NickTag:GetNicknameTable (UnitName ("player")), minor), "BATTLEGROUND")
  356.  
  357.     end
  358.  
  359. ------------------------------------------------------------------------------------------------------------------------------------------------------
  360. --> cache stuff
  361.  
  362.     --> this will clear the information about the player within nicktag cache
  363.     function NickTag:ResetPlayerPersona()
  364.         local playerName = UnitName ("player")
  365.        
  366.         if (playerName) then
  367.             local playerPersona = NickTag:GetNicknameTable (playerName)
  368.             if (playerPersona) then
  369.                 playerPersona [CONST_INDEX_NICKNAME] = playerName
  370.                 playerPersona [CONST_INDEX_AVATAR_PATH] = false
  371.                 playerPersona [CONST_INDEX_AVATAR_TEXCOORD] = false
  372.                 playerPersona [CONST_INDEX_BACKGROUND_PATH] = false
  373.                 playerPersona [CONST_INDEX_BACKGROUND_TEXCOORD] = false
  374.                 playerPersona [CONST_INDEX_BACKGROUND_COLOR] = false
  375.                 playerPersona [CONST_INDEX_REVISION] = playerPersona [CONST_INDEX_REVISION] + 1
  376.                
  377.                 C_Timer.After (1, NickTag.SendPersona)
  378.             end
  379.         end
  380.     end
  381.    
  382.     --> reset cache
  383.     function NickTag:ResetCache()
  384.    
  385.         local playerName = UnitName ("player")
  386.        
  387.         if (playerName) then
  388.             local player = NickTag:GetNicknameTable (playerName)
  389.             if (player and pool.last_version == minor) then
  390.                 for thisPlayerName, _ in pairs (pool) do
  391.                     if (thisPlayerName ~= playerName) then
  392.                         pool [thisPlayerName] = nil
  393.                     end
  394.                 end
  395.                 --vardump (pool)
  396.             else
  397.                 table.wipe (pool)
  398.             end
  399.            
  400.             pool.nextreset = time() + (60*60*24*15) --> 15 days or 1296000 seconds
  401.             pool.last_version = minor
  402.         else
  403.             --> sometimes player guid isn't available right after logon, so, just schedule until it become available.
  404.             NickTag:ScheduleTimer ("ResetCache", 0.3)
  405.         end
  406.     end
  407.    
  408.     --register a table where data can be saved
  409.     function NickTag:NickTagSetCache (_table)
  410.         if (not pool.default) then
  411.             --already have a place to save
  412.             --save the new table as sibling
  413.             --so all addons using nicktag can have the data synchronized
  414.             siblingsPools [#siblingsPools + 1] = _table
  415.  
  416.             --copy all players into the sibling table
  417.             for key, value in pairs (pool) do
  418.                 _table [key] = value
  419.             end
  420.  
  421.             return
  422.         end
  423.        
  424.         pool = _table
  425.         isMaster = true --> this instance of nicktag will save data
  426.        
  427.         if (not pool.nextreset) then
  428.             pool.nextreset = time() + (60*60*24*15)
  429.         end
  430.         if (not pool.last_version) then
  431.             pool.last_version = minor
  432.         end
  433.         if (pool.last_version < minor) then
  434.             pool.nextreset = 1
  435.         end
  436.         if (time() > pool.nextreset) then
  437.             NickTag:ResetCache()
  438.         end
  439.     end
  440.  
  441.     function NickTag:SyncSiblings()
  442.         --copy all data into siblings table
  443.         for _, syblingTable in ipairs (siblingsPools) do
  444.             for key, value in pairs (pool) do
  445.                 syblingTable [key] = value
  446.             end
  447.         end
  448.     end
  449.  
  450. ------------------------------------------------------------------------------------------------------------------------------------------------------
  451. --> basic functions
  452.  
  453.     --> trim from from http://lua-users.org/wiki/StringTrim
  454.     function trim (s)
  455.         local from = s:match"^%s*()"
  456.         return from > #s and "" or s:match(".*%S", from)
  457.     end
  458.     --
  459.     local titlecase = function (first, rest)
  460.         return first:upper()..rest:lower()
  461.     end
  462.     --
  463.     local have_repeated = false
  464.     local count_spaces = 0
  465.     local check_repeated = function (char)
  466.         if (char == "  ") then
  467.             have_repeated = true
  468.         elseif (string.len (char) > 2) then
  469.             have_repeated = true
  470.         elseif (char == " ") then
  471.             count_spaces = count_spaces + 1
  472.         end
  473.     end
  474.  
  475.    
  476.     --> we need to keep game smooth checking and formating nicknames.
  477.     --> SetNickname and names comming from other player need to be check.
  478.     function NickTag:CheckName (name)
  479.         return true
  480.     end
  481.  
  482.     --> set the "player" nickname and schedule for send updated persona
  483.     function NickTag:SetNickname (name)
  484.    
  485.         --> check data before
  486.         assert (type (name) == "string", "NickTag 'SetNickname' expects a string on #1 argument.")
  487.        
  488.         --> check if the nickname is okey to allowed to use.
  489.         local okey, errortype = NickTag:CheckName (name)
  490.         if (not okey) then
  491.             NickTag:Msg ("SetNickname() invalid name ", name)
  492.             return false, errortype
  493.         end
  494.        
  495.         --> here we format the text to match titles, e.g converts name like "JASON NICKSHOW" into "Jason Nickshow".
  496.         name = name:gsub ("(%a)([%w_']*)", titlecase)
  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
  740. do
  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()
  1007. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement