-- -- WoWLiCe Interface Addon for World of Warcraft -- Loosely based on LiCe for ircII-EPIC4 by SrfRoG -- Copyright (c)2008 Alex Quintana -- LiCe Copyright (C) 1993-2000 SrfRoG (cag@codehack.com) -- -- 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, write to the Free Software -- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -- -- -- All code by Alex Quintana, unless specified. -- props go out to SrfRoG, hop, HSOC etc. (wonder if any of them play WoW, heh) -- -- Recursion ID's and the functions/hooks that use them: -- 55 - lice\Events.lua: ChatEdit_SendText(editBox, AddHistory) -- Binding Variables BINDING_HEADER_WOWLICE = "LiCe"; BINDING_NAME_LICE_SHOW_FRIENDS = "Show Online Friends"; BINDING_NAME_LICE_SHOW_ALL_FRIENDS = "Show All Friends"; BINDING_NAME_LICE_NOIG = "Interactive Ignore Removal"; BINDING_NAME_LICE_CH_SURF_F = "Channel Surf Forward"; BINDING_NAME_LICE_CH_SURF_B = "Channel Surf Backward"; BINDING_NAME_LICE_SPOTLIGHT = "Inventory Spotlight"; LiCe = {}; LiCe.Theme = {}; -- note: this is a table filled with DPS values, it is not a LiCe module LiCe.Damage = 0; -- variables LiCe.DEBUG = true; LiCe.REQUIRED_ALEXLIB = { 0, 1, 26 }; LiCe.MWheel = 0; LiCe.SSaverPass = 0; local eventsToRegister = { "VARIABLES_LOADED", "UPDATE_BINDINGS", "CHAT_MSG_CHANNEL_LIST", "CHAT_MSG_CHANNEL_NOTICE", "WHO_LIST_UPDATE", "PLAYER_ENTERING_WORLD", "FRIENDLIST_UPDATE", "CHAT_MSG_SYSTEM", "CHAT_MSG_WHISPER", "PLAYER_ALIVE", "PLAYER_UNGHOST", "COMBAT_LOG_EVENT_UNFILTERED", "PLAYER_ENTER_COMBAT", "PLAYER_LEAVE_COMBAT" }; LiCe.AutoReplyEvents = { "CHAT_MSG_CHANNEL", "CHAT_MSG_PARTY", "CHAT_MSG_GUILD", "CHAT_MSG_OFFICER", "CHAT_MSG_EMOTE", "CHAT_MSG_TEXT_EMOTE", "CHAT_MSG_SAY", "CHAT_MSG_YELL" }; LiCe.Stacks = {}; -- note: for current use, this is ok. If we start using it for anything else, we'll need to make an array. LiCe.ClassString = "Warrior Paladin Death Knight Mage Warlock Priest Shaman Hunter Rogue Druid"; -- for key bindings: convert a shifted character into SHIFT- LiCe.ShiftChars = {} LiCe.ShiftChars["~"] = "`"; LiCe.ShiftChars["!"] = "1"; LiCe.ShiftChars["@"] = "2"; LiCe.ShiftChars["#"] = "3"; LiCe.ShiftChars["$"] = "4"; LiCe.ShiftChars["%"] = "5"; LiCe.ShiftChars["^"] = "6"; LiCe.ShiftChars["&"] = "7"; LiCe.ShiftChars["*"] = "8"; LiCe.ShiftChars["("] = "9"; LiCe.ShiftChars[")"] = "0"; LiCe.ShiftChars["+"] = "="; LiCe.ShiftChars["{"] = "["; LiCe.ShiftChars["}"] = "]"; LiCe.ShiftChars["|"] = "\\"; LiCe.ShiftChars[":"] = ";"; LiCe.ShiftChars["\""] = "'"; LiCe.ShiftChars["<"] = ","; LiCe.ShiftChars[">"] = "."; LiCe.ShiftChars["?"] = "/"; -- what's this doing here? well alexlib is a bit messy right now.. i will move it when i sort out AlexLib proper function AlexLib:FindBinding(char) if (strmatch(char, "%u")) then return "SHIFT-"..strlower(char); elseif (LiCe.ShiftChars[char]) then return "SHIFT-"..LiCe.ShiftChars[char]; else return strupper(char); end end -- the reverse of the above function. -1 means the key binding modifier was control or alt or something inappropriate function AlexLib:ReverseBinding(b) if (not b) then return; end if (strmatch(b, "^SHIFT%-%u")) then return select(3, strfind(b, "^SHIFT%-(%u)")); elseif (strmatch(b, "^SHIFT%-")) then local key = strlower(select(3, strfind(b, "^SHIFT%-(.)"))); for k,v in pairs(LiCe.ShiftChars) do if (v==key) then key = k; break; end end return key; elseif (strmatch(b, "^.$")) then return strlower(b); else return -1; end end -- function LiCe:DumpStackedMessages(prefix) local itemstring=""; while (LiCe.Stacks[prefix][1]) do local item = table.remove(LiCe.Stacks[prefix], 1); if (itemstring=="") then itemstring = item; else itemstring = itemstring..", "..item; end end return prefix..": "..itemstring; end -- OnLoad handler function LiCe:OnLoad() -- Check AlexLib version for i = 1, 3 do if (AlexLib.VERSION[i] < LiCe.REQUIRED_ALEXLIB[i]) then LiCe:LoadFailedAlexLib(); return; end end -- register events AlexLib:RegisterEvents(eventsToRegister); AlexLib:RegisterEvents(LiCe.AutoReplyEvents); -- register slash commands AlexLib:NewSlashCmd("LICEALIAS", function(msg) LiCe.Alias:SlashAlias(msg); end, "/alias"); AlexLib:NewSlashCmd("CHAT_AFK", function(msg) LiCe:AFK(msg); end, "/afk"); AlexLib:NewSlashCmd("LICEAUTOREPLY", function(words) LiCe:AutoReply(words); end, "/ar"); AlexLib:NewSlashCmd("CHAT_DND", function(msg) LiCe:DND(msg); end, "/dnd"); AlexLib:NewSlashCmd("LICECTOG", function(args) LiCe.Settings:CToggle(args); end, "/ctog"); AlexLib:NewSlashCmd("LICEERASE", function(args) LiCe.Play:Erase(args); end, "/erase"); AlexLib:NewSlashCmd("FRIENDS", function(args) LiCe.Friends:Friend(args); end, { "/friend" }); AlexLib:NewSlashCmd("LICEIGNORE", function(args) LiCe.Ignore:Ignore(args); end, { "/ig", "/ignore" }); AlexLib:NewSlashCmd("LICEMTOG", function(options) LiCe.Settings:MToggle(options); end, "/mtog"); AlexLib:NewSlashCmd("LICENOIG", function(args) LiCe.Ignore:NoIg(args); end, "/noig"); AlexLib:NewSlashCmd("LICEOOPS", function(args) LiCe:Oops(args); end, "/oops"); AlexLib:NewSlashCmd("LICEPLAY", function(args) LiCe.Play:Play(args); end, "/play"); AlexLib:NewSlashCmd("LICERESET", function() LiCe.Settings:Reset(); end, "/resetlice"); AlexLib:NewSlashCmd("LICESENSORS", function(ids) LiCe.Settings:Sensors(ids); end, "/sensors"); AlexLib:NewSlashCmd("LICESET", function(args) LiCe.Settings:Set(args) end, "/set"); AlexLib:NewSlashCmd("TIME", function() LiCe:PrintTime() end, "/time"); AlexLib:NewSlashCmd("LICETOG", function(options) LiCe.Settings:Toggle(options); end, "/tog"); AlexLib:NewSlashCmd("LICEQUERY", function(args) LiCe:Query(args); end, "/query"); AlexLib:NewSlashCmd("LICEWP", function(args) LiCe.GPS:WayPoint(args); end, "/wp"); AlexLib:NewSlashCmd("LICESV", function(to) LiCe:ShowVersion(to); end, "/sv"); AlexLib:NewSlashCmd("LICETHEME", function(name) LiCe:SlashTheme(name); end, "/theme"); end function LiCe:LoadTheme() local theme; if (LiCe_Settings.Theme) then theme = LiCe_Settings.Theme; else theme = "WoWLiCe"; end try(LiCe.Theme[theme], LiCe.Theme); end function LiCe:SlashTheme(name) local colwidth = 4; -- this is temporary, should be a /sensor or something if (not name or name=="") then local list = ""; local cnt = 1; LiCe:Print("DEFAULTMSG", "Available themes:"); for k in pairs(LiCe.Theme) do list = list.." "..k; if (cnt >= colwidth) then LiCe:Print("DEFAULTMSG", list); list = ""; cnt = 1; else cnt = cnt + 1; end end if (list ~= "") then LiCe:Print("DEFAULTMSG", list); end else for k in pairs(LiCe.Theme) do if (strmatch(k, "^"..AlexLib:MakePatternIgnoreCase(name)..".*")) then LiCe_Settings.LastTheme = LiCe_Settings.Theme; LiCe_Settings.Theme = k; LiCe:LoadTheme(); return; end end LiCe:Print("ERROR", "No theme matching \""..name.."\" found."); end end function LiCe:ShowVersion(to) if (not to or to == "") then LiCe:Print("INFO", "|cff55ff55LiCe|r v|cffffffff"..GetAddOnMetadata("WoWLiCe", "Version").."|r |cffffffff(|rusing theme: "..LiCe_Settings.Theme.."|cffffffff)"); else SendChatMessage("LiCe v"..GetAddOnMetadata("WoWLiCe", "Version").." (using theme: "..LiCe_Settings.Theme..")", "WHISPER", nil, to); end end function LiCe:UIFade(value) AlexLib:NewTimer(90, function(value) local a = UIParent:GetAlpha(); if (value < 1) then if (a > value) then UIParent:SetAlpha(a - .005); else return; end elseif (value == 1) then if (a < 1) then UIParent:SetAlpha(a + .005); else LiCe:StartScreenSaver(); return; end end AlexLib:NewTimer(10, LiCe:UIFade(value)); end, value); end -- turns the screen saver on (fade out UI marginally every 20 minutes, then wait 30 seconds, fade it back in) function LiCe:StartScreenSaver() AlexLib:ClearTimer("screensaver"); AlexLib:NewTimer(1200000, function() --AlexLib:NewTimer(var * 3600, function() LiCe:UIFade(.9); AlexLib:NewTimer(30000, function() LiCe:UIFade(1); end, nil, "activescreensaver"); end, nil, "screensaver"); end -- Load Failed because of AlexLib being too old function LiCe:LoadFailedAlexLib() local v=""; for i = 1, 3 do v = v..AlexLib.VERSION[i]; if (i~=3) then v = v.."."; end end DEFAULT_CHAT_FRAME:AddMessage("## Incompatible version of AlexLib found: v"..v); v=""; for i = 1, 3 do v = v..LiCe.REQUIRED_ALEXLIB[i]; if (i~=3) then v = v.."."; end end DEFAULT_CHAT_FRAME:AddMessage("## In order to work, WoWLiCe needs AlexLib version "..v.." or higher."); DEFAULT_CHAT_FRAME:AddMessage("## Please update your AlexLib and try again."); message("LiCe has detected that you have an outdated version of AlexLib. Please see the chat frame for details. WoWLiCe will be unloaded now."); LiCe = nil; end -- OnEvent handler function LiCe:OnEvent(self, event, ...) --AlexLib:Print(event); if (LiCe.EventHandlers[event]) then local f = LiCe.EventHandlers[event]; f(self, event, ...); end end function LiCe:PrintTime() LiCe:Print("INFO", "The time is now "..LiCe:GetClock().."."); end function LiCe:GetClock() if (LiCe_Settings.Set.CLOCK_FORMAT~="") then return date(LiCe_Settings.Set.CLOCK_FORMAT); elseif (LiCe_Settings.Set.CLOCK_24HOUR) then return date("%H:%M"); else return strupper(date("%I:%M %p")); end end -- comes in handy when debugging inside of the addmessage hook. -- This will also throw an error if OrigAddMessage is nil, which is useful. function LiCe:DPrint(...) DEFAULT_CHAT_FRAME:OrigAddMessage(...) end -- LiCe IsChannelOwner (is user a channel owner?) function LiCe:IsChannelOwner(chan, user) if (not LiCe.ChannelNames[chan]) then return nil; end if (not user or user=="") then user = UnitName("player"); end for i, v in ipairs(LiCe.ChannelNames[chan]) do if ("*"..user==v) then return true; end end return nil; end -- LiCe IsChannelMod (is user a channel moderator?) function LiCe:IsChannelMod(chan, user) if (not LiCe.ChannelNames[chan]) then return nil; end if (not user or user=="") then user = UnitName("player"); end for i, v in ipairs(LiCe.ChannelNames[chan]) do if ("@"..user==v) then return true; end end return nil; end -- LiCe gsub (to convert %c into |cff and %r into |r) function LiCe:gsubc(text, f, r, c) text = gsub(text, "%%c", "\124cff"); text = gsub(text, "%%r", "\124r"); if (f and r) then text = gsub(text, f, r, c); end return text; end -- LiCe Get colors function function LiCe:GetColor(name) local r, g, b; local a = 1; if (LiCe_Settings.Set["COLOR_"..strupper(name)]) then r, g, b = strsplit(" ", LiCe_Settings.Set["COLOR_"..strupper(name)]); else r, g, b = strsplit(" ", LiCe_Settings.Set.COLOR_DEFAULTMSG); end return r, g, b, a; end -- LiCe Get Banner function function LiCe:GetBanner(color, g, b) local r; if (tonumber(color)) then r = color; else r, g, b = LiCe:GetColor(color); end local banner = LiCe_Settings.Set.BANNER; if (banner~="") then banner = banner.." "; end return AlexLib:RGBtoHex(r, g, b, 1)..banner.."|r"; end -- LiCe Print function function LiCe:Print(bannercolor, txt, r, g, b, nostack) if (not r) then r, g, b = LiCe:GetColor("DEFAULTMSG"); end local banner; if (strmatch(bannercolor, "^%x%x%x%x%x%x%x%x$")) then banner = LiCe_Settings.Set.BANNER; if (banner~="") then banner = banner.." "; end banner = "|c"..bannercolor..banner.."|r"; elseif (bannercolor=="DEFAULT") then banner = LiCe_Settings.Set.BANNER; else banner = LiCe:GetBanner(bannercolor); end if (noprint) then return banner.." "..txt; else DEFAULT_CHAT_FRAME:AddMessage(banner..txt, r, g, b, nil, nil, nostack); end end -- aeq/2k8