--------------------------------------------------------------------------------------- -- NxSocial - Social Window (friends, guild) -- Copyright 2007-2012 Carbon Based Creations, LLC --------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------- -- Carbonite - Addon for World of Warcraft(tm) -- Copyright 2007-2012 Carbon Based Creations, LLC -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. --------------------------------------------------------------------------------------- -------- -- Init function Nx.Social:Init() self.List.Sorted = {} local opts = Nx:GetGlobalOpts() self.GOpts = opts if opts["SocialEnable"] then -- Nx.prt ("SocialEnable") local ff = FriendsFrame GetUIPanelWidth (ff) ff:SetAttribute ("UIPanelLayout-enabled", false) hooksecurefunc ("PanelTemplates_SetTab", Nx.Social.PanelTemplates_SetTab) end self.Punks = Nx:GetSocial ("Pk") self.PunksActive = Nx:GetSocial ("PkAct") for k, v in pairs (self.PunksActive) do if not (v.MId and v.X and v.Y and v.Time) then -- Munge changed? Nx:ClearSocial ("PkAct") self.PunksActive = Nx:GetSocial ("PkAct") break end end self.PunkNewDir = 0 self.PunksHUD:Create() self.TeamHUD:Create() -- TEST!! -- self.HookOrig = FriendsFrame_ShowSubFrame -- FriendsFrame_ShowSubFrame = self.Hook end --[[ function Nx.Social.Hook (v) Nx.prt ("HOOK %s", v) Nx.Social.HookOrig (v) Nx.prtFrame ("GuildFrame", GuildFrame) end --]] function Nx.Social:ShowUIPanel (frame) if not GameMenuFrame:IsShown() and not self.NoShow then if self.InOnTabBar then return end -- Nx.prtFrame ("FF", frame) if InCombatLockdown() and(GetNumGroupMembers()>0 or _G["RaidGroupFrame_Update"]) then return end -- Nx.prt ("Social:ShowUIPanel %s", debugstack (2, 3, 0)) -- if IsAltKeyDown() then -- return -- end -- Nx.prt ("Social:ShowUIPanel") self.NoShow = true self:Create() local win = self.Win local wf = win.Frm wf:Raise() if not win:IsShown() then -- Toggle off? -- Nx.prt ("Social:ShowUIPanel show win") win:Show() self:ShowBlizzTabs (false) self.Bar:Select (self.TabSelected, true) end --[[ --V4 local guildTabI = self.OrigTabI + 2 self.Bar:Enable (guildTabI, IsInGuild() ~= nil) if self.TabSelected == guildTabI then local function func() GuildFrame:Show() -- Nx.prt ("FF G UPD") end Nx.Timer:Start ("SocialFFUpdate", 0, self, func) end --]] self.NoShow = false end end function Nx.Social:HideUIPanel (frame) if self.Win then -- Nx.prt ("Social:HideUIPanel") self.NoShow = true self:RestoreFriendsFrame() self:Show (false) self.NoShow = false -- Nx.prt ("Social:HideUIPanel2") end end -------- function Nx.Social:RestoreFriendsFrame() local ff = FriendsFrame -- Nx.prtFrame ("RestoreFF", ff) if ff:GetParent() == self.FFHolder then -- Nx.prt ("Social:RestoreFriendsFrame") -- ff:SetAttribute ("UIPanelLayout-enabled", false) local l = ff:GetFrameLevel (ff) -- self.Win:Detach (ff) self:ShowBlizzTabs() ff:SetParent (UIParent) -- This can cause ShowUIPanel calls if Esc key was pressed ff:SetToplevel (true) ff:SetFrameLevel (l) ff:Raise() ff:Hide() end end -------- -- Open window function Nx.Social:Show (on) self:Create() if self.Win then self.Win:Show (on) end end -------- -- Hide window. Used before combat lockdown function Nx.Social:PreCombatHide() if self.Win then if IsInRaid() then -- Nx.prt ("PreCombatHide") local ff = FriendsFrame -- ff:SetAttribute ("UIPanelLayout-enabled", true) -- ff:SetMovable (true) self:HideUIPanel (ff) end end end -------- -- Create window function Nx.Social:Create() local opts = Nx:GetGlobalOpts() if not opts["SocialEnable"] then return end if self.Win then return end local tbH = Nx.TabBar:GetHeight() -- Create Window local win = Nx.Window:Create ("NxSocial") self.Win = win local frm = win.Frm win:CreateButtons (true, true) win:InitLayoutData (nil, -.25, -.18, -.5, -.64) frm:SetToplevel (true) frm:Hide() tinsert (UISpecialFrames, frm:GetName()) win:SetUser (self, self.OnWin) win:RegisterEvent ("FRIENDLIST_SHOW", self.OnFriendListUpdate) win:RegisterEvent ("FRIENDLIST_UPDATE", self.OnFriendListUpdate) win:RegisterEvent ("GUILD_ROSTER_UPDATE", self.OnFriendListUpdate) -- FF local ffH = CreateFrame ("Frame", "NxSocFFH", UIParent) self.FFHolder = ffH ffH:SetWidth (384) ffH:SetHeight (512) local ff = FriendsFrame ff:SetParent (ffH) ff:SetPoint ("TOPLEFT", ffH, "TOPLEFT", 0, 0) win:Attach (ffH, 0, 1, 0, -tbH, 384 - 20, 512 - 40) -- win:Attach (ff, 0, 1, 0, -tbH) -- Create Tab Bar local bar = Nx.TabBar:Create (nil, frm, 1, 1) self.Bar = bar win:Attach (bar.Frm, 0, 1, -tbH, 1) bar:SetUser (self, self.OnTabBar) local palw = 0 local selected = 2 --PAIDS! palw = 40 selected = 1 --PAIDE! local orig = 3 bar:AddTab ("Pals", 1, palw) bar:AddTab ("Punks", 2, 46) if NxData.NXVerDebug then bar:AddTab ("Com", 3, 38) orig = 4 end self.OrigTabI = orig bar:AddTab ("Friends", orig, 60, false, "FriendsFrameTabTemplate", 1) bar:AddTab ("Who", orig + 1, 45, false, "FriendsFrameTabTemplate", 2) -- bar:AddTab ("Guild", orig + 2, 45, false, "FriendsFrameTabTemplate", 3) --V4 moved bar:AddTab ("Chat", orig + 2, 45, false, "FriendsFrameTabTemplate", 3) bar:AddTab ("Raid", orig + 3, 45, false, "FriendsFrameTabTemplate", 4) -- self.List:Create() self.TabSelected = selected bar:Select (selected) -- Select after list is created end -------- function Nx.Social:OnWin (typ) if typ == "Close" then self:HideUIPanel (FriendsFrame) end end function Nx.Social:OnFriendListUpdate (event) --[[ Nx.prt ("OnFriendListUpdate %s", event) for n = 1, GetNumFriends() do local name, level, class, area, connected, status, note = GetFriendInfo (n) Nx.prt ("#%s %s", n, name or "nil") end --]] self.List:Update() end -------- function Nx.Social:OnUpdate() if self.Win then local wf = self.Win.Frm if wf:IsVisible() then if self.Win:IsMovingOrSizing() then return end -- Nx.prt ("Soc vis") --[[ local f = GuildControlPopupFrame if f:IsVisible() then if f:GetFrameStrata() ~= wf:GetFrameStrata() then f:SetFrameStrata (wf:GetFrameStrata()) end if f:GetFrameLevel() <= self.Win.Frm:GetFrameLevel() then f:Raise() -- Nx.prt ("raise") end end --]] local f = ChannelFrameDaughterFrame if f:IsVisible() then f:SetFrameLevel (wf:GetFrameLevel() + 100) end end end end -------- function Nx.Social.PanelTemplates_SetTab (frame, index) local self = Nx.Social local ff = FriendsFrame if frame == ff and self.Bar and not self.InOnTabBar then index = index + self.OrigTabI - 1 -- Nx.prt ("PanelTemplates_SetTab #%s", index) self.Bar:Select (index) end end -------- function Nx.Social:OnTabBar (index, click, inSetTab) if self.InOnTabBar then -- Nx.prt ("OnTabBar %s in tab bar", index) return end -- Nx.prt ("OnTabBar %s", index) -- local oldSel = self.TabSelected self.TabSelected = index if not self.Win:IsShown() then -- Nx.prt ("OnTabBar %s !win", index) return end self.InOnTabBar = true --[[ if self.TabSelected == self.OrigTabI + 2 and not IsInGuild() then self.Bar:Select (oldSel) self.InOnTabBar = false return end --]] local list = self.List.List local ff = FriendsFrame local tbH = Nx.TabBar:GetHeight() if ff:GetParent() ~= self.FFHolder then -- Nx.prt ("OnTabBar %s Parent", index) local ffH = self.FFHolder ff:SetToplevel (false) ff:SetParent (ffH) ff:SetPoint ("TOPLEFT", ffH, "TOPLEFT", 0, 0) self:ShowBlizzTabs (false) end if index < self.OrigTabI then self.FFHolder:Hide() list.Frm:Show() else list.Frm:Hide() self.FFHolder:Show() ff:Show() end self.List:Update() self.InOnTabBar = false -- Nx.prt ("OnTabBar %s done", index) end function Nx.Social:ShowBlizzTabs (show) for n = 1, 10 do local tabf = getglobal ("FriendsFrameTab" .. n) if tabf then if show ~= false then tabf:Show() else tabf:Hide() end end end end -------- -- Create social list function Nx.Social.List:Create() local win = Nx.Social.Win local tbH = Nx.TabBar:GetHeight() -- Dummy frame --[[ local f = CreateFrame ("Frame", nil, UIParent) self.Frm = f f.NxSocialList = self f:SetMovable (true) f:EnableMouse (true) f:SetFrameStrata ("MEDIUM") local t = f:CreateTexture() t:SetTexture (.2, .2, .2, .5) t:SetAllPoints (f) f.texture = t f:Show() win:Attach (f, 0, .02, 0, -tbH) --]] -- List Nx.List:SetCreateFont ("FontM") local list = Nx.List:Create ("Social", 2, -2, 100, 12 * 3, win.Frm) self.List = list list:SetUser (self, self.OnListEvent) -- list:SetLineHeight (12) list:ColumnAdd ("", 1, 80) list:ColumnAdd ("Character", 2, 110) list:ColumnAdd ("Lvl", 3, 20) list:ColumnAdd ("Class", 4, 65) list:ColumnAdd ("Zone", 5, 150) list:ColumnAdd ("Note", 6, 500) win:Attach (list.Frm, 0, 1, 0, -tbH) -- FF local ff = FriendsFrame self.FriendsFrame = ff self:SetLevels() -- Generic menu local function funcOpenOptions() Nx.Opts:Open ("Social & Punks") end -- Create pals menu local menu = Nx.Menu:Create (list.Frm, 230) self.PalsMenu = menu local function func (self) if self.MenuSelName then local box = ChatEdit_ChooseBoxForSend() --V4 ChatEdit_ActivateChat (box) box:SetText ("/w " .. self.MenuSelName .. " " .. box:GetText()) --[[ local frm = DEFAULT_CHAT_FRAME local eb = frm["editBox"] if not eb:IsVisible() then ChatFrame_OpenChat ("/w " .. self.MenuSelName, frm) else eb:SetText ("/w " .. self.MenuSelName .. " " .. eb:GetText()) end --]] end end menu:AddItem (0, "Whisper", func, self) local function func (self) if self.MenuSelName then InviteUnit (self.MenuSelName) end end menu:AddItem (0, "Invite", func, self) menu:AddItem (0, "") local function func (self) if UnitIsPlayer ("target") and UnitCanCooperate ("player", "target") then -- Nx.prt ("target %s", UnitName ("target")) AddFriend (UnitName ("target")) --V4 was AddFriend ("target") else StaticPopup_Show ("ADD_FRIEND") end end menu:AddItem (0, "Add Pal And Friend", func, self) local function func (self) if self.MenuSelName then self:ClrFriend (self.MenuSelName) local i = self:FindFriendI (self.MenuSelName) if i then RemoveFriend (self.MenuSelName) else self:Update() end end end menu:AddItem (0, "Remove Pal And Friend", func, self) menu:AddItem (0, "") local function func (self) if self.MenuSelName then local i = self:FindFriendI (self.MenuSelName) if i then self.FriendsFrame["NotesID"] = i StaticPopup_Show ("SET_FRIENDNOTE", GetFriendInfo (i)) end end end self.PalMenuINote = menu:AddItem (0, "Set Note", func, self) menu:AddItem (0, "Set Person", self.Menu_OnSetPerson, self) menu:AddItem (0, "") menu:AddItem (0, "Make Pal (Red) Into Friend", self.Menu_OnMakePalFriend, self) menu:AddItem (0, "Make All Pals Into Friends", self.Menu_OnMakePalsFriends, self) menu:AddItem (0, "") menu:AddItem (0, "Options...", funcOpenOptions, self) -- Create punks menu local menu = Nx.Menu:Create (list.Frm) self.PunksMenu = menu local function func (self) self:GotoPunk (self.List.MenuSelName) end menu:AddItem (0, "Goto", func, Nx.Social) menu:AddItem (0, "Add Character", self.Menu_OnPunkAdd, self) menu:AddItem (0, "Remove Character", self.Menu_OnPunkRemove, self) menu:AddItem (0, "Set Note", self.Menu_OnPunkSetNote, self) local function func (self) Nx:ClearSocial ("PkAct") self.PunksActive = Nx:GetSocial ("PkAct") end menu:AddItem (0, "Clear Actives", func, Nx.Social) menu:AddItem (0, "") menu:AddItem (0, "Options...", funcOpenOptions, self) end function Nx.Social.List:SetLevels() local win = Nx.Social.Win local wf = win.Frm local ff = self.FriendsFrame ff:SetToplevel (false) -- ff:SetAlpha (1) -- Nx.prt ("Lev1 "..wf:GetFrameLevel().." "..ff:GetFrameLevel()) wf:Raise() -- Nx.prt ("Lev2 "..wf:GetFrameLevel().." "..ff:GetFrameLevel()) local f = getglobal ("FriendsFrameCloseButton") local lev = f:GetFrameLevel() ff:SetFrameLevel (lev - 1) wf:SetFrameLevel (lev - 2) -- Nx.prt ("Lev3 "..wf:GetFrameLevel().." "..ff:GetFrameLevel()) end function Nx.Social.List:Menu_OnSetPerson() if self.MenuSelName then local person = self:FindFriendPerson (self.MenuSelName) or "" Nx:ShowEditBox ("Set person who owns character", person, self.MenuSelName, self.SetPersonAccept) end end function Nx.Social.List.SetPersonAccept (person, friend) person = Nx.Util_CleanName (person) local list = Nx.Social.List list:SetPersonFriend (person, friend) list:Update() end function Nx.Social.List:Menu_OnMakePalFriend() if self.MenuSelName then AddFriend (self.MenuSelName) end end function Nx.Social.List:Menu_OnMakePalsFriends() local pal = Nx:GetSocial ("Pal") for _, friends in pairs (pal) do for fName, v in pairs (friends) do if not self:FindFriendI (fName) then -- Not a friend? AddFriend (fName) end end end end function Nx.Social.List:Menu_OnPunkAdd() local name = UnitName ("target") if name and UnitIsPlayer ("target") and UnitIsEnemy ("player", "target") then self:PunkAdd (name, UnitLevel ("target"), UnitClass ("target")) self:Update() else Nx:ShowEditBox ("Add punk name", self.MenuSelName or Nx.Social.LastLocalPunk or "", self, self.PunkAddAccept) end end function Nx.Social.List.PunkAddAccept (name, list) list:PunkAdd (name) list:Update() end function Nx.Social.List:PunkAdd (name, level, class) local punks = Nx:GetSocial ("Pk") name = Nx.Util_CleanName (name) local punk = Nx.Social.PunksActive[name] if punk then level = level or punk.Lvl class = class or punk.Class end punks[name] = format ("%s~%s~%s", time(), level or "", class or "") end function Nx.Social.List:Menu_OnPunkRemove() if self.MenuSelName then local punks = Nx:GetSocial ("Pk") punks[self.MenuSelName] = nil self:Update() end end function Nx.Social.List:Menu_OnPunkSetNote() if self.MenuSelName then local punks = Nx:GetSocial ("Pk") local punk = punks[self.MenuSelName] if punk then self.MenuPunkName = self.MenuSelName local tm, lvl, class, note = strsplit ("~", punk) Nx:ShowEditBox ("Set note", note or "", self, self.PunkSetNote) end end end function Nx.Social.List.PunkSetNote (text, list) local punks = Nx:GetSocial ("Pk") local punk = punks[list.MenuPunkName] local tm, lvl, class, note = strsplit ("~", punk) punks[list.MenuPunkName] = format ("%s~%s~%s~%s", tm, lvl, class, text) list:Update() end -------- -- On list control updates function Nx.Social.List:OnListEvent (eventName, sel, val2, click) local name = self.List:ItemGetData (sel) self.SelName = name local tabI = Nx.Social.TabSelected if tabI == 1 then local i = self:FindFriendI (name) if i then -- Nx.prt ("Sel %s", i) SetSelectedFriend (i) end end if eventName == "select" or eventName == "mid" or eventName == "back" then elseif eventName == "menu" then -- Nx.prt ("OnListEvent %s", val2) self.MenuSelName = self.SelName if tabI == 1 then local i = self:FindFriendI (self.SelName) self.PalMenuINote:Show (i ~= nil) self.PalsMenu:Open() elseif tabI == 2 then self.PunksMenu:Open() else self.ComMenu:Open() end end end function Nx.Social.List:FindFriendI (friend) local cnt = GetNumFriends() for n = 1, cnt do local name, level, class, area, connected, status, note = GetFriendInfo (n) if name == friend then return n end end end -------- -- Find person who has friend -- (friend name) -- ret person name function Nx.Social.List:FindFriendPerson (friend) local pal = Nx:GetSocial ("Pal") for person, friends in pairs (pal) do for fname, v in pairs (friends) do if friend == fname then return person end end end end function Nx.Social.List:SetPersonFriend (person, friend) self:ClrFriend (friend) local pal = Nx:GetSocial ("Pal") local friends = pal[person] or {} pal[person] = friends friends[friend] = "" end -------- -- Clear friend from all persons function Nx.Social.List:ClrFriend (friend) local pal = Nx:GetSocial ("Pal") for person, friends in pairs (pal) do friends[friend] = nil -- Nx.prt ("delete %s", friend) if not next (friends) then -- No friends left? if person ~= "" then -- Nx.prt ("delete %s", person) pal[person] = nil end end end end function Nx.Social.List:Update() -- self:Update_() end -------- -- function Nx.Social.List:Update_() -- Nx.prt ("SocialListUpdate") local soc = Nx.Social local win = soc.Win local list = self.List if not (win and list) then -- Can be called with nil List if GuildProfiler present during create return end self.SelName = nil local pal = Nx:GetSocial ("Pal") local tabI = soc.TabSelected win:SetTitle ("") list:Empty() if tabI == 1 then --PAIDS! list:ColumnSetName (1, "Person") -- Person A Char A -- Person A Char B -- Person B Char A local data = {} local f2p = {} local fConnected = {} for pName, friends in pairs (pal) do for fName, _ in pairs (friends) do tinsert (data, format ("%s~%s", pName, fName)) f2p[fName] = pName end end local fI = {} local cnt = GetNumFriends() for n = 1, cnt do local name, level, class, area, connected, status, note = GetFriendInfo (n) if name then fI[name] = n fConnected[name] = connected local pName = f2p[name] local pData = pal[pName or ""] if connected then pData[name] = format ("%s~%s", level, class) else pData[name] = pData[name] or "" -- Keep last data or start a new entry end if not pName then tinsert (data, format ("~%s", name)) end end end local function func (a, b) local pName1, fName1 = strsplit ("~", a) local pName2, fName2 = strsplit ("~", b) if fConnected[fName1] and not fConnected[fName2] then return true end if not fConnected[fName1] and fConnected[fName2] then return false end if pName1 == pName2 then return fName1 < fName2 end if pName1 == "" then return false end if pName2 == "" then return true end return pName1 < pName2 end sort (data, func) win:SetTitle (format ("Pals: |cffffffff%d/%d", cnt, 50)) for _, plyr in ipairs (data) do local pName, fName = strsplit ("~", plyr) local i = fI[fName] list:ItemAdd (fName) local conCol = fConnected[fName] and "|cff80f080" or "|cff808080" if #pName > 0 then list:ItemSet (1, conCol .. pName) end if not i then conCol = "|cfff04040" end list:ItemSet (2, conCol .. fName) local name, level, class, area, connected, status, note if i then name, level, class, area, connected, status, note = GetFriendInfo (i) end if connected then list:ItemSet (5, area) else local pData = pal[pName] level, class = strsplit ("~", pData[fName]) end if level ~= "" then list:ItemSet (3, format ("%s", level)) local color = Nx.ClassColorStrs[NXlClassLocToCap[class]] or "" list:ItemSet (4, color .. class) end local s = status or "" if note then s = s .. " " .. note end list:ItemSet (6, s) end --PAIDE! elseif tabI == 2 then list:ColumnSetName (1, "Status") local punks = soc.Punks local punksA = soc.PunksActive local tm = GetTime() local myCnt = 0 local actCnt = 0 local data = {} for pName, str in pairs (punks) do tinsert (data, pName) end sort (data) for _, pName in ipairs (data) do myCnt = myCnt + 1 local tm, lvl, class, note = strsplit ("~", punks[pName]) list:ItemAdd (pName) if punksA[pName] then list:ItemSet (1, "|cffff6060Found") end list:ItemSet (2, pName) if lvl and lvl ~= 0 then list:ItemSet (3, tostring (lvl)) end if class then local color = Nx.ClassColorStrs[NXlClassLocToCap[class]] or "" list:ItemSet (4, color .. class) end if note and #note > 0 then list:ItemSet (6, note) end end list:ItemAdd() list:ItemAdd() list:ItemSet (2, "|cff8080ff-- Active --") local data = {} for pName in pairs (punksA) do -- Nx.prt ("PkList %s", pName) tinsert (data, pName) end -- Nx.prtVar ("", data) sort (data) for _, pName in ipairs (data) do actCnt = actCnt + 1 local punk = punksA[pName] list:ItemAdd (pName) local seconds = tm - punk.Time list:ItemSet (1, format ("%d:%02d", seconds / 60 % 60, seconds % 60)) local name = punks[pName] and pName or ("|cffafafaf" .. pName) list:ItemSet (2, name) if punk.Lvl ~= 0 then list:ItemSet (3, tostring (punk.Lvl)) end if punk.Class then list:ItemSet (4, punk.Class) end local mapName = Nx.MapIdToName[punk.MId] or "?" list:ItemSet (5, format ("%s %d %d", mapName, punk.X, punk.Y)) list:ItemSet (6, format ("Near %s", punk.FinderName)) end win:SetTitle (format ("Punks: %s Active: %s", myCnt, actCnt)) elseif NxData.NXVerDebug and tabI == 3 then local actCnt = Nx.Util_tcount (Nx.Quest.CapturePlyrData) for _, data in pairs (Nx.Quest.CapturePlyrData) do list:ItemAdd() list:ItemSet (2, data.Name) list:ItemSet (3, data.Level) list:ItemSet (6, format ("%s/%s", data.RcvCnt, data.Total)) end if actCnt > 0 then list:ItemAdd() end local data = Nx.Com:SortUserQuests() local cnt = 0 local qcnt = 0 for n, msg in ipairs (data) do local name, ver, r, c, dt, ver1, qCnt, lvl, mId = strsplit ("^", msg) ver = tonumber (ver) cnt = cnt + 1 qcnt = qcnt + (qCnt or 0) list:ItemAdd() list:ItemSet (2, name) if lvl then list:ItemSet (3, tostring (tonumber (lvl, 16))) end if mId then local name = Nx.MapIdToName[tonumber (mId, 16)] or "?" list:ItemSet (5, name) end local i = strfind (msg, "%^") if i then msg = strsub (msg, i + 1) end list:ItemSet (6, msg) end local capCnt = Nx.Util_tcount (Nx:GetCap()["Q"]) win:SetTitle (format ("Total: %s Q%s, active %s, data %s", cnt, qcnt, actCnt, capCnt)) end list:Update() end ------------------------------------------------------------------------------- -- Punks management function Nx.Social:DecodeComRcvPunks (finderName, info, punksStr) -- Nx.prt ("%s: %s %s %s", finderName, punksStr, info.X, info.Y) local punksT = { strsplit ("!", punksStr) } for n, v in ipairs (punksT) do local lvl = tonumber (strsub (v, 1, 2), 16) if not lvl then -- Error? break end local name = strsub (v, 3) if lvl >= 0xff then name = strsub (v, 9) lvl = 0 end local punk = self:GetPunk (name, nil, info.MId, info.X, info.Y) punk.FinderName = finderName punk.Lvl = max (lvl, punk.Lvl or 0) punk.Time = info.T end if not Nx.Timer:IsActive ("SocialUpdate") then Nx.Timer:Start ("SocialUpdate", 2, self, self.OnUpdateTimer) end end -------- -- Add a punk we detected ourselves function Nx.Social:AddLocalPunk (name, plyrNear, level, class) -- Nx.prt ("AddLocalPunk %s", name) if Nx.InBG and not plyrNear then return end local map = Nx.Map:GetMap (1) name = strmatch (name, "[^-]+") -- Remove server name self.LastLocalPunk = name local rMapId = map.RMapId local x, y = map.PlyrRZX, map.PlyrRZY if plyrNear then plyrNear = strmatch (plyrNear, "[^-]+") -- Remove server name local i = Nx.GroupMembers[plyrNear] if i then local unit = Nx.GroupType .. i local s = UnitName (unit) if s then local pX, pY = GetPlayerMapPosition (unit) if pX ~= 0 or pY ~= 0 then x = pX * 100 y = pY * 100 end -- DEBUG! -- if IsControlKeyDown() then -- Nx.prt ("Local punk %s near %s #%s %s %s", name, plyrNear, i, x, y) -- end end end end -- DEBUG! -- if IsControlKeyDown() then -- Nx.prt ("-Local punk %s near %s %s %s", name, plyrNear or "nil", x, y) -- end local punk = self:GetPunk (name, plyrNear, rMapId, x, y) if not punk.Time and not Nx.InBG and self.GOpts["PunkNewLocalWarnChat"] then -- New? if not Nx.InSanctuary or self.GOpts["PunkShowInSafeArea"] then -- if (rMapId ~= 3006 and rMapId ~= 4003 and rMapId ~= 4012) or self.GOpts["PunkShowInSafeArea"] then local typ = self.Punks[name] and "|cffff4040Punk" or "Enemy" Nx.prt ("%s %s detected near you", typ, name) if self.GOpts["PunkNewLocalWarnSnd"] then Nx:PlaySoundFile ("sound\\doodad\\belltolltribal.wav") end end end punk.FinderName = "me" punk.Lvl = level or punk.Lvl or 0 punk.Class = class or punk.Class if not punk.Time or GetTime() - punk.Time > 2 then punk.Time = GetTime() end if not Nx.Timer:IsActive ("SocialUpdate") then Nx.Timer:Start ("SocialUpdate", 2, self, self.OnUpdateTimer) end self.PunksHUD:Add (name) end -------- function Nx.Social:GetPunk (name, plyrNear, mId, x, y) local punk = self.PunksActive[name] if not punk then punk = {} self.PunksActive[name] = punk punk.DrawDir = self.PunkNewDir self.PunkNewDir = self.PunkNewDir + 3.14159 / 4.25 punk.CircleTime = GetTime() end if not Nx.InBG or not punk.PlyrNear or plyrNear and plyrNear ~= punk.PlyrNear then -- Nx.prt ("Punk %s near %s %s %s", name, plyrNear or "nil", x, y) punk.PlyrNear = plyrNear punk.MId = mId punk.X = x punk.Y = y end -- punk.Alert = nil if not punk.Alert and self.Punks[name] then self.PunksHUD:Add (name) if self.GOpts["PunkMAlertText"] then local tm, lvl, class, note = strsplit ("~", self.Punks[name]) -- note = "Test note. xyz. abc 12213213872xxx" if note then UIErrorsFrame:AddMessage (format ("Note: %s", note), 1, 0, 1, 1) end local map = Nx.Map:GetMap (1) local wx, wy = map:GetWorldPos (mId, x, y) local dist = ((map.PlyrX - wx) ^ 2 + (map.PlyrY - wy) ^ 2) ^ .5 * 4.575 local s = dist < 100 and "|cffff4000near you" or format ("at %d yards", dist) UIErrorsFrame:AddMessage (format ("|cffff4000%s|r detected %s!", name, s), 1, 1, 0, 1) end if self.GOpts["PunkMAlertSnd"] then Nx:PlaySoundFile ("sound\\spells\\antiholy.wav") end punk.Alert = true end if GetTime() - punk.CircleTime > 4 then -- Long enough for visual refresh? punk.CircleTime = GetTime() end return punk end -------- function Nx.Social:OnUpdateTimer() self:CalcPunks() -- Check tab selection first, since they could be nil if self.TabSelected == 2 and self.Win:IsShown() then self.List:Update() return 3 end end -------- -- Update punks data function Nx.Social:CalcPunks() local punks = self.Punks local punksA = self.PunksActive local tm = GetTime() - (Nx.InBG and 30 or 90) -- Expire time (1.5 min) for pName, punk in pairs (punksA) do if punks[pName] then -- On our list? if tm - 240 > punk.Time then -- Expired? (5 mins) punksA[pName] = nil self.PunksHUD:Remove (pName) end else if tm > punk.Time then -- Expired? punksA[pName] = nil self.PunksHUD:Remove (pName) end end end end -------- -- Update map icons (called by map) function Nx.Social:UpdateIcons (map) if Nx.Tick % 120 == 4 then self:CalcPunks() end local math = math local alt = IsAltKeyDown() local tm = GetTime() local idToName = Nx.MapIdToName local punks = self.Punks local punksA = self.PunksActive local size = self.GOpts["PunkAreaSize"] * map.ScaleDraw local sizeM = self.GOpts["PunkMAreaSize"] * map.ScaleDraw local areaR, areaG, areaB = Nx.Util_num2rgba (self.GOpts["PunkAreaColor"]) local iconR, iconG, iconB, iconA = Nx.Util_num2rgba (self.GOpts["PunkIconColor"]) local areaRM, areaGM, areaBM = Nx.Util_num2rgba (self.GOpts["PunkMAreaColor"]) local showInNorthrend = self.GOpts["PunkShowInNorthrend"] local showInSafeArea = self.GOpts["PunkShowInSafeArea"] local decay = .24 local decayM = .21 local inBG = Nx.InBG if inBG then if not self.GOpts["PunkShowInBG"] or Nx.Free then return end size = self.GOpts["PunkBGAreaSize"] * map.ScaleDraw areaR, areaG, areaB = Nx.Util_num2rgba (self.GOpts["PunkBGAreaColor"]) local decay = 2 local decayM = .25 end local iconGlow = abs (GetTime() * 400 % 200 - 100) / 400 + .75 if alt then map.Level = map.Level + 11 end for pName, punk in pairs (punksA) do local dur = tm - punk.Time local circleDur = tm - punk.CircleTime local punkMId = punk.MId local wx, wy = map:GetWorldPos (punkMId, punk.X, punk.Y) local x = wx + math.sin (punk.DrawDir) * 2 local y = wy + math.cos (punk.DrawDir) * 2 -- DEBUG! -- if IsControlKeyDown() then -- local sz = size / (circleDur * decay + 1) -- Nx.prt ("Punk %s near %s %s %s sz%s", pName, punk.PlyrNear or "nil", x, y, sz) -- end if punks[pName] then -- Punk match? local sz = sizeM / (circleDur * decayM + 1) if sz >= 1 then sz = max (sz, 25) local f = map:GetIconNI() if map:ClipFrameW (f, x, y, sz, sz, 0) then f.texture:SetBlendMode ("ADD") f.texture:SetTexture ("Interface\\AddOns\\Carbonite\\Gfx\\Map\\IconCircle") if dur < .1 then f.texture:SetVertexColor (.3, 1, .3, 1) else f.texture:SetVertexColor (areaRM, areaGM, areaBM, 1) end end end else if (not Nx.InSanctuary or showInSafeArea) and -- if ((punkMId ~= 3006 and punkMId ~= 4003 and punkMId ~= 4012) or showInSafeArea) and ((punkMId < 4000 or punkMId > 4999) or showInNorthrend) then local sz = size / (circleDur * decay + 1) if sz >= 1 then sz = max (sz, 22) local f = map:GetIconNI() if map:ClipFrameW (f, x, y, sz, sz, 0) then f.texture:SetBlendMode ("ADD") f.texture:SetTexture ("Interface\\AddOns\\Carbonite\\Gfx\\Map\\IconCircle") if dur < .05 then if inBG then f.texture:SetVertexColor (.15, .15, .15, 1) else f.texture:SetVertexColor (.25, .25, .25, 1) end else f.texture:SetVertexColor (areaR, areaG, areaB, 1) end end end end end -- Draw punk dot if punks[pName] then -- Punk match? local f = map:GetIcon (2) if map:ClipFrameW (f, x, y, 14, 14, 0) then local lvl = punk.Lvl > 0 and punk.Lvl or "?" local mapName = idToName[punkMId] or "?" f.NxTip = format ("*|cffff0000%s %s, %d:%02d ago\n%s (%d,%d)", pName, lvl, dur / 60 % 60, dur % 60, mapName, punk.X, punk.Y) f.NXType = 3001 f.NXData = pName f.texture:SetTexture ("Interface\\AddOns\\Carbonite\\Gfx\\Map\\IconPlyrZ") f.texture:SetVertexColor (iconR, iconG, iconB, iconA * iconGlow) if alt then local txt = map:GetText (format ("*|cffff0000%s|r*", pName)) map:MoveTextToIcon (txt, f, 18, 1) end end else if (not Nx.InSanctuary or showInSafeArea) and -- if ((punkMId ~= 3006 and punkMId ~= 4003 and punkMId ~= 4012) or showInSafeArea) and ((punkMId < 4000 or punkMId > 4999) or showInNorthrend) then local i = dur < 10 and 2 or 1 local f = map:GetIcon (i) if map:ClipFrameW (f, x, y, 10, 10, 0) then local lvl = punk.Lvl > 0 and punk.Lvl or "?" local mapName = idToName[punkMId] or "?" f.NxTip = format ("|cffff6060%s %s, %d:%02d ago\n%s (%d,%d)", pName, lvl, dur / 60 % 60, dur % 60, mapName, punk.X, punk.Y) f.NXType = 3001 f.NXData = pName f.texture:SetTexture ("Interface\\AddOns\\Carbonite\\Gfx\\Map\\IconPlyrZ") if dur < 10 then f.texture:SetVertexColor (iconR, iconG, iconB, iconA * iconGlow) else f.texture:SetVertexColor (iconR, iconG, iconB, iconA * .6) end end end end end if alt then map.Level = map.Level - 11 else map.Level = map.Level + 3 end end -------- -- Goto a named punk function Nx.Social:GotoPunk (name) local punk = self.PunksActive[name] if punk then local map = Nx.Map:GetMap (1) local wx, wy = map:GetWorldPos (punk.MId, punk.X, punk.Y) local x = wx + math.sin (punk.DrawDir) * 2 local y = wy + math.cos (punk.DrawDir) * 2 map:SetTarget ("Goto", x, y, x, y, false, 0, name) end end -------- -- Get a named punks paste info function Nx.Social:GetPunkPasteInfo (name) local punk = self.PunksActive[name] if punk then local lvl = punk.Lvl > 0 and punk.Lvl or "?" local class = punk.Class or "?" return format ("Punk: %s, %s %s at %s %d %d", name, lvl, class, Nx.MapIdToName[punk.MId] or "?", punk.X, punk.Y) end return "" end ------------------------------------------------------------------------------- -------- -- Create punk HUD function Nx.Social.PunksHUD:Create() --PAIDS! local opts = Nx:GetGlobalOpts() self.Opts = opts self.Punks = {} self.Buts = {} self.NumButs = opts["PunkTWinMaxButs"] self.NumButsUsed = 0 self.Changed = true -- Create Window -- Nx.Window:ClrSaveData ("NxPunkHUD") -- DEBUG! Nx.Window:SetCreateFade (.5, 0) local win = Nx.Window:Create ("NxPunkHUD", nil, nil, true, 1, 1, nil, true) self.Win = win win:InitLayoutData (nil, -.6, -.1, 128, 68) -- win:CreateButtons (nil, true) win:SetBGAlpha (0, .5) win.Frm:SetToplevel (true) -- Create buttons local ox, oy = win:GetClientOffset() local x = ox - 2 local y = -oy for n = 1, self.NumButs do -- Nx.prt ("But #%s create", n) local but = CreateFrame ("Button", nil, win.Frm, "SecureUnitButtonTemplate") self.Buts[n] = but but:SetPoint ("TOPLEFT", x, y) y = y - 13 but:SetAttribute ("type1", "macro") -- but:SetAttribute ("macrotext1", "/targetenemy") -- but:SetAttribute ("type2", "target") -- but:SetAttribute ("unit", "player") but:SetAttribute ("*type2", "click") but:SetAttribute ("*clickbutton2", but) but["Click"] = Nx.Social.PunksHUD.Click but:RegisterForClicks ("LeftButtonDown", "RightButtonDown") local t = but:CreateTexture() t:SetTexture (1, 1, 1, 1) t:SetAllPoints (but) but.texture = t but:SetWidth (125) but:SetHeight (12) but:Hide() local fstr = but:CreateFontString() but.NXFStr = fstr fstr:SetFontObject ("GameFontNormalSmall") fstr:SetJustifyH ("LEFT") fstr:SetPoint ("TOPLEFT", 0, 1) fstr:SetWidth (125) fstr:SetHeight (12) end --PAIDE! end -------- -- SecureTemplates Click handler -- self is button frame function Nx.Social.PunksHUD:Click() local but = self -- Nx.prt ("click %s", but.NXName or "nil") if IsShiftKeyDown() then Nx.Social.List:PunkAdd (but.NXName) Nx.prt ("Punk %s added", but.NXName or "") else Nx.Social.PunksHUD:Remove (but.NXName) end end -------- function Nx.Social.PunksHUD:Add (name) --PAIDS! if not self.Punks[name] then local punks = Nx.Social.Punks if punks[name] then -- Match? tinsert (self.Punks, 1, name) -- Top of list else local found for n = 1, #self.Punks do if not punks[self.Punks[n]] then tinsert (self.Punks, n, name) -- Top of non matches found = true break end end if not found then tinsert (self.Punks, name) -- End end end end self.Punks[name] = true self.Changed = true --PAIDE! end -------- function Nx.Social.PunksHUD:Remove (name) --PAIDS! for n = 1, #self.Punks do if self.Punks[n] == name then tremove (self.Punks, n) break end end self.Punks[name] = nil self.Changed = true --PAIDE! end -------- function Nx.Social.PunksHUD:Update() --PAIDS! if not self.Win then return end local Social = Nx.Social if self.Changed then local lockDown = InCombatLockdown() ~= nil local lchanged = self.LockedDown ~= lockDown self.LockedDown = lockDown if not lockDown then self.Changed = false local punks = Social.Punks local punksA = Social.PunksActive local n = 1 for index, name in ipairs (self.Punks) do local punk = self.Punks[name] -- Nx.prt ("But #%s update %s", n, name) local but = self.Buts[n] local function func (self) Nx.prt ("hey") end but:SetAttribute ("macrotext1", "/targetexact " .. name) -- but:SetAttribute ("shift-macrotext1", "/target " .. name .. "-target") but.NXName = name local s = name if punks[name] then -- Match? s = "|cffff80ff*" .. name end local class = punksA[name] and punksA[name].Class if class then s = s .. ", |cffa0a0a0" .. class end but.NXFStr:SetText (s) but:Show() n = n + 1 if n > self.NumButs then break end end self.NumButsUsed = n - 1 for i = n, self.NumButs do local but = self.Buts[i] but:Hide() end self.Win:SetSize (120, n * 13 - 15) end if lchanged then local win = self.Win if lockDown then win:SetTitle ("|cffff2020" .. self.Opts["PunkTWinTitle"]) else win:SetTitle (self.Opts["PunkTWinTitle"]) end end end -- local punksA = Social.PunksActive local tm = GetTime() for n = 1, self.NumButsUsed do local but = self.Buts[n] local punk = punksA[but.NXName] if punk then local dur = tm - punk.Time dur = dur < .3 and dur or dur * .05 + .285 -- Quick pulse, then slow fade -- Nx.prt ("Punk #%s %s", n, dur) local r = min (max (1 - dur, .1), 1) but.texture:SetVertexColor (r, 0, 0, .5) end end --PAIDE! end ------------------------------------------------------------------------------- -------- -- Create group HUD function Nx.Social.TeamHUD:Create() --PAIDS! local opts = Nx:GetGlobalOpts() if not opts["TeamTWinEnable"] then return end self.Players = {} for n = 1, MAX_RAID_MEMBERS do local data = {} data.Dist = 999999999 self.Players[n] = data end self.Buts = {} self.NumButs = opts["TeamTWinMaxButs"] self.HealthFrms = {} self.FStrs = {} self.UpdateTime = 0 -- Create Window -- Nx.Window:ClrSaveData ("NxTeamHUD") -- DEBUG! Nx.Window:SetCreateFade (.5, 0) local win = Nx.Window:Create ("NxTeamHUD", 20, nil, true, 1, nil, true, true) -- Hidden self.Win = win win:SetBGAlpha (0, 1) win:InitLayoutData (nil, -.6, -.3, 100, 10) -- win:CreateButtons (nil, true) win.Frm:SetToplevel (true) -- Create buttons local ox, oy = win:GetClientOffset() local x = ox - 2 local y = -oy for n = 1, self.NumButs do -- Nx.prt ("But #%s create", n) local but = CreateFrame ("Button", nil, win.Frm, "SecureUnitButtonTemplate") self.Buts[n] = but but:SetPoint ("TOPLEFT", x, y) y = y - 14 if n == 1 then but:SetAttribute ("type", "target") but:SetAttribute ("unit1", "player") but:SetAttribute ("unit2", "targetenemy") else but:SetAttribute ("type", "macro") but:Hide() end but:RegisterForClicks ("LeftButtonDown", "RightButtonDown") local t = but:CreateTexture() t:SetTexture (0, .1, 0, .9) t:SetAllPoints (but) but.texture = t but:SetWidth (50) but:SetHeight (12) local f = CreateFrame ("Frame", nil, but) self.HealthFrms[n] = f f:SetPoint ("TOPLEFT", 0, 0) local t = f:CreateTexture() -- t:SetTexture (0, .1, 0, .4) t:SetAllPoints (f) f.texture = t -- f:SetWidth (50) f:SetHeight (12) local fstr = f:CreateFontString() self.FStrs[n] = fstr fstr:SetAllPoints (but) fstr:SetFontObject ("GameFontNormalSmall") fstr:SetJustifyH ("LEFT") fstr:SetPoint ("TOPLEFT", 0, 0) fstr:SetWidth (50) fstr:SetHeight (12) fstr:SetText ("Me") end --PAIDE! end -------- function Nx.Social.TeamHUD:Update() --PAIDS! if not self.Win or not self.Win.Frm:IsVisible() then return end local tm = GetTime() local update = tm - self.UpdateTime > 1 if update then self.UpdateTime = tm end local cw, ch = self.Win:GetSize() local Social = Nx.Social local lockDown = InCombatLockdown() ~= nil local lchanged = self.LockedDown ~= lockDown self.LockedDown = lockDown if update and not lockDown then local Map = Nx.Map local map = Map:GetMap (1) local mapId, plX, plY = map.RMapId, map.PlyrRZX, map.PlyrRZY local plX, plY = Map:GetWorldPos (mapId, plX, plY) local inArena = Nx.InArena local members = MAX_PARTY_MEMBERS local unitName = "party" local maxDist = 999999990 if IsInRaid() then -- Arenas are raids members = MAX_RAID_MEMBERS unitName = "raid" maxDist = 250 end for n = 1, members do local player = self.Players[n] local unit = unitName .. n local name = UnitName (unit) player.Name = name or "zzz" -- if IsControlKeyDown() then -- Nx.prt ("%s %s", n, name or "nil") -- end player.Dist = 999999999 if name and not UnitIsUnit (unit, "player") then player.Unit = unit -- Nx.prt ("Pal %s %s", name, per) local pX, pY = GetPlayerMapPosition (unit) if pX == 0 then player.Dist = 999999 else pX = pX * 100 pY = pY * 100 local wx, wy = Map:GetWorldPos (map.MapId, pX, pY) local dist = (plX - wx) ^ 2 + (plY - wy) ^ 2 player.Dist = dist ^ .5 * 4.575 end end end if not lockDown then if inArena then sort (self.Players, function (a, b) return a.Name < b.Name end) else local func = function (a, b) if a.Dist < 100 then if b.Dist < 100 then return a.Name < b.Name end return true else if b.Dist < 100 then return false end return a.Dist < b.Dist end return a.Name < b.Name end sort (self.Players, func) end local but = self.Buts[1] but:SetWidth (cw) local n = 2 for index, player in ipairs (self.Players) do player.But = nil if player.Dist < maxDist or player.Dist == 999999 then local name = player.Name -- Nx.prt ("But #%s update %s", n, name) local but = self.Buts[n] player.But = but player.FrmI = n but:SetAttribute ("macrotext1", "/targetexact " .. name) but:SetAttribute ("macrotext2", "/target " .. name .. "-target") but:SetWidth (cw) but:Show() local f = self.HealthFrms[n] player.HealthFrm = f n = n + 1 if n > self.NumButs then break end end end for i = n, self.NumButs do local but = self.Buts[i] but:Hide() end self.Win:SetSize (cw, n * 14 - 14) end end -- Update text local fstr = self.FStrs[1] local h = UnitIsDeadOrGhost ("player") and 0 or UnitHealth ("player") local per = min (h / UnitHealthMax ("player"), 1) -- Can overflow? -- Nx.prt ("%s %s", h, per) local f = self.HealthFrms[1] f:SetWidth (per * cw + 1) f.texture:SetTexture (1 - per, per, 0, .5) local plTarget = UnitName ("target") for index, player in ipairs (self.Players) do local but = player.But if but then local unit = player.Unit local h = UnitIsDeadOrGhost (unit) and 0 or UnitHealth (unit) local per = min (h / UnitHealthMax (unit), 1) -- Can overflow? local f = player.HealthFrm f:SetWidth (per * cw + 1) f.texture:SetTexture (.6 - per * .6, per * .6, 0, .7) local name = player.Name -- local cls = UnitClass (unit) or "" local targetStr = plTarget == name and "|cff8080ff>" or "" local combatStr = UnitAffectingCombat (unit) and "|cffff4040*" or "" local colStr = player.Dist < 41 and "|cffc0ffc0" or "|cff808080" local distStr = player.Dist ~= 999999 and format ("%d yds", player.Dist) or "" local s = format ("%s%s%s%s %s", targetStr, combatStr, colStr, name, distStr) self.FStrs[player.FrmI]:SetText (s) end end if lchanged then local win = self.Win if lockDown then win:SetTitle ("|cffff2020Team:") else win:SetTitle ("Team:") end end --PAIDE! end ------------------------------------------------------------------------------- -- EOF