├── media ├── fonts │ ├── Luna.ttf │ ├── Vixar.TTF │ ├── exocet.ttf │ ├── Aldrich.ttf │ ├── Bangers.ttf │ ├── Bazooka.ttf │ ├── Celestia.ttf │ ├── DorisPP.ttf │ ├── Gentium.ttf │ ├── Iceland.ttf │ ├── Optimus.ttf │ ├── budhand.ttf │ ├── Enigmatic.ttf │ ├── FasterOne.ttf │ ├── Fitzgerald.ttf │ ├── Inconsolata.ttf │ ├── MetalLord.ttf │ ├── SansNarrow.ttf │ ├── TradeWinds.ttf │ ├── VeraSerif.ttf │ ├── Yellowjacket.ttf │ └── LiberationSans.ttf ├── textures │ ├── Bars.tga │ ├── Dabs.tga │ ├── Frost.tga │ ├── Glaze.tga │ ├── Gloss.tga │ ├── Lyfe.tga │ ├── Perl2.tga │ ├── Rocks.tga │ ├── Runes.tga │ ├── Wisps.tga │ ├── Xeon.tga │ ├── Armory.tga │ ├── BantoBar.tga │ ├── Diagonal.tga │ ├── Glamour.tga │ ├── Glamour2.tga │ ├── Glamour3.tga │ ├── Glamour4.tga │ ├── Glamour5.tga │ ├── Glamour6.tga │ ├── Glamour7.tga │ ├── Graphite.tga │ ├── Healbot.tga │ ├── LiteStep.tga │ ├── Otravi.tga │ ├── Skewed.tga │ ├── Smooth.tga │ ├── Striped.tga │ ├── Aluminium.tga │ ├── Minimalist.tga │ └── Ruben.tga └── media.lua ├── README.md ├── Punschrulle.toc ├── Punschrulle.lua └── core ├── Entity.lua ├── Bar.lua ├── Tables.lua ├── Mirror.lua └── Castbar.lua /media/fonts/Luna.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Luna.ttf -------------------------------------------------------------------------------- /media/fonts/Vixar.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Vixar.TTF -------------------------------------------------------------------------------- /media/fonts/exocet.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/exocet.ttf -------------------------------------------------------------------------------- /media/fonts/Aldrich.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Aldrich.ttf -------------------------------------------------------------------------------- /media/fonts/Bangers.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Bangers.ttf -------------------------------------------------------------------------------- /media/fonts/Bazooka.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Bazooka.ttf -------------------------------------------------------------------------------- /media/fonts/Celestia.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Celestia.ttf -------------------------------------------------------------------------------- /media/fonts/DorisPP.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/DorisPP.ttf -------------------------------------------------------------------------------- /media/fonts/Gentium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Gentium.ttf -------------------------------------------------------------------------------- /media/fonts/Iceland.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Iceland.ttf -------------------------------------------------------------------------------- /media/fonts/Optimus.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Optimus.ttf -------------------------------------------------------------------------------- /media/fonts/budhand.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/budhand.ttf -------------------------------------------------------------------------------- /media/textures/Bars.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Bars.tga -------------------------------------------------------------------------------- /media/textures/Dabs.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Dabs.tga -------------------------------------------------------------------------------- /media/textures/Frost.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Frost.tga -------------------------------------------------------------------------------- /media/textures/Glaze.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glaze.tga -------------------------------------------------------------------------------- /media/textures/Gloss.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Gloss.tga -------------------------------------------------------------------------------- /media/textures/Lyfe.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Lyfe.tga -------------------------------------------------------------------------------- /media/textures/Perl2.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Perl2.tga -------------------------------------------------------------------------------- /media/textures/Rocks.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Rocks.tga -------------------------------------------------------------------------------- /media/textures/Runes.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Runes.tga -------------------------------------------------------------------------------- /media/textures/Wisps.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Wisps.tga -------------------------------------------------------------------------------- /media/textures/Xeon.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Xeon.tga -------------------------------------------------------------------------------- /media/fonts/Enigmatic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Enigmatic.ttf -------------------------------------------------------------------------------- /media/fonts/FasterOne.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/FasterOne.ttf -------------------------------------------------------------------------------- /media/fonts/Fitzgerald.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Fitzgerald.ttf -------------------------------------------------------------------------------- /media/fonts/Inconsolata.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Inconsolata.ttf -------------------------------------------------------------------------------- /media/fonts/MetalLord.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/MetalLord.ttf -------------------------------------------------------------------------------- /media/fonts/SansNarrow.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/SansNarrow.ttf -------------------------------------------------------------------------------- /media/fonts/TradeWinds.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/TradeWinds.ttf -------------------------------------------------------------------------------- /media/fonts/VeraSerif.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/VeraSerif.ttf -------------------------------------------------------------------------------- /media/textures/Armory.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Armory.tga -------------------------------------------------------------------------------- /media/textures/BantoBar.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/BantoBar.tga -------------------------------------------------------------------------------- /media/textures/Diagonal.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Diagonal.tga -------------------------------------------------------------------------------- /media/textures/Glamour.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glamour.tga -------------------------------------------------------------------------------- /media/textures/Glamour2.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glamour2.tga -------------------------------------------------------------------------------- /media/textures/Glamour3.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glamour3.tga -------------------------------------------------------------------------------- /media/textures/Glamour4.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glamour4.tga -------------------------------------------------------------------------------- /media/textures/Glamour5.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glamour5.tga -------------------------------------------------------------------------------- /media/textures/Glamour6.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glamour6.tga -------------------------------------------------------------------------------- /media/textures/Glamour7.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Glamour7.tga -------------------------------------------------------------------------------- /media/textures/Graphite.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Graphite.tga -------------------------------------------------------------------------------- /media/textures/Healbot.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Healbot.tga -------------------------------------------------------------------------------- /media/textures/LiteStep.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/LiteStep.tga -------------------------------------------------------------------------------- /media/textures/Otravi.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Otravi.tga -------------------------------------------------------------------------------- /media/textures/Skewed.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Skewed.tga -------------------------------------------------------------------------------- /media/textures/Smooth.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Smooth.tga -------------------------------------------------------------------------------- /media/textures/Striped.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Striped.tga -------------------------------------------------------------------------------- /media/fonts/Yellowjacket.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/Yellowjacket.ttf -------------------------------------------------------------------------------- /media/textures/Aluminium.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Aluminium.tga -------------------------------------------------------------------------------- /media/textures/Minimalist.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/textures/Minimalist.tga -------------------------------------------------------------------------------- /media/fonts/LiberationSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Attero/Punschrulle/HEAD/media/fonts/LiberationSans.ttf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Punschrulle 2 | A highly customizable player castbar for the World of Warcraft 1.12.1 Client 3 | 4 | Contact: Attero@Ely 5 | -------------------------------------------------------------------------------- /Punschrulle.toc: -------------------------------------------------------------------------------- 1 | ## Interface: 11200 2 | ## Title: Punschrulle Castbar 1.0 3 | ## Notes: Highly customizable castbar. 4 | ## Author: Attero 5 | ## Version: 1.0 6 | ## Dependencies: 7 | ## SavedVariables: PunschrulleDB 8 | ## SavedVariablesPerCharacter: PunschrulleProfile 9 | 10 | Punschrulle.lua 11 | media\media.lua 12 | core\Tables.lua 13 | core\Options.lua 14 | core\Entity.lua 15 | core\Bar.lua 16 | core\Castbar.lua 17 | core\Mirror.lua -------------------------------------------------------------------------------- /media/media.lua: -------------------------------------------------------------------------------- 1 | --To add a new font or texture, simply put them in the same folder as the others and add it to the appropriate list below. 2 | --Do note that the file paths are case sensitive. 3 | 4 | PunschrulleFonts = { 5 | Aldrich = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Aldrich.ttf", 6 | Bangers = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Bangers.ttf", 7 | Bazooka = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Bazooka.ttf", 8 | Celestia = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Celestia.ttf", 9 | DorisPP = "Interface\\AddOns\\Punschrulle\\media\\fonts\\DorisPP.ttf", 10 | Enigmatic = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Enigmatic.ttf", 11 | FasterOne = "Interface\\AddOns\\Punschrulle\\media\\fonts\\FasterOne.ttf", 12 | Fitzgerald = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Fitzgerald.ttf", 13 | Gentium = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Gentium.ttf", 14 | Iceland = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Iceland.ttf", 15 | Inconsolata = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Inconsolata.ttf", 16 | LiberationSans = "Interface\\AddOns\\Punschrulle\\media\\fonts\\LiberationSans.ttf", 17 | Luna = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Luna.ttf", 18 | MetalLord = "Interface\\AddOns\\Punschrulle\\media\\fonts\\MetalLord.ttf", 19 | Optimus = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Optimus.ttf", 20 | SansNarrow = "Interface\\AddOns\\Punschrulle\\media\\fonts\\SansNarrow.ttf", 21 | TradeWinds = "Interface\\AddOns\\Punschrulle\\media\\fonts\\TradeWinds.ttf", 22 | VeraSerif = "Interface\\AddOns\\Punschrulle\\media\\fonts\\VeraSerif.ttf", 23 | Vixar = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Vixar.ttf", 24 | Yellowjacket = "Interface\\AddOns\\Punschrulle\\media\\fonts\\Yellowjacket.ttf", 25 | Exocet = "Interface\\AddOns\\Punschrulle\\media\\fonts\\exocet.ttf", 26 | Budhand = "Interface\\AddOns\\Punschrulle\\media\\fonts\\budhand.ttf", 27 | ArialNarrow = "Fonts\\ARIALN.TTF", 28 | Skurri = "Fonts\\skurri.ttf", 29 | Morpheus = "Fonts\\MORPHEUS.ttf", 30 | } 31 | 32 | PunschrulleTextures = { 33 | Aluminium = "Interface\\AddOns\\Punschrulle\\media\\textures\\Aluminium", 34 | Armory = "Interface\\AddOns\\Punschrulle\\media\\textures\\Armory", 35 | BantoBar = "Interface\\AddOns\\Punschrulle\\media\\textures\\BantoBar", 36 | Bars = "Interface\\AddOns\\Punschrulle\\media\\textures\\Bars", 37 | Blizzard = "Interface\\TargetingFrame\\UI-StatusBar", 38 | Dabs = "Interface\\AddOns\\Punschrulle\\media\\textures\\Dabs", 39 | Diagonal = "Interface\\AddOns\\Punschrulle\\media\\textures\\Diagonal", 40 | Frost = "Interface\\AddOns\\Punschrulle\\media\\textures\\Frost", 41 | Glamour = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glamour", 42 | Glamour2 = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glamour2", 43 | Glamour3 = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glamour3", 44 | Glamour4 = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glamour4", 45 | Glamour5 = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glamour5", 46 | Glamour6 = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glamour6", 47 | Glamour7 = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glamour7", 48 | Glaze = "Interface\\AddOns\\Punschrulle\\media\\textures\\Glaze", 49 | Gloss = "Interface\\AddOns\\Punschrulle\\media\\textures\\Gloss", 50 | Graphite = "Interface\\AddOns\\Punschrulle\\media\\textures\\Graphite", 51 | Healbot = "Interface\\AddOns\\Punschrulle\\media\\textures\\Healbot", 52 | LiteStep = "Interface\\AddOns\\Punschrulle\\media\\textures\\LiteStep", 53 | Lyfe = "Interface\\AddOns\\Punschrulle\\media\\textures\\Lyfe", 54 | Minimalist = "Interface\\AddOns\\Punschrulle\\media\\textures\\Minimalist", 55 | Otravi = "Interface\\AddOns\\Punschrulle\\media\\textures\\Otravi", 56 | Perl2 = "Interface\\AddOns\\Punschrulle\\media\\textures\\Perl2", 57 | Rocks = "Interface\\AddOns\\Punschrulle\\media\\textures\\Rocks", 58 | Ruben = "Interface\\AddOns\\Punschrulle\\media\\textures\\Ruben", 59 | Runes = "Interface\\AddOns\\Punschrulle\\media\\textures\\Runes", 60 | Skewed = "Interface\\AddOns\\Punschrulle\\media\\textures\\Skewed", 61 | Smooth = "Interface\\AddOns\\Punschrulle\\media\\textures\\Smooth", 62 | Striped = "Interface\\AddOns\\Punschrulle\\media\\textures\\Striped", 63 | Wisps = "Interface\\AddOns\\Punschrulle\\media\\textures\\Wisps", 64 | Xeon = "Interface\\AddOns\\Punschrulle\\media\\textures\\Xeon" 65 | } -------------------------------------------------------------------------------- /Punschrulle.lua: -------------------------------------------------------------------------------- 1 | local PunschDBVer = 13 2 | PunschrulleVersion = "1.0" 3 | 4 | function Punschrulle_Initialize() 5 | Punschrulle = CreateFrame("Frame", nil, UIParent) 6 | 7 | SLASH_PUNSCHRULLE1 = "/punsch"; 8 | SLASH_PUNSCHRULLE2 = "/punschrulle"; 9 | SlashCmdList["PUNSCHRULLE"] = Punschrulle_Command; 10 | 11 | Punschrulle:SetScript("OnEvent",Punschrulle_OnEvent) 12 | Punschrulle:RegisterEvent("ADDON_LOADED"); 13 | end 14 | 15 | function Punschrulle_OnEvent() 16 | if (event == "ADDON_LOADED") then 17 | if (arg1 == "Punschrulle") then 18 | Punschrulle:UnregisterEvent("ADDON_LOADED") 19 | 20 | if PunschrulleDB==nil then 21 | Punschrulle_Setdefaults(); 22 | elseif (PunschrulleDB.DBVer~=PunschDBVer) then 23 | DEFAULT_CHAT_FRAME:AddMessage("|cFF7373E6Punschrulle:|r DB outdated; settings reset to default"); 24 | Punschrulle_Setdefaults(); 25 | end 26 | 27 | if PunschrulleProfile==nil then 28 | PunschrulleProfile = "Default" 29 | elseif not PunschrulleDB.Profiles[PunschrulleProfile] then 30 | PunschrulleProfile = "Default" 31 | DEFAULT_CHAT_FRAME:AddMessage("|cFF7373E6Punschrulle:|r Profile not found, using profile " .. PunschrulleDB.Profiles[PunschrulleProfile].Name) 32 | end 33 | 34 | if not PunschrulleDB.Profiles[PunschrulleProfile].MuteWelcomeMessage then 35 | DEFAULT_CHAT_FRAME:AddMessage("|cFF7373E6Punschrulle|r v" .. PunschrulleVersion .. " by Attero. /punsch"); 36 | end 37 | 38 | Punsch_Castbar_Create() 39 | Punsch_Mirror_Create() 40 | --Punsch_ECB_Create() 41 | Punsch_Entity_UpdateAll() 42 | end 43 | end 44 | end 45 | 46 | function Punschrulle_Command(msg) 47 | msg = strlower(msg) 48 | local cmd, subCmd = Punschrulle_GetCmd(msg); 49 | if(cmd=="lock") then 50 | Punsch_Entity_ToggleLock(); 51 | elseif(cmd=="config") then 52 | Punsch_Option_MainWindow_Toggle() 53 | elseif(cmd=="test") then 54 | ManaTickTest() 55 | elseif(cmd=="default") then 56 | DEFAULT_CHAT_FRAME:AddMessage("|cFF7373E6Punschrulle:|r Reset to defaults"); 57 | Punschrulle_Setdefaults(); 58 | else 59 | DEFAULT_CHAT_FRAME:AddMessage("|cFF7373E6Punschrulle:|r /punsch config,default,lock"); 60 | end 61 | end 62 | 63 | --[[ 64 | ManaTickTest: 65 | This is a test designed to ensure the mana tickrate of the server is correct. Stock MANGoS is broken. 66 | Usage: Empty your manapool, type /punsch test. 67 | If total error is around 0 at the point when you reach a full mana pool, the server is decent and evocation channelticks can be made to work. (they arent implemented atm tho) 68 | --]] 69 | function ManaTickTest() 70 | if not ManaTestStartTest then 71 | ManaTestStartTest = true 72 | DEFAULT_CHAT_FRAME:AddMessage("Started tracking of mana regeneration ticks ") 73 | local m = CreateFrame("Frame","ManaTickTestFrame",UIParent) 74 | m:RegisterEvent("UNIT_MANA") 75 | ManaTestCurrentMana = UnitMana("player") 76 | ManaTestTickError = 0 77 | ManaTestTickCount = 0 78 | m:SetScript("OnEvent", function () 79 | if ManaTestCurrentMana < UnitMana("player") then 80 | if ManaTestLastTickTime then 81 | ManaTestTickError = ManaTestTickError + GetTime()-ManaTestLastTickTime - 2 82 | DEFAULT_CHAT_FRAME:AddMessage( 83 | "mana gain at " .. string.format("%.4f",GetTime()) .. 84 | " Time since last: " .. string.format("%.4f",GetTime()-ManaTestLastTickTime) .. 85 | " Total Error: " .. string.format("%.4f",ManaTestTickError) .. 86 | " Avg Error: " .. string.format("%.4f",ManaTestTickError/ManaTestTickCount)) 87 | else 88 | DEFAULT_CHAT_FRAME:AddMessage("mana gain. Initial tick at " .. GetTime()) 89 | end 90 | ManaTestLastTickTime = GetTime() 91 | ManaTestTickCount = ManaTestTickCount + 1 92 | end 93 | ManaTestCurrentMana = UnitMana("player") 94 | end) 95 | else 96 | DEFAULT_CHAT_FRAME:AddMessage("Reset tracking of mana regeneration ticks ") 97 | ManaTestCurrentMana = UnitMana("player") 98 | ManaTestTickError = 0 99 | ManaTestLastTickTime = nil 100 | end 101 | end 102 | 103 | function Punschrulle_GetCmd(msg) 104 | if(msg) then 105 | local a,b,c = strfind(msg, "(%S+)"); 106 | if(a) then 107 | return c, strsub(msg, b+2); 108 | else 109 | return ""; 110 | end 111 | end 112 | end 113 | 114 | function Punschrulle_Setdefaults() 115 | PunschrulleProfile = "Default" 116 | PunschrulleDB = { 117 | DBVer = PunschDBVer, 118 | Profiles = {} 119 | } 120 | PunschrulleDB.Profiles[PunschrulleProfile] = Punschrulle_DeepCopy(Punsch_Tables_ProfilePresets.Default,{}) 121 | PunschrulleDB.Profiles[PunschrulleProfile].Name = "Default" 122 | Punsch_Options_EditFrame_UpdateAll() 123 | Punsch_Entity_UpdateAll() 124 | end 125 | 126 | 127 | function Punschrulle_GetIcon(s) 128 | if type(s) == "number" then 129 | return GetMacroIconInfo(s) 130 | else 131 | return s 132 | end 133 | end 134 | 135 | function Punschrulle_GetFont(s) 136 | if PunschrulleFonts[s] then return PunschrulleFonts[s] end 137 | return GameFontNormal:GetFont() 138 | end 139 | 140 | function Punschrulle_GetTexture(s) 141 | if PunschrulleTextures[s] then return PunschrulleTextures[s] end 142 | return "" 143 | end 144 | 145 | function Punschrulle_DeepCopy(a, b) 146 | if type(a) ~= "table" or type(b) ~= "table" then 147 | return 148 | end 149 | for k,v in pairs(a) do 150 | if type(v) ~= "table" then 151 | b[k] = v; 152 | else 153 | local x = {} 154 | Punschrulle_DeepCopy(v, x); 155 | b[k] = x; 156 | end 157 | end 158 | return b; 159 | end 160 | 161 | Punschrulle_Initialize() -------------------------------------------------------------------------------- /core/Entity.lua: -------------------------------------------------------------------------------- 1 | PunschEntities = {} 2 | 3 | function Punsch_Entity_Create(e,db) 4 | e.self = CreateFrame("Frame","Punschrulle" .. e.Type,UIParent) 5 | e.self:SetFrameStrata("HIGH") 6 | 7 | e.ContentFrame = CreateFrame("Frame",nil,e.self) 8 | e.ContentFrame:SetAllPoints(e.self) 9 | 10 | e.BorderFrame = CreateFrame("Frame",nil,e.ContentFrame) 11 | 12 | e.selfBG = e.ContentFrame:CreateTexture(nil,"BACKGROUND") 13 | e.selfBG:SetAllPoints(e.self) 14 | 15 | e.selfFill = e.ContentFrame:CreateTexture(nil,"BORDER") 16 | e.selfFill:SetPoint("TOPLEFT", e.self) 17 | e.selfFill:SetHeight(db.Height) 18 | 19 | e.self:SetPoint(db.Anchor.Point,UIParent,db.Anchor.rPoint,db.Anchor.X,db.Anchor.Y) 20 | end 21 | 22 | function Punsch_Entity_UpdateAll() 23 | for _,e in pairs(PunschEntities) do 24 | Punsch_Entity_Update(e,PunschrulleDB.Profiles[PunschrulleProfile]["Entities"][e.Type]) 25 | end 26 | end 27 | 28 | function Punsch_Entity_Update(e,db) 29 | e.self:ClearAllPoints() 30 | 31 | e.self:SetWidth(db.Width) 32 | e.self:SetHeight(db.Height) 33 | e.selfFill:SetHeight(db.Height) 34 | e.selfBG:SetTexture(db.Bg.r, 35 | db.Bg.g, 36 | db.Bg.b, 37 | db.Bg.a) 38 | e.selfFill:SetTexture(Punschrulle_GetTexture(db.Texture)) 39 | if db.Fill then 40 | e.selfFill:SetVertexColor(db.Fill.r, 41 | db.Fill.g, 42 | db.Fill.b, 43 | db.Fill.a) 44 | end 45 | 46 | if db.Border.Show then 47 | e.BorderFrame:SetPoint("TOPLEFT",e.ContentFrame,"TOPLEFT",-db.Border.Padding,db.Border.Padding) 48 | e.BorderFrame:SetPoint("BOTTOMRIGHT",e.ContentFrame,"BOTTOMRIGHT",db.Border.Padding,-db.Border.Padding) 49 | e.BorderFrame:SetBackdrop({ 50 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", 51 | edgeSize = db.Border.Size}) 52 | e.BorderFrame:SetBackdropBorderColor(db.Border.r, db.Border.g, db.Border.b, db.Border.a) 53 | if db.Border.OnTop then 54 | e.BorderFrame:SetFrameStrata("DIALOG") 55 | else 56 | e.BorderFrame:SetFrameStrata("MEDIUM") 57 | end 58 | else 59 | e.BorderFrame:SetBackdrop(nil) 60 | end 61 | 62 | if e.Type == "Castbar" then 63 | Punsch_Castbar_Update(e) 64 | elseif e.Type == "Mirror" then 65 | Punsch_Mirror_UpdateMirrors(e) 66 | elseif e.Type == "ECB" then 67 | Punsch_ECB_UpdateECBs(e) 68 | end 69 | end 70 | 71 | 72 | function Punsch_Entity_CreateUnlock(e) 73 | e.UnlockFrame = CreateFrame("Frame",nil,e.self) 74 | e.UnlockFrame:SetFrameStrata("DIALOG") 75 | e.UnlockFrame:SetAllPoints(e.self) 76 | --e.UnlockFrame.parent = e 77 | 78 | e.unlockBG = e.UnlockFrame:CreateTexture(nil,"ARTWORK") 79 | e.unlockBG:SetAllPoints(e.UnlockFrame) 80 | e.unlockBG:SetTexture(0.1,1,0.3,0.4) 81 | 82 | e.unlockText = e.UnlockFrame:CreateFontString(nil,"OVERLAY") 83 | e.unlockText:SetFont(GameFontHighlight:GetFont(), 10) 84 | e.unlockText:SetText(e.Type) 85 | e.unlockText:SetPoint("CENTER", e.UnlockFrame) 86 | 87 | e.UnlockFrame:SetScript("OnMouseDown", Punsch_Entity_Startmove) 88 | e.UnlockFrame:SetScript("OnMouseUp", Punsch_Entity_Stopmove) 89 | e.UnlockFrame:SetScript("OnHide", Punsch_Entity_Stopmove) 90 | end 91 | 92 | function Punsch_Entity_Startmove() 93 | this:GetParent().IsMovingOrSizing = 1 94 | this:GetParent():StartMoving() 95 | end 96 | 97 | function Punsch_Entity_GetRelativePoint(e,point,relativeTo,relativePoint) 98 | local x1,y1 = Punsch_Entity_GetPoint(e,point) 99 | local x2,y2 = Punsch_Entity_GetPoint(relativeTo,relativePoint) 100 | return x1-x2,y1-y2 101 | end 102 | 103 | function Punsch_Entity_GetPoint(e,point) 104 | if point == "TOP" then 105 | local x = e:GetCenter() 106 | return x, e:GetTop() 107 | elseif point == "RIGHT" then 108 | local _,y = e:GetCenter() 109 | return e:GetRight(), y 110 | elseif point == "BOTTOM" then 111 | local x = e:GetCenter() 112 | return x, e:GetBottom() 113 | elseif point == "LEFT" then 114 | local _,y = e:GetCenter() 115 | return e:GetLeft(), y 116 | elseif point == "TOPLEFT" then 117 | return e:GetLeft(), e:GetTop() 118 | elseif point == "TOPRIGHT" then 119 | return e:GetRight(),e:GetTop() 120 | elseif point == "BOTTOMRIGHT" then 121 | return e:GetRight(),e:GetBottom() 122 | elseif point == "BOTTOMLEFT" then 123 | return e:GetLeft(),e:GetBottom() 124 | elseif point == "CENTER" then 125 | return e:GetCenter() 126 | end 127 | end 128 | 129 | function Punsch_Entity_UpdateToNewAnchor(e,db) 130 | local rTo 131 | if db.Anchor.rTo == "Castbar" then 132 | rTo = PunschEntities["Castbar"].self 133 | else 134 | rTo = UIParent 135 | end 136 | db.Anchor.X,db.Anchor.Y = Punsch_Entity_GetRelativePoint( 137 | e.self, 138 | db.Anchor.Point, 139 | rTo, 140 | db.Anchor.rPoint) 141 | 142 | if rTo == UIParent and e.isBar and e.ShowIcon then 143 | db.Anchor.X = db.Anchor.X - db.Height 144 | end 145 | end 146 | 147 | function Punsch_Entity_Stopmove() 148 | --save position here 149 | if this:GetParent().IsMovingOrSizing then 150 | this:GetParent():StopMovingOrSizing() 151 | local entityname = strsub(this:GetParent():GetName(), 12) 152 | Punsch_Entity_UpdateToNewAnchor(PunschEntities[entityname],PunschrulleDB.Profiles[PunschrulleProfile]["Entities"][entityname]) 153 | this:GetParent().IsMovingOrSizing = nil 154 | Punsch_Options_EditFrame_UpdateAll() 155 | end 156 | end 157 | 158 | Punsch_Entity_Locked = true 159 | function Punsch_Entity_ToggleLock() 160 | if Punsch_Entity_Locked then 161 | Punsch_Entity_Locked = false 162 | Punsch_Entity_UnlockAll() 163 | else 164 | Punsch_Entity_Locked = true 165 | Punsch_Entity_LockAll() 166 | end 167 | end 168 | 169 | function Punsch_Entity_UnlockAll() 170 | for _,e in pairs(PunschEntities) do 171 | if not e.UnlockFrame then Punsch_Entity_CreateUnlock(e) end 172 | e.UnlockFrame:Show() 173 | e.self:SetMovable(true) 174 | e.UnlockFrame:EnableMouse(true) 175 | end 176 | end 177 | 178 | function Punsch_Entity_LockAll() 179 | for _,e in pairs(PunschEntities) do 180 | if not e.UnlockFrame then Punsch_Entity_CreateUnlock(e) end 181 | e.UnlockFrame:Hide() 182 | e.self:SetMovable(false) 183 | e.UnlockFrame:EnableMouse(false) 184 | end 185 | end 186 | -------------------------------------------------------------------------------- /core/Bar.lua: -------------------------------------------------------------------------------- 1 | function Punsch_Bar_Create(e,db) 2 | Punsch_Entity_Create(e,db) 3 | e.TextFrame = CreateFrame("Frame",nil,e.ContentFrame) 4 | e.TextFrame:SetFrameStrata("DIALOG") 5 | e.TextFrame:SetAllPoints(e.ContentFrame) 6 | 7 | e.text1 = e.TextFrame:CreateFontString(nil,"OVERLAY") 8 | e.text1:SetFont(GameFontNormal:GetFont(), 10) 9 | e.text1:SetJustifyH("LEFT") 10 | e.text1:SetText("Frostbolt") 11 | 12 | e.text2 = e.TextFrame:CreateFontString(nil,"OVERLAY") 13 | e.text2:SetFont(GameFontHighlight:GetFont(), 10) 14 | e.text2:SetText("1.7/2.5") 15 | 16 | e.icon = e.TextFrame:CreateTexture() 17 | e.icon:SetTexture("Interface\\Icons\\Spell_Frost_FrostBolt02") 18 | e.icon:SetTexCoord(0.07,0.93,0.08,0.93) 19 | e.icon:SetPoint("TOPLEFT", e.self,"TOPLEFT",-e.self:GetHeight(),0) 20 | e.icon:SetWidth(e.self:GetHeight()) 21 | e.icon:SetHeight(e.self:GetHeight()) 22 | 23 | e.sparkFrame = CreateFrame("Frame",nil,e.ContentFrame) 24 | e.sparkFrame:SetFrameStrata("DIALOG") 25 | e.spark = e.sparkFrame:CreateTexture(nil,"OVERLAY") 26 | e.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") 27 | e.spark:SetBlendMode("ADD") 28 | e.spark:SetPoint("CENTER",e.selfFill,"RIGHT") 29 | 30 | e.FramingFrame = CreateFrame("Frame",nil,e.ContentFrame) 31 | e.FramingFrame:SetFrameStrata("BACKGROUND") 32 | 33 | e.frameBot = e.FramingFrame:CreateTexture(nil,"BACKGROUND") 34 | e.frameTopBar = e.FramingFrame:CreateTexture(nil,"ARTWORK") 35 | e.frameMidBar = e.FramingFrame:CreateTexture(nil,"BORDER") 36 | e.frameTopIcon = e.FramingFrame:CreateTexture(nil,"ARTWORK") 37 | e.frameMidIcon = e.FramingFrame:CreateTexture(nil,"BORDER") 38 | 39 | e.selfBG:SetAllPoints(e.self) 40 | 41 | e.isBar = true 42 | e.selfFillShown = true 43 | e.isFading = false 44 | end 45 | 46 | function Punsch_Bar_Update(e,db) 47 | e.AlwaysShow = db.AlwaysShow 48 | if e.AlwaysShow then 49 | e.ContentFrame:Show() 50 | else 51 | e.ContentFrame:Hide() 52 | end 53 | 54 | e.decimals = db.Decimals 55 | 56 | e.StretchTexture = db.StretchTexture 57 | if e.StretchTexture then 58 | e.selfFill:SetTexCoord(0,1,0,1) 59 | e.selfBG:SetTexCoord(0,1,0,1) 60 | end 61 | 62 | e.ShowTextureOnFullBar = db.ShowTextureOnFullBar 63 | if e.ShowTextureOnFullBar then 64 | e.selfBG:SetTexture(Punschrulle_GetTexture(db.Texture)) 65 | e.selfBG:SetVertexColor(db.Bg.r,db.Bg.g,db.Bg.b,db.Bg.a) 66 | end 67 | 68 | e.selfBG:SetTexCoord(0,1,0,1) 69 | 70 | e.ShowSpark = db.Spark.Enable 71 | if e.ShowSpark then 72 | e.spark:SetWidth(db.Spark.Width) 73 | e.spark:SetHeight(db.Spark.Height) 74 | e.spark:SetVertexColor(db.Spark.r,db.Spark.g,db.Spark.b,db.Spark.a) 75 | e.spark:Show() 76 | else 77 | e.spark:Hide() 78 | end 79 | 80 | e.ShowIcon = db.ShowIcon 81 | if e.ShowIcon then 82 | e.icon:SetAlpha(1) 83 | e.icon:SetPoint("TOPLEFT", e.self,"TOPLEFT",-e.self:GetHeight() -db.IconPadding,0) 84 | e.icon:SetWidth(e.self:GetHeight()) 85 | e.icon:SetHeight(e.self:GetHeight()) 86 | e.self:SetWidth(db.Width-db.Height) 87 | else 88 | e.icon:SetAlpha(0) 89 | e.self:SetWidth(db.Width) 90 | end 91 | 92 | if db.Border.Show and db.BorderEncompassIcon and e.ShowIcon then 93 | e.BorderFrame:SetPoint("TOPLEFT",e.icon,"TOPLEFT",-db.Border.Padding,db.Border.Padding) 94 | e.BorderFrame:SetPoint("BOTTOMRIGHT",e.ContentFrame,"BOTTOMRIGHT",db.Border.Padding,-db.Border.Padding) 95 | end 96 | 97 | 98 | if db.Frame.Enable then 99 | e.FramingFrame:Show() 100 | e.frameBot:SetTexture(db.Frame.Borderr,db.Frame.Borderg,db.Frame.Borderb,db.Frame.Bordera) 101 | e.frameTopBar:SetTexture(db.Frame.Borderr,db.Frame.Borderg,db.Frame.Borderb,db.Frame.Bordera) 102 | e.frameMidBar:SetTexture(db.Frame.r,db.Frame.g,db.Frame.b,db.Frame.a) 103 | 104 | e.frameTopBar:SetPoint("TOPLEFT", e.self,"TOPLEFT",-db.Frame.InnerBorderSize,db.Frame.InnerBorderSize) 105 | e.frameTopBar:SetPoint("BOTTOMRIGHT", e.self,"BOTTOMRIGHT",db.Frame.InnerBorderSize,-db.Frame.InnerBorderSize) 106 | e.frameMidBar:SetPoint("TOPLEFT", e.frameTopBar,"TOPLEFT",-db.Frame.Thickness,db.Frame.Thickness) 107 | e.frameMidBar:SetPoint("BOTTOMRIGHT", e.frameTopBar,"BOTTOMRIGHT",db.Frame.Thickness,-db.Frame.Thickness) 108 | 109 | if e.ShowIcon then 110 | e.frameTopIcon:SetTexture(db.Frame.Borderr,db.Frame.Borderg,db.Frame.Borderb,db.Frame.Bordera) 111 | e.frameMidIcon:SetTexture(db.Frame.r,db.Frame.g,db.Frame.b,db.Frame.a) 112 | e.frameTopIcon:SetPoint("TOPLEFT", e.icon,"TOPLEFT",-db.Frame.InnerBorderSize,db.Frame.InnerBorderSize) 113 | e.frameTopIcon:SetPoint("BOTTOMRIGHT", e.icon,"BOTTOMRIGHT",db.Frame.InnerBorderSize,-db.Frame.InnerBorderSize) 114 | e.frameMidIcon:SetPoint("TOPLEFT", e.frameTopIcon,"TOPLEFT",-db.Frame.Thickness,db.Frame.Thickness) 115 | e.frameMidIcon:SetPoint("BOTTOMRIGHT", e.frameTopIcon,"BOTTOMRIGHT",db.Frame.Thickness,-db.Frame.Thickness) 116 | e.frameBot:SetPoint("TOPLEFT", e.frameMidIcon,"TOPLEFT",-db.Frame.OuterBorderSize,db.Frame.OuterBorderSize) 117 | e.frameMidIcon:Show() 118 | e.frameTopIcon:Show() 119 | else 120 | e.frameBot:SetPoint("TOPLEFT", e.frameMidBar,"TOPLEFT",-db.Frame.OuterBorderSize,db.Frame.OuterBorderSize) 121 | e.frameMidIcon:Hide() 122 | e.frameTopIcon:Hide() 123 | end 124 | e.frameBot:SetPoint("BOTTOMRIGHT", e.frameMidBar,"BOTTOMRIGHT",db.Frame.OuterBorderSize,-db.Frame.OuterBorderSize) 125 | 126 | 127 | else 128 | e.FramingFrame:Hide() 129 | end 130 | 131 | e.text1:SetFont(Punschrulle_GetFont(db.TextLeft.Font), db.TextLeft.FontSize) 132 | e.text1:SetShadowOffset(db.TextLeft.FontShadowX,db.TextLeft.FontShadowY) 133 | e.text1:ClearAllPoints() 134 | e.text1:SetPoint(db.TextLeft.Point, e.self,db.TextLeft.rPoint,db.TextLeft.X,db.TextLeft.Y) 135 | e.text1:SetTextColor(db.TextLeft.r,db.TextLeft.g,db.TextLeft.b,db.TextLeft.a) 136 | e.text1:SetShadowColor(db.TextLeft.sr,db.TextLeft.sg,db.TextLeft.sb,db.TextLeft.sa) 137 | 138 | --needed for shadowoffset to properly update. 139 | local t = e.text1:GetText() 140 | e.text1:SetText("") 141 | e.text1:SetText(t) 142 | 143 | e.text2:SetFont(Punschrulle_GetFont(db.TextRight.Font), db.TextRight.FontSize) 144 | e.text2:SetShadowOffset(db.TextRight.FontShadowX,db.TextRight.FontShadowY) 145 | e.text2:ClearAllPoints() 146 | e.text2:SetPoint(db.TextRight.Point, e.self,db.TextRight.rPoint,db.TextRight.X,db.TextRight.Y) 147 | e.text2:SetTextColor(db.TextRight.r,db.TextRight.g,db.TextRight.b,db.TextRight.a) 148 | e.text2:SetShadowColor(db.TextRight.sr,db.TextRight.sg,db.TextRight.sb,db.TextRight.sa) 149 | 150 | e.DurationTextSpacing = "" 151 | local i = db.TextRight.Spacing 152 | if i then 153 | while i > 0 do 154 | e.DurationTextSpacing = e.DurationTextSpacing .. " " 155 | i = i - 1 156 | end 157 | end 158 | 159 | --needed for shadowoffset to properly update. 160 | local t = e.text2:GetText() 161 | e.text2:SetText("") 162 | e.text2:SetText(t) 163 | 164 | e.fadeTime = db.Fade.Time 165 | e.fadeEnable = db.Fade.Enable 166 | 167 | Punsch_Bar_SetPercent(e,0,0.7) 168 | end 169 | 170 | function Punsch_Bar_FadeStop(e) 171 | if e.isFading == true then 172 | e.ContentFrame:SetAlpha(1) 173 | e.isFading = false 174 | end 175 | end 176 | 177 | function Punsch_Bar_SetPercent(e,left,right) 178 | if right >= 0.01 then 179 | if right >=1 then right = 1 end 180 | if not e.selfFillShown == true then 181 | e.selfFill:Show() 182 | if e.ShowSpark then e.spark:Show() end 183 | e.selfFillShown = true 184 | end 185 | e.selfFill:SetWidth(e.self:GetWidth()*(right-left)) 186 | 187 | if not e.StretchTexture then 188 | e.selfFill:SetTexCoord(left,right,0,1) 189 | end 190 | else 191 | e.selfFill:Hide() 192 | if e.ShowSpark then e.spark:Hide() end 193 | e.selfFillShown = false 194 | end 195 | end -------------------------------------------------------------------------------- /core/Tables.lua: -------------------------------------------------------------------------------- 1 | Punsch_Tables_KnownChannels = { 2 | --This table is just used to find the spellname from the icon. Should only contain unnamed channeled spells cast by the user 3 | ByIcon = { 4 | MAGE = { 5 | ["Interface\\Icons\\Spell_Frost_IceStorm"] = "Blizzard", 6 | ["Interface\\Icons\\Spell_Nature_Purge"] = "Evocation" , 7 | ["Interface\\Icons\\Spell_Nature_StarFall"] = "Arcane Missiles", 8 | }, 9 | PRIEST = { 10 | ["Interface\\Icons\\Spell_Holy_MindVision"] = "Mind Vision", 11 | ["Interface\\Icons\\Spell_Shadow_SiphonMana"] = "Mind Flay", 12 | }, 13 | WARLOCK = { 14 | ["Interface\\Icons\\Spell_Shadow_RainOfFire"] = "Rain of Fire", 15 | ["Interface\\Icons\\Spell_Shadow_Haunting"] = "Drain Soul", 16 | ["Interface\\Icons\\Spell_Shadow_LifeDrain02"] = "Drain Life", 17 | ["Interface\\Icons\\Spell_Shadow_SiphonMana"] = "Drain Mana", 18 | ["Interface\\Icons\\Spell_Fire_Incinerate"] = "Hellfire", 19 | ["Interface\\Icons\\Spell_Shadow_LifeDrain"] = "Health Funnel" 20 | }, 21 | HUNTER = { 22 | ["Interface\\Icons\\Ability_Hunter_EagleEye"] = "Eagle Eye", 23 | ["Interface\\Icons\\Ability_Hunter_MendPet"] = "Mend Pet", 24 | ["Interface\\Icons\\Ability_Hunter_BeastTaming"] = "Tame Beast", 25 | }, 26 | DRUID = { 27 | ["Interface\\Icons\\Spell_Nature_Cyclone"] = "Hurricane", 28 | ["Interface\\Icons\\Spell_Nature_Tranquility"] = "Tranquility", 29 | }, 30 | SHARED = { 31 | ["Interface\\Icons\\INV_Misc_Bandage_12"] = "Heavy Runecloth Bandage", 32 | ["Interface\\Icons\\INV_Misc_Bandage_11"] = "Runecloth Bandage", 33 | ["Interface\\Icons\\INV_Misc_Bandage_20"] = "Heavy Mageweave Bandage", 34 | ["Interface\\Icons\\INV_Misc_Bandage_19"] = "Mageweave Bandage", 35 | ["Interface\\Icons\\INV_Misc_Bandage_02"] = "Heavy Silk Bandage", 36 | ["Interface\\Icons\\INV_Misc_Bandage_01"] = "Silk Bandage", 37 | ["Interface\\Icons\\INV_Misc_Bandage_17"] = "Heavy Wool Bandage", 38 | ["Interface\\Icons\\INV_Misc_Bandage_14"] = "Wool Bandage", 39 | ["Interface\\Icons\\INV_Misc_Bandage_18"] = "Heavy Linen Bandage", 40 | ["Interface\\Icons\\INV_Misc_Bandage_15"] = "Linen Bandage", 41 | 42 | } 43 | }, 44 | --This table contains all information needed to show ticks on channels properly 45 | ByName = { 46 | ["Blizzard"] = { 47 | Tick = "time", 48 | TickCount = 8 49 | }, 50 | ["Arcane Missiles"] = { 51 | Tick = "time", 52 | TickCount = 5 53 | }, 54 | ["Evocation"] = { 55 | Tick = "mana", 56 | }, 57 | ["Mind Flay"] = { 58 | Tick = "time", 59 | TickCount = 3 60 | }, 61 | ["Rain of Fire"] = { 62 | Tick = "time", 63 | TickCount = 4 64 | }, 65 | ["Drain Soul"] = { 66 | Tick = "time", 67 | TickCount = 5 68 | }, 69 | ["Drain Life"] = { 70 | Tick = "time", 71 | TickCount = 5 72 | }, 73 | ["Drain Mana"] = { 74 | Tick = "time", 75 | TickCount = 5 76 | }, 77 | ["Hellfire"] = { 78 | Tick = "time", 79 | TickCount = 15 80 | }, 81 | ["Health Funnel"] = { 82 | Tick = "time", 83 | TickCount = 10 84 | }, 85 | ["Mend Pet"] = { 86 | Tick = "time", 87 | TickCount = 5 88 | }, 89 | ["Hurricane"] = { 90 | Tick = "time", 91 | TickCount = 10 92 | }, 93 | ["Tranquility"] = { 94 | Tick = "time", 95 | TickCount = 5 96 | }, 97 | 98 | --item based channels 99 | ["Heavy Runecloth Bandage"] = { 100 | Tick = "time", 101 | TickCount = 8 102 | }, 103 | ["Runecloth Bandage"] = { 104 | Tick = "time", 105 | TickCount = 8 106 | }, 107 | ["Heavy Mageweave Bandage"] = { 108 | Tick = "time", 109 | TickCount = 8 110 | }, 111 | ["Mageweave Bandage"] = { 112 | Tick = "time", 113 | TickCount = 8 114 | }, 115 | ["Heavy Silk Bandage"] = { 116 | Tick = "time", 117 | TickCount = 8 118 | }, 119 | ["Silk Bandage"] = { 120 | Tick = "time", 121 | TickCount = 8 122 | }, 123 | ["Heavy Wool Bandage"] = { 124 | Tick = "time", 125 | TickCount = 7 126 | }, 127 | ["Wool Bandage"] = { 128 | Tick = "time", 129 | TickCount = 7 130 | }, 131 | ["Heavy Linen Bandage"] = { 132 | Tick = "time", 133 | TickCount = 6 134 | }, 135 | ["Linen Bandage"] = { 136 | Tick = "time", 137 | TickCount = 6 138 | }, 139 | 140 | --racial channel 141 | ["Cannibalize"] = { 142 | Tick = "time", 143 | TickCount = 5, 144 | Icon = "Interface\\Icons\\Ability_Racial_Cannibalize" 145 | }, 146 | } 147 | } 148 | 149 | --[[Implement these to an exceptiontable for world object interactions. eventually. maybe. someday. 150 | ["First Aid"] = "Interface\\Icons\\Spell_Holy_SealOfSacrifice", 151 | ["Herb Gathering"] = "Interface\\Icons\\INV_Misc_Flower_02", 152 | --]] 153 | --/script message(ActionButton1Icon:GetTexture()) 154 | 155 | Punsch_Tables_ProfilePresets = { 156 | Default = { 157 | Name = "New Profile (Default)", 158 | MuteWelcomeMessage = false, 159 | ["Entities"] = { 160 | ["Castbar"] = { 161 | --Entity 162 | Width = 355, 163 | Height = 30, 164 | Anchor = { 165 | X = -177, 166 | Y = -215.5, 167 | rPoint = "CENTER", 168 | rTo = "", 169 | Point = "TOPLEFT" 170 | }, 171 | Bg = { 172 | r = 0, 173 | g = 0, 174 | b = 0, 175 | a = 1 176 | }, 177 | Fill = { 178 | r = 0.54, 179 | g = 0.54, 180 | b = 0.54, 181 | a = 1 182 | }, 183 | 184 | Texture = "Minimalist", 185 | Border = { 186 | Show = false, 187 | Padding = 4, 188 | Size = 16, 189 | r = 0, 190 | g = 0, 191 | b = 0, 192 | a = 1, 193 | OnTop = true 194 | }, 195 | 196 | --Bar 197 | AlwaysShow = false, 198 | 199 | ShowTextureOnFullBar = true, 200 | StretchTexture = false, 201 | Decimals = 1, 202 | 203 | BorderEncompassIcon = false, 204 | 205 | ShowIcon = true, 206 | IconPadding = 1, 207 | 208 | Spark = { 209 | Enable = true, 210 | Height = 60, 211 | Width = 15, 212 | r = 0.13, 213 | g = 0.23, 214 | b = 0.34, 215 | a = 1, 216 | }, 217 | 218 | TextLeft = { 219 | X = 3, 220 | Y = 0, 221 | rPoint = "LEFT", 222 | Point = "LEFT", 223 | r = 1, 224 | g = 1, 225 | b = 1, 226 | a = 1, 227 | sr = 0, 228 | sg = 0, 229 | sb = 0, 230 | sa = 1, 231 | Font = "Vixar", 232 | FontSize = 14, 233 | FontShadowX = 0.8, 234 | FontShadowY = -0.8, 235 | }, 236 | 237 | TextRight = { 238 | X = -3, 239 | Y = 0, 240 | rPoint = "RIGHT", 241 | Point = "RIGHT", 242 | r = 1, 243 | g = 1, 244 | b = 1, 245 | a = 1, 246 | sr = 0, 247 | sg = 0, 248 | sb = 0, 249 | sa = 1, 250 | Font = "Vixar", 251 | FontSize = 14, 252 | FontShadowX = 0.8, 253 | FontShadowY = -0.8, 254 | Spacing = 1, 255 | }, 256 | 257 | Frame = { 258 | Enable = true, 259 | Thickness = 0.8, 260 | InnerBorderSize = 0, 261 | OuterBorderSize = 0, 262 | Borderr = 1, 263 | Borderg = 1, 264 | Borderb = 1, 265 | Bordera = 0, 266 | r = 0, 267 | g = 0, 268 | b = 0, 269 | a = 1, 270 | }, 271 | 272 | --Castbar 273 | 274 | ShowMultiShot = false, 275 | ShowAimedShot = true, 276 | 277 | ShowRank = false, 278 | RankAsRoman = true, 279 | RankAsShort = true, 280 | UpperCaseSpellName = false, 281 | 282 | CountUpOnCast = true, 283 | CountUpOnChannel = false, 284 | 285 | ShowLag = true, 286 | 287 | 288 | Tick = { 289 | Enable = true, 290 | ShowLag = false, 291 | AsSolidColor = false, 292 | TopAnchor = 0, 293 | BotAnchor = 0.15, 294 | Width = 3.2, 295 | r = 0, 296 | g = 0, 297 | b = 0, 298 | a = 1 299 | }, 300 | 301 | HideBlizzardBar = true, 302 | 303 | FillChannel = { 304 | r = 0.54, 305 | g = 0.54, 306 | b = 0.54, 307 | a = 1 308 | }, 309 | 310 | Lag = { 311 | r = 0.95, 312 | g = 1, 313 | b = 1, 314 | a = 1 315 | }, 316 | 317 | TextDelay = { 318 | X = -3, 319 | Y = 0, 320 | rPoint = "LEFT", 321 | Point = "RIGHT", 322 | r = 0.85, 323 | g = 0, 324 | b = 0, 325 | a = 1, 326 | sr = 0, 327 | sg = 0, 328 | sb = 0, 329 | sa = 0, 330 | Font = "Vixar", 331 | FontSize = 14, 332 | FontShadowX = 0.8, 333 | FontShadowY = -0.8, 334 | AnchorToDuration = true, 335 | }, 336 | 337 | TextLag = { 338 | r = 1, 339 | g = 1, 340 | b = 1, 341 | a = 1, 342 | sr = 0, 343 | sg = 0, 344 | sb = 0, 345 | sa = 1, 346 | Font = "", 347 | FontSize = 9, 348 | FontShadowX = 1, 349 | FontShadowY = -1, 350 | }, 351 | 352 | Fade = { 353 | Enable = true, 354 | OnChannel = false, 355 | Time = 0.9, 356 | PlayerInterruptAsFailure = true, 357 | FailureHoldTime = 0, 358 | SuccessHoldTime = 0, 359 | ShowLagWhileFading = true, 360 | Success = { 361 | r = 0.2, 362 | g = 0.6, 363 | b = 0.2, 364 | a = 1 365 | }, 366 | Failure = { 367 | r = 0.6, 368 | g = 0.2, 369 | b = 0.2, 370 | a = 1 371 | }, 372 | Tolerance = 0.3, 373 | }, 374 | 375 | ChannelDelayToDuration = false 376 | }, 377 | ["Mirror"] = { 378 | --Entity 379 | Width = 170, 380 | Height = 11, 381 | Anchor = { 382 | X = 0, 383 | Y = 1, 384 | rPoint = "TOPRIGHT", 385 | rTo = "Castbar", 386 | Point = "BOTTOMRIGHT" 387 | }, 388 | Bg = { 389 | r = 0, 390 | g = 0, 391 | b = 0, 392 | a = 1 393 | }, 394 | 395 | Texture = "Minimalist", 396 | 397 | Border = { 398 | Show = false, 399 | Padding = 4, 400 | Size = 16, 401 | r = 0, 402 | g = 0, 403 | b = 0, 404 | a = 1, 405 | OnTop = true 406 | }, 407 | 408 | --Bar 409 | AlwaysShow = false, 410 | ShowTextureOnFullBar = false; 411 | StretchTexture = false, 412 | Decimals = 1, 413 | 414 | BorderEncompassIcon = false, 415 | 416 | ShowIcon = true, 417 | IconPadding = 1, 418 | 419 | Spark = { 420 | Enable = true, 421 | Height = 22, 422 | Width = 15, 423 | r = 0.13, 424 | g = 0.23, 425 | b = 0.34, 426 | a = 1, 427 | }, 428 | 429 | TextLeft = { 430 | X = 2, 431 | Y = 0, 432 | rPoint = "LEFT", 433 | Point = "LEFT", 434 | r = 1, 435 | g = 1, 436 | b = 1, 437 | a = 1, 438 | sr = 0, 439 | sg = 0, 440 | sb = 0, 441 | sa = 1, 442 | Font = "Vixar", 443 | FontSize = 10, 444 | FontShadowX = 0.8, 445 | FontShadowY = -0.8, 446 | }, 447 | 448 | TextRight = { 449 | X = -2, 450 | Y = 0, 451 | rPoint = "RIGHT", 452 | Point = "RIGHT", 453 | r = 1, 454 | g = 1, 455 | b = 1, 456 | a = 1, 457 | sr = 0, 458 | sg = 0, 459 | sb = 0, 460 | sa = 1, 461 | Font = "Vixar", 462 | FontSize = 10, 463 | FontShadowX = 0.8, 464 | FontShadowY = -0.8, 465 | }, 466 | 467 | Frame = { 468 | Enable = true, 469 | Thickness = 0.8, 470 | InnerBorderSize = 0, 471 | OuterBorderSize = 0, 472 | Borderr = 1, 473 | Borderg = 1, 474 | Borderb = 1, 475 | Bordera = 0, 476 | r = 0, 477 | g = 0, 478 | b = 0, 479 | a = 1, 480 | }, 481 | 482 | --Mirror 483 | GrowUp = true, 484 | Padding = 1, 485 | HideBlizzardBar = true, 486 | 487 | Fade = { 488 | Enable = true, 489 | Time = 0.9, 490 | HoldTime = 0, 491 | }, 492 | Events = { 493 | BREATH = { 494 | label = "Breath", 495 | enable = true, 496 | r = 0, 497 | g = 0.5, 498 | b = 1, 499 | a = 1, 500 | icon = "Interface\\Icons\\Spell_Shadow_DemonBreath" 501 | }, 502 | EXHAUSTION = { 503 | label = "Exhaustion", 504 | enable = true, 505 | r = 1, 506 | g = 0.9, 507 | b = 0, 508 | a = 1, 509 | icon = "Interface\\Icons\\Ability_Suffocate" 510 | }, 511 | FEIGNDEATH = { 512 | label = "Feign Death", 513 | enable = true, 514 | r = 1, 515 | g = 0.7, 516 | b = 0, 517 | a = 1, 518 | icon = "Interface\\Icons\\Ability_Rogue_FeignDeath" 519 | }, 520 | CAMP = { 521 | label = "Logout", 522 | enable = true, 523 | r = 1, 524 | g = 0.7, 525 | b = 0, 526 | a = 1, 527 | icon = "Interface\\Icons\\Spell_Magic_PolymorphChicken" 528 | }, 529 | QUIT = { 530 | label = "Quit Game", 531 | enable = true, 532 | r = 1, 533 | g = 0.7, 534 | b = 0, 535 | a = 1, 536 | icon = "Interface\\Icons\\Spell_Magic_PolymorphChicken" 537 | }, 538 | BOOT = { 539 | label = "Instance Boot", 540 | enable = true, 541 | r = 1, 542 | g = 0, 543 | b = 0, 544 | a = 1, 545 | icon = "Interface\\Icons\\INV_Misc_Rune_01" 546 | }, 547 | SUMMON = { 548 | label = "Summon", 549 | enable = true, 550 | r = 1, 551 | g = 0.3, 552 | b = 1, 553 | a = 1, 554 | icon = "Interface\\Icons\\Spell_Shadow_Twilight" 555 | }, 556 | GAMESTART = { 557 | label = "Game Start", 558 | enable = true, 559 | r = 0, 560 | g = 1, 561 | b = 0, 562 | a = 1, 563 | icon = "Interface\\Icons\\Ability_DualWield" 564 | }, 565 | WSG_FLAGRESPAWN = { 566 | label = "Flag respawn", 567 | enable = true, 568 | r = 0, 569 | g = 1, 570 | b = 0, 571 | a = 1, 572 | icon = "Interface\\Icons\\Ability_DualWield" 573 | }, 574 | } 575 | }, 576 | } 577 | }, 578 | } 579 | -------------------------------------------------------------------------------- /core/Mirror.lua: -------------------------------------------------------------------------------- 1 | PunschMirrors = {} 2 | PunschMirrorCount = 3 3 | PunschMirrorEvents = {} 4 | function Punsch_Mirror_Create() 5 | local db = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"] 6 | PunschEntities["Mirror"] = {} 7 | local e = PunschEntities["Mirror"] 8 | PunschMirrors[0] = e 9 | e.Type = "Mirror" 10 | Punsch_Bar_Create(e,db) 11 | 12 | for i=1,PunschMirrorCount do 13 | PunschMirrors[i] = {} 14 | PunschMirrors[i].Type = "Mirror" .. i 15 | Punsch_Bar_Create(PunschMirrors[i],db) 16 | end 17 | 18 | e.self:SetScript("OnEvent",Punsch_Mirror_OnEvent) 19 | e.self:SetScript("OnUpdate",Punsch_Mirror_OnUpdate) 20 | 21 | e.self:RegisterEvent("MIRROR_TIMER_START") 22 | e.self:RegisterEvent("MIRROR_TIMER_PAUSE") 23 | e.self:RegisterEvent("MIRROR_TIMER_STOP") 24 | 25 | e.self:RegisterEvent("PLAYER_CAMPING") 26 | e.self:RegisterEvent("PLAYER_QUITING") 27 | 28 | --e.self:RegisterEvent("LOGOUT_CANCEL") 29 | --doesnt seem to fire, workaround below 30 | local oldOnHide = StaticPopupDialogs["CAMP"].OnHide 31 | StaticPopupDialogs["CAMP"].OnHide = function () 32 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["CAMP"]) 33 | oldOnHide() 34 | end 35 | local oldOnHide = StaticPopupDialogs["QUIT"].OnHide 36 | StaticPopupDialogs["QUIT"].OnHide = function () 37 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["QUIT"]) 38 | oldOnHide() 39 | end 40 | 41 | e.self:RegisterEvent("INSTANCE_BOOT_START") 42 | e.self:RegisterEvent("INSTANCE_BOOT_STOP") 43 | 44 | e.self:RegisterEvent("CONFIRM_SUMMON") 45 | --e.self:RegisterEvent("CANCEL_SUMMON") 46 | 47 | --hooks confirming summons 48 | local oldOnAccept = StaticPopupDialogs["CONFIRM_SUMMON"].OnAccept 49 | StaticPopupDialogs["CONFIRM_SUMMON"].OnAccept = function () 50 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["SUMMON"]) 51 | oldOnAccept() 52 | end 53 | StaticPopupDialogs["CONFIRM_SUMMON"].OnHide = function () 54 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["SUMMON"]) 55 | end 56 | 57 | --bg timers 58 | e.self:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL") 59 | e.self:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE") 60 | e.self:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE") 61 | e.self:RegisterEvent("PLAYER_ENTERING_WORLD") 62 | end 63 | 64 | --updates the bars to the current state of the db 65 | function Punsch_Mirror_UpdateMirrors(e) 66 | local db = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"] 67 | Punsch_Bar_Update(e,db) 68 | 69 | if db.HideBlizzardBar then 70 | UIParent:UnregisterEvent("MIRROR_TIMER_START") 71 | else 72 | UIParent:RegisterEvent("MIRROR_TIMER_START") 73 | end 74 | 75 | if db.Anchor.rTo == "Castbar" then 76 | e.self:SetPoint(db.Anchor.Point, 77 | PunschEntities["Castbar"].self, 78 | db.Anchor.rPoint, 79 | db.Anchor.X, 80 | db.Anchor.Y) 81 | elseif e.ShowIcon then 82 | e.self:SetPoint(db.Anchor.Point, 83 | UIParent, 84 | db.Anchor.rPoint, 85 | db.Anchor.X+db.Height, 86 | db.Anchor.Y) 87 | else 88 | e.self:SetPoint(db.Anchor.Point, 89 | UIParent, 90 | db.Anchor.rPoint, 91 | db.Anchor.X, 92 | db.Anchor.Y) 93 | end 94 | 95 | e.fadeHoldTime = db.Fade.HoldTime 96 | 97 | e.GrowUp = db.GrowUp 98 | 99 | for i=1,PunschMirrorCount do 100 | Punsch_Entity_Update(PunschMirrors[i],db) 101 | Punsch_Bar_Update(PunschMirrors[i],db) 102 | 103 | if e.GrowUp then 104 | PunschMirrors[i].self:SetPoint("TOPLEFT", 105 | e.self, 106 | "TOPLEFT", 107 | 0, 108 | (i)*(db.Height+db.Padding)) 109 | else 110 | PunschMirrors[i].self:SetPoint("TOPLEFT", 111 | e.self, 112 | "TOPLEFT", 113 | 0, 114 | -((i)*(db.Height+db.Padding))) 115 | end 116 | end 117 | end 118 | 119 | local debugMirror = nil 120 | function Punsch_Mirror_OnEvent() 121 | if (event == "MIRROR_TIMER_START") then 122 | --arg1 name, "BREATH", "EXHAUSTION" or "FEIGNDEATH" 123 | --arg2 Current value of timer 124 | --arg3 Maximum value of timer 125 | --arg4 step. (how much it moves per second) 126 | --arg5 pause 1/0 127 | --arg6 label 128 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage("MIRROR_TIMER_START " .. arg1 .. "," .. arg2 .. "," .. arg3 .. "," .. arg4 .. "," .. arg5 .. "," .. arg6) end 129 | if not PunschMirrorEvents[arg1] then 130 | PunschMirrorEvents[arg1] = {} 131 | PunschMirrorEvents[arg1].name = arg1 132 | end 133 | PunschMirrorEvents[arg1].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"][arg1].label 134 | PunschMirrorEvents[arg1].value = arg2 135 | PunschMirrorEvents[arg1].max = arg3 136 | PunschMirrorEvents[arg1].step = arg4 137 | PunschMirrorEvents[arg1].pause = arg5 138 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents[arg1]) 139 | elseif (event == "MIRROR_TIMER_PAUSE") then 140 | --arg1 duration to pause for 141 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage("MIRROR_TIMER_PAUSE " .. arg1) end 142 | DEFAULT_CHAT_FRAME:AddMessage(" MIRROR_TIMER_PAUSE fired, arg1: " .. arg1) 143 | elseif (event == "MIRROR_TIMER_STOP") then 144 | --arg1 name of mirror to stop 145 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage("MIRROR_TIMER_STOP " .. arg1) end 146 | Punsch_Mirror_OnEventStop(PunschMirrorEvents[arg1]) 147 | elseif (event == "PLAYER_CAMPING") then 148 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage(event) end 149 | if not PunschMirrorEvents["CAMP"] then 150 | PunschMirrorEvents["CAMP"] = {} 151 | PunschMirrorEvents["CAMP"].name = "CAMP" 152 | end 153 | PunschMirrorEvents["CAMP"].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"]["CAMP"].label 154 | PunschMirrorEvents["CAMP"].value = 20 * 1000 155 | PunschMirrorEvents["CAMP"].max = 20 * 1000 156 | PunschMirrorEvents["CAMP"].step = -1 157 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents["CAMP"]) 158 | elseif (event == "PLAYER_QUITING") then 159 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage(event) end 160 | if not PunschMirrorEvents["QUIT"] then 161 | PunschMirrorEvents["QUIT"] = {} 162 | PunschMirrorEvents["QUIT"].name = "QUIT" 163 | end 164 | PunschMirrorEvents["QUIT"].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"]["QUIT"].label 165 | PunschMirrorEvents["QUIT"].value = 20 * 1000 166 | PunschMirrorEvents["QUIT"].max = 20 * 1000 167 | PunschMirrorEvents["QUIT"].step = -1 168 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents["QUIT"]) 169 | elseif (event == "INSTANCE_BOOT_START") then 170 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage(event) end 171 | if not PunschMirrorEvents["BOOT"] then 172 | PunschMirrorEvents["BOOT"] = {} 173 | PunschMirrorEvents["BOOT"].name = "BOOT" 174 | end 175 | PunschMirrorEvents["BOOT"].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"]["BOOT"].label 176 | PunschMirrorEvents["BOOT"].value = GetInstanceBootTimeRemaining() * 1000 177 | PunschMirrorEvents["BOOT"].max = GetInstanceBootTimeRemaining() * 1000 178 | PunschMirrorEvents["BOOT"].step = -1 179 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents["BOOT"]) 180 | elseif (event == "INSTANCE_BOOT_STOP") then 181 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage(event) end 182 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["BOOT"]) 183 | elseif (event == "CONFIRM_SUMMON") then 184 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage(event) end 185 | if not PunschMirrorEvents["SUMMON"] then 186 | PunschMirrorEvents["SUMMON"] = {} 187 | PunschMirrorEvents["SUMMON"].name = "SUMMON" 188 | end 189 | PunschMirrorEvents["SUMMON"].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"]["SUMMON"].label 190 | PunschMirrorEvents["SUMMON"].value = GetSummonConfirmTimeLeft() * 1000 191 | PunschMirrorEvents["SUMMON"].max = GetSummonConfirmTimeLeft() * 1000 192 | PunschMirrorEvents["SUMMON"].step = -1 193 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents["SUMMON"]) 194 | --elseif (event == "CANCEL_SUMMON") then 195 | -- DEFAULT_CHAT_FRAME:AddMessage(event) 196 | -- if debugMirror then DEFAULT_CHAT_FRAME:AddMessage(event) end 197 | -- Punsch_Mirror_OnEventStop(PunschMirrorEvents["SUMMON"]) 198 | elseif (event == "CHAT_MSG_BG_SYSTEM_NEUTRAL") then 199 | if debugMirror then DEFAULT_CHAT_FRAME:AddMessage(event .. " '" .. arg1 .. "'") end 200 | if not PunschMirrorEvents["GAMESTART"] then 201 | PunschMirrorEvents["GAMESTART"] = {} 202 | PunschMirrorEvents["GAMESTART"].name = "GAMESTART" 203 | PunschMirrorEvents["GAMESTART"].max = 60000 204 | PunschMirrorEvents["GAMESTART"].step = -1 205 | end 206 | if strfind(arg1,"1 minute") then 207 | PunschMirrorEvents["GAMESTART"].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"]["GAMESTART"].label 208 | PunschMirrorEvents["GAMESTART"].value = 60000 209 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents["GAMESTART"]) 210 | elseif strfind(arg1,"30 seconds") then 211 | PunschMirrorEvents["GAMESTART"].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"]["GAMESTART"].label 212 | PunschMirrorEvents["GAMESTART"].value = 30000 213 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents["GAMESTART"]) 214 | elseif strfind(arg1,"Let the battle for") or strfind(arg1,"The Battle for Arathi Basin has begun!") then --well memed nost 215 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["GAMESTART"]) 216 | elseif strfind(arg1,"The flags are now placed at their bases.") then 217 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["WSG_FLAGRESPAWN"]) 218 | else 219 | --DEFAULT_CHAT_FRAME:AddMessage("unhandled " .. event .. " '" .. arg1 .. "'") 220 | end 221 | elseif (event == "CHAT_MSG_BG_SYSTEM_ALLIANCE") or (event == "CHAT_MSG_BG_SYSTEM_HORDE") then 222 | if strfind(arg1,"(%S+) captured the (%S+) flag!") then 223 | if not PunschMirrorEvents["WSG_FLAGRESPAWN"] then 224 | PunschMirrorEvents["WSG_FLAGRESPAWN"] = {} 225 | PunschMirrorEvents["WSG_FLAGRESPAWN"].name = "WSG_FLAGRESPAWN" 226 | PunschMirrorEvents["WSG_FLAGRESPAWN"].max = 23000 227 | PunschMirrorEvents["WSG_FLAGRESPAWN"].step = -1 228 | end 229 | PunschMirrorEvents["WSG_FLAGRESPAWN"].label = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"]["WSG_FLAGRESPAWN"].label 230 | PunschMirrorEvents["WSG_FLAGRESPAWN"].value = PunschMirrorEvents["WSG_FLAGRESPAWN"].max 231 | Punsch_Mirror_AssignFirstUnassignedEvent(PunschMirrorEvents["WSG_FLAGRESPAWN"]) 232 | end 233 | elseif (event == "PLAYER_ENTERING_WORLD") then 234 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["GAMESTART"]) 235 | Punsch_Mirror_OnEventStop(PunschMirrorEvents["WSG_FLAGRESPAWN"]) 236 | end 237 | end 238 | 239 | function Punsch_Mirror_AssignFirstUnassignedEvent(event) 240 | for i=0,PunschMirrorCount do 241 | if not PunschMirrors[i].event or PunschMirrors[i].event == event then 242 | Punsch_Mirror_AssignEvent(PunschMirrors[i], event) 243 | break 244 | end 245 | end 246 | end 247 | 248 | function Punsch_Mirror_AssignEvent(e,event) 249 | e.event = event 250 | if event then 251 | if not PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"][event.name].enable then return end 252 | Punsch_Bar_FadeStop(e) 253 | e.selfFill:SetVertexColor(PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"][event.name].r, 254 | PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"][event.name].g, 255 | PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"][event.name].b, 256 | PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"][event.name].a) 257 | if not e.icon:SetTexture(PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Mirror"]["Events"][event.name].icon) then 258 | e.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark") 259 | end 260 | e.text1:SetText(event.label) 261 | if PunschEntities["Mirror"].ShowSpark then e.spark:Show() end 262 | e.ContentFrame:Show() 263 | else 264 | if not PunschEntities["Mirror"].AlwaysShow then e.ContentFrame:Hide() end 265 | end 266 | end 267 | 268 | function Punsch_Mirror_UnAssignEvent(event) 269 | if not event then return end 270 | local eventFound = false 271 | for i=0,PunschMirrorCount do 272 | if PunschMirrors[i].event == event and not eventFound then 273 | eventFound = true 274 | end 275 | if eventFound then 276 | if i 0 then 322 | e.holdTime = e.holdTime-elapsed 323 | if e.holdTime < 0 then 324 | e.fadeTimeleft = e.fadeTimeleft + e.holdTime 325 | end 326 | else 327 | e.fadeTimeleft = e.fadeTimeleft-elapsed 328 | end 329 | if e.fadeTimeleft <=0 then 330 | Punsch_Bar_FadeStop(e) 331 | if not e.AlwaysShow then e.ContentFrame:Hide() end 332 | Punsch_Mirror_UnAssignEvent(e.event) 333 | else 334 | e.ContentFrame:SetAlpha(1- (e.fadeTime - e.fadeTimeleft) / e.fadeTime) 335 | end 336 | else 337 | e.event.value = e.event.value + elapsed*1000*e.event.step 338 | if e.event.value > e.event.max then e.event.value = e.event.max end 339 | if e.event.value < 0 then e.event.value = 0 end 340 | e.text2:SetText(string.format("%." .. e.decimals .. "f",e.event.value/1000)) 341 | Punsch_Bar_SetPercent(e,0,e.event.value/e.event.max) 342 | end 343 | end 344 | -------------------------------------------------------------------------------- /media/textures/Ruben.tga: -------------------------------------------------------------------------------- 1 |  )*(220886896>?<==;AB?BCABB@>?===:<=:>?<<=:<=:<<:>?<>?<<=:@A>>?=9:8996;<9?@=>><<<9;<9>>;>>;>>;;<9<=:;<:997;;9=>;=>;=>;:<:>@=>>;<=:<=:;;9<=:>?<>?<<=:;<9=>;=>;=>;;<9;;9;<9>?<<=::;9:;9:;9675:;9>><>><>?==>;<=;=>;<=:;<9;<:;<:;<99:69:8;<9;;9=>;>?<<=:;<9?@>AB?=>;::8;;9>>;::8:;8==;==:=>;>>;=>;==;@@>>?<>>;=>;==:>?<<=:9:6;<9>>;;<9==:;<9:;8;;9;;9::8;;9<=:9:8=>;<=:<=:<<:??=>?;>>;;;9;;9;<9==:>><>?==>;?@>==:@@>=>;AB?BCABB@>?===:<=:>?<<=:<=:<<:>?<>?<<=:@A>>?=9:8996;<9?@=>><<<9;<9>>;>>;>>;;<9<=:;<:997;;9=>;=>;=>;:<:>@=>>;<=:<=:;;9<=:>?<>?<<=:;<9=>;=>;=>;;<9;;9;<9>?<<=::;9:;9:;9675:;9>><>><>?==>;<=;=>;<=:;<9;<:;<:;<99:69:8;<9;;9=>;>?<<=:;<9?@>AB?=>;::8;;9>>;::8:;8==;==:=>;>>;=>;==;@@>>?<>>;=>;==:>?<<=:9:6;<9>>;;<9==:;<9:;8;;9;;9::8;;9<=:9:8=>;<=:<=:<<9==;9:767400.''%..,553<<:AA>CDAFGDIKGIJFHIFGHEHIEFGDHHEJJGHIEFHDJKHJKHLMJJLHHIFHIFJLIFGDFFBIIFHHEDDABD@HHEHIFHIEHHEFFCDFBDEBDEBEFDEFBEGDKOLKNJFGDFGDFGDHIEKKHJKHHIFHIEJJHGHDHHEHHEHHEJKHJJHJKHIJGGHDFHDFFDHIFGIFFGDHHEFGDHIFFHDHIFHIFFFDHHEKLJKLIJJHGHEEFBEFCEFBGHEHIEJJGJKHIIFIIFJKHHHEGHDJJHJJGHIFHIEIJGJKHGHDHIFJKIIIFIJFGHDFGDFFDJKIJJHIJFHIEHHEIJFHIEIJFIJFIJFIIFGHEEECIJGJKHJJGIJFKLHKLHJKHJJGLLIHIFFGDGHDHIFHIFIJGIJFHIEHIFJKHIJFHIFGHEHIEFGDHHEJJGHIEFHDJKHJKHLMJJLHHIFHIFJLIFGDFFBIIFHHEDDABD@HHEHIFHIEHHEFFCDFBDEBDEBEFDEFBEGDKOLKNJFGDFGDFGDHIEKKHJKHHIFHIEJJHGHDHHEHHEHHEJKHJJHJKHIJGGHDFHDFFDHIFGIFFGDHHEFGDHIFFHDHIFHIFFFDHHEKLJKLIJJHGHEEFBEFCEFBGHEHIEJJGJKHIIFIIFJKHHHEGHDJJHJJGHIFHIEIJGJKHGHDHIFJKIIIFIJFGHDFGDFFDJKIJJHIJFHIEHHEIJFHIEIJFIJFIJFIIFGHEEECIJGJKHJJGIJFKKHIJGFFCAA?>?<553,-+342>>;DECGIELMIKMINPKOPLRROSTPSSPQRNTVRUVSQSORSOVYUUVSSTPTUQUVRTTPUVRSSPRSPMNJMOKPPMMOKRRNSTPSTPSSPPQMPRNSTPOPLLLIMNKPQMVYUTWSSTPSTPSTQVWSWXTVVRSTPSTPSUQRSOPQMPQMPPMRSOSTPTVRSTPRSPPQMRSPSVSSURTVSRSPSSPRSOPPMPPMPQMRROSSPRSPSURVWTTVRUVSSTQPRMOPLMNJMMJNOKOOLPPMRRORSORSPVVSVWSVWSVWSRSOPRMSSPSSPTURTTQTVRQRNPQMSSPPQMUVSPPLNOLRSPQRNQRNSTPSTPTUQPPMMMKTVRUVRTUQVVSSTQSTPQROSSPTVRTVRTTRTURWXUPQMSSPSTQPRNQRNMOKOPLOPLRROSTPSSPQRNTVRUVSQSORSOVYUUVSSTPTUQUVRTTPUVRSSPRSPMNJMOKPPMMOKRRNSTPSTPSSPPQMPRNSTPOPLLLIMNKPQMVYUTWSSTPSTPSTQVWSWXTVVRSTPSTPSUQRSOPQMPQMPPMRSOSTPTVRSTPRSPPQMRSPSVSSURTVSRSPSSPRSOPPMPPMPQMRROSSPRSPSURVWTTVRUVSSTQPRMOPLMNJMMJNOKOOLPPMRRORSORSPVVSVWSVWSVWSRSOPRMSSPSSPTURTTQTVRQRNPQMSSPPQMUVSPPLNOLRSPQRNQRNSTPSTPTUQPPMMMKTVRUVRTUQVVSSTQSTPOPMNNKKLIEFC>><664*+);;9EECMNKSTPUVRVWSVXSZ\X^^Z[\XZ[W\]Y]^Y]^ZZ\X^^[]^Y\]Y\]X^^Z^_[^^Z]^Y^^ZZ\WZ[W\\Y^^\\]Y\]Y[\X\]Y]^ZZ\XYZWYZV[\X[\XWYTY[WY[WW[WYZV]^Z]^Z_`\]]Y\]Y\]Y[\XZ[W[\XUWRYZVac^dgc_a]YZU[\X^^Z_a]^a^]^Y^^\\]Y\]Y\]Y\]YWYUVWSUVSWYSXYUXZW\^[Y\XWYUZ[W\^YYZWZ[W[\YYYUSSQVWSYYVYYUYYU^`\`a]^^Z]^Z]^Y\]YYYUXYT`a^^^ZYYUYYUYZVZ[W^^Z^^Z\\YWWSUWRWXS\]Y^^Z_`\^`\^^ZWWSZ[W^_Z]]Y\\XZ[WZ[WZ\W]]Y\\Y]^Z]^Z\]Y]^Z`a]ZZW]]Y^^[]^YZ[WYYUWYSZ\X^^Z[\XZ[W\]Y]^Y]^ZZ\X^^[]^Y\]Y\]X^^Z^_[^^Z]^Y^^ZZ\WZ[W\\Y^^\\]Y\]Y[\X\]Y]^ZZ\XYZWYZV[\X[\XWYTY[WY[WW[WYZV]^Z]^Z_`\]]Y\]Y\]Y[\XZ[W[\XUWRYZVac^dgc_a]YZU[\X^^Z_a]^a^]^Y^^\\]Y\]Y\]Y\]YWYUVWSUVSWYSXYUXZW\^[Y\XWYUZ[W\^YYZWZ[W[\YYYUSSQVWSYYVYYUYYU^`\`a]^^Z]^Z]^Y\]YYYUXYT`a^^^ZYYUYYUYZVZ[W^^Z^^Z\\YWWSUWRWXS\]Y^^Z_`\^`\^^ZWWSZ[W^_Z]]Y\\XZ[WZ[WZ[V[[WWWTSTQMMKDEC<=;442AB?GIFQQNYZW\^Zaa]bc_ac^bd_ac^ac]`a]`a\ab]ac]deade`cd^cd_ce_gieefccd__a[_`[_`[ac]efccc^ac^_a\_a\ab]de`aa]bc^cd_gidfgccd_ce`injcd`cd_cc_deagieefbde`cd__`[bc]efcmokgheeec__[cc_efcbc_efcegdac]`a\ac^egceea_a\ab]ac_`a]_`\`c_ceacd_`a]ce`ac]ab]_a\ab]`a\cd_cd_\]Z\]Z_`[_`\]]ZZ[W[[Xac^cd__`[\]Y]_[`a\_`[]^[_`[_a[_`[cd_cc^eeacd_bc]]_Z`a\ghddd_aa]ab][[X[\Yab\aa\`a\cd_bc_ac]ac]`a\`a]bc___[aa]de`dea_a]ab]deabd_cd_cd_ac^bd_ac^ac]`a]`a\ab]ac]deade`cd^cd_ce_gieefccd__a[_`[_`[ac]efccc^ac^_a\_a\ab]de`aa]bc^cd_gidfgccd_ce`injcd`cd_cc_deagieefbde`cd__`[bc]efcmokgheeec__[cc_efcbc_efcegdac]`a\ac^egceea_a\ab]ac_`a]_`\`c_ceacd_`a]ce`ac]ab]_a\ab]`a\cd_cd_\]Z\]Z_`[_`\]]ZZ[W[[Xac^cd__`[\]Y]_[`a\_`[]^[_`[_a[_`[cd_cc^eeacd_bc]]_Z`a\ghddd_aa]ab][[X[\Yab\aa\`a\cd_bc_ab]_a[[[WVWTQROGGE??=674BC@JJHMMKUURbb_dfaefbijehidghciieghccd`bc^fgbhidefbijeijedf`df`ffafhbghdikfegcffbijehidhidkmhklhghdjkgikfghcijdmnijkfikfkmhrvrilhhidookqsoopmlmijkfhidijeijfqtomnieeabc^hiehiefhcfhcklhijfhidcd_bc^hidkkfbc^efahiehieikgikgjkfikfjkglnjmokdfadfadfafgcefaefade`bd_bc^dfahhdde`ghcfgbefbfhdefbmniijfffaijeijfefadf`ijehhclmhijejkelmhjkfhhchhcghbfhbfgbab]fgbjkfghbghcfgbhhdbd^hjfkmhcd`efbhhdffbdeabb_\\Z^^[hhdfhcefbijehidghciieghccd`bc^fgbhidefbijeijedf`df`ffafhbghdikfegcffbijehidhidkmhklhghdjkgikfghcijdmnijkfikfkmhrvrilhhidookqsoopmlmijkfhidijeijfqtomnieeabc^hiehiefhcfhcklhijfhidcd_bc^hidkkfbc^efahiehieikgikgjkfikfjkglnjmokdfadfadfafgcefaefade`bd_bc^dfahhdde`ghcfgbefbfhdefbmniijfffaijeijfefadf`ijehhclmhijejkelmhjkfhhchhcghbfhbfgbab]fgbjkfghbghcfgbhhd`b\bda`a]STPLMJDDB886EFCNOKUVR`a]hiejkgklgjkeijejkfnpkjkgdeaggcklhhiegidjkfikejkfde`ggbjkglniikgmnjnpllmhnpklmhklglmiklgikeghcghclmhoqlopkprlprnlnkikflojqtnklgjkelnilmglmhlmhrtotvqiieiieggcikeghcfgcegaghcikeklhlmhjkfikennjllgklglniikgikgikfjkgmnillhklgrvrtwsikfhieklhjkgklgmnikkghidhidlmilnilniklgjkfghdklhmokklglnimniijeijejkeklglminpklmiklgopkkkfklgllgkmiikfmniklgijeikeghcllglmijkfmnjlniikfhidggcfgcjkggidghcegbjkgmnjlmiklgjkeijejkfnpkjkgdeaggcklhhiegidjkfikejkfde`ggbjkglniikgmnjnpllmhnpklmhklglmiklgikeghcghclmhoqlopkprlprnlnkikflojqtnklgjkelnilmglmhlmhrtotvqiieiieggcikeghcfgcegaghcikeklhlmhjkfikennjllgklglniikgikgikfjkgmnillhklgrvrtwsikfhieklhjkgklgmnikkghidhidlmilnilniklgjkfghdklhmokklglnimniijeijejkeklglminpklmiklgopkkkfklgllgkmiikfmniklgijeikeghcllglmijkfklhgid_a\WXTNNKDEB;;9FGDNOKZ[Vce`ijflmhnojrsnmninpkmniiiehienojmnilmhnojnpknokjkgmnimojklgmniprmprmnokprmnojkmglmhnnjmnjjkeiieijeijeikfmniqsmpsnnqmjkgkmijkgijejkflmgprmpqlmniprmmnjkmhnojpplkmgklgikeikfjkfjkgkmgkmhnpkmnimnistonniijeijfjlgnojopllniijejlgkkgrvrtxtkkgnokoqmqrnqrmppkmnikmhghcjkfmnipqmmniklgopkmnjopklmhklgghchidopkkmgjkfmninpkoplnokmmhmnhnnijmijmiijfkkgikfjkfklgnojmnikmhoqmlmiklgmniklgfgbklgijfghckmgnpjopknojnojrsnmninpkmniiiehienojmnilmhnojnpknokjkgmnimojklgmniprmprmnokprmnojkmglmhnnjmnjjkeiieijeijeikfmniqsmpsnnqmjkgkmijkgijejkflmgprmpqlmniprmmnjkmhnojpplkmgklgikeikfjkfjkgkmgkmhnpkmnimnistonniijeijfjlgnojopllniijejlgkkgrvrtxtkkgnokoqmqrnqrmppkmnikmhghcjkfmnipqmmniklgopkmnjopklmhklgghchidopkkmgjkfmninpkoplnokmmhmnhnnijmijmiijfkkgikfjkfklgnojmnikmhmokghdaa][\XQRNDEA<<9FGERRO]^Zdd_ijdklfnojrrmvvrrrnijeee`pqlrrnmojkmhjkfklgmnjjkfmnikmglmijkenoimojkmgkkfnojnoinnimninokopkmniprmtwroqmmoimninrmormqsokmhjlgjkfknhjlgnojnoktvpstnlmiijemninolkmhlmhikfikfghcefakmhopkmnikmhkkghiejkfkmgfgcefajkfklgklgijekmgmmhfgctyvqsokkgkmgnokopkpqmpqlmnjnnjmnimnjkmglmiijehidkkgmojjkejkenojmninojklghidhicjkfmninpjkkfkmgrsnmojjmiegefgcghcjkfkkgmmhklgijejkfnojkkgmnimnimnikkghjgkkgnpknninoimnhnojrrmvvrrrnijeee`pqlrrnmojkmhjkfklgmnjjkfmnikmglmijkenoimojkmgkkfnojnoinnimninokopkmniprmtwroqmmoimninrmormqsokmhjlgjkfknhjlgnojnoktvpstnlmiijemninolkmhlmhikfikfghcefakmhopkmnikmhkkghiejkfkmgfgcefajkfklgklgijekmgmmhfgctyvqsokkgkmgnokopkpqmpqlmnjnnjmnimnjkmglmiijehidkkgmojjkejkenojmninojklghidhicjkfmninpjkkfkmgrsnmojjmiegefgcghcjkfkkgmmhklgijehidijeaa]\]YSTPIJF<<:IIFTUQ\]Ycd_hicmnirtnrtoqrmmmiijenojrsnnojjkflmimniikeijenpknojjkgnoknpkopkoplklfgickmhnoiopknnjmnijkfkmgpsnoplnojlmgjkflojnqmoqmnpknpkmnjkmgkmglnifgboqkopknpknnjijekmiklgklgnoknoklmikmgikekmglmhjkgjkfhicffbggchiejkgijeikfmninpknnkijeiieknkmrniieikeklgjkfmninpklmimnjnojmnjlmhjkfkmhkmgjkfikerspturnnjklgklgkkgijehiekkgstpstoopkstoopknojkmgijelmirsomnjmnjlmgkmhkmgmnjmniklgmnilmilmhiiemminojmnimnimnhopkrtnrtoqrmmmiijenojrsnnojjkflmimniikeijenpknojjkgnoknpkopkoplklfgickmhnoiopknnjmnijkfkmgpsnoplnojlmgjkflojnqmoqmnpknpkmnjkmgkmglnifgboqkopknpknnjijekmiklgklgnoknoklmikmgikekmglmhjkgjkfhicffbggchiejkgijeikfmninpknnkijeiieknkmrniieikeklgjkfmninpklmimnjnojmnjlmhjkfkmhkmgjkfikerspturnnjklgklgkkgijehiekkgstpstoopkstoopknojkmgijelmirsomnjmnjlmgkmhkmgklhhidab]\]YSSPHIF;;9JJGVVS]]Y`a\fhbppkstoknikkgnokpqllniopkmnilmihielmhlnikmgmnimnijkggidgiemninpknpjkmgikeikfpqmprmlmhjkfsvpnpklmhmniikfkmgx{wsupkmgmojprnrrnmnjmniklgjkggidijeklgikfijejkglninokmninoknojqrnprlmnimnjjkgmnjprmppmlmijlgkmhmnjprmnpkkmgklghiemmihieinjprommiiiegidjkgnokoplpqmnokjkfklgikgefagickmhjkfturrspnpkkmglmglmgmmhkkgkmhrtortoiidmmgnnimnikmhmninoknokmnikmglmhprmsvpmmhkmgmmiklgijejkfijfnojppmnnijkfkmgrrmstoknikkgnokpqllniopkmnilmihielmhlnikmgmnimnijkggidgiemninpknpjkmgikeikfpqmprmlmhjkfsvpnpklmhmniikfkmgx{wsupkmgmojprnrrnmnjmniklgjkggidijeklgikfijejkglninokmninoknojqrnprlmnimnjjkgmnjprmppmlmijlgkmhmnjprmnpkkmgklghiemmihieinjprommiiiegidjkgnokoplpqmnokjkfklgikgefagickmhjkfturrspnpkkmglmglmgmmhkkgkmhrtortoiidmmgnnimnikmhmninoknokmnikmglmhprmsvpkkffhbcc_Z[WPQMGHD;;9KLISTP]^Yeeajkfqrmmniikfnpkprmprmmnilnhpqknpkklgjkfnpknpkijenokkmhikekmgjkfmnjnojnpkjlgmoinpkopkorltwrtvqprmqsnopkmnisvqx|xmnidealmgnpkmnimnimmhklgmnjmnjghcfgbegagieijemninokmnjmojmnimnkmnjjkfmnijlgijelmhpqlopkjkglminojkmhklgmninpkkmhhiehiekojmnkkmifgbiiekmhmnjmojmninokmnjjkfijfgiekmiklgrtptvrhiekmimnimninpkppmpqmkminojnpknoiijeijfkkgmninplsupnpjmnjklglmhqsnprmklgjkgmnimnifgblminojprmmninojopkopkstomniikfnpkprmprmmnilnhpqknpkklgjkfnpknpkijenokkmhikekmgjkfmnjnojnpkjlgmoinpkopkorltwrtvqprmqsnopkmnisvqx|xmnidealmgnpkmnimnimmhklgmnjmnjghcfgbegagieijemninokmnjmojmnimnkmnjjkfmnijlgijelmhpqlopkjkglminojkmhklgmninpkkmhhiehiekojmnkkmifgbiiekmhmnjmojmninokmnjjkfijfgiekmiklgrtptvrhiekmimnimninpkppmpqmkminojnpknoiijeijfkkgmninplsupnpjmnjklglmhqsnprmijeefbcd_\]YNOKHIF>>;FGDPQM[\Xbd_hidlmhgidlojnpklnilninpkijfijejkfnpklniklgijejlgklgkmhlnjklghicjjflnilniijejkfgicgicklgklgklgklhnokmnjjjetwsptojkfjkflnhlninojjlgiieopkprllnjjkfijeiieklhijehiejkfijehieijeijflnjklikliklgijelnimniklgfgbjkgklhijehidijelnjlmjijfggcfjeghcgiejkgllimnjlnijlghieijffgcgidijfghdlmhjkgwywpqlijeijfjlgjlgjkgklhnojprmpqlijehieijeijeklgjkfkmimnimniopklmiklglmiklhjjfjjfnnjmnjjjejkgjkgijeijelmhlnimninojgidlojnpklnilninpkijfijejkfnpklniklgijejlgklgkmhlnjklghicjjflnilniijejkfgicgicklgklgklgklhnokmnjjjetwsptojkfjkflnhlninojjlgiieopkprllnjjkfijeiieklhijehiejkfijehieijeijflnjklikliklgijelnimniklgfgbjkgklhijehidijelnjlmjijfggcfjeghcgiejkgllimnjlnijlghieijffgcgidijfghdlmhjkgwywpqlijeijfjlgjlgjkgklhnojprmpqlijehieijeijeklgjkfkmimnimniopklmiklglmiklhhhdeeadd`\]YQQMGHE;<:FFCPPLWXS[\Yde`efaefbqsnnokjkfjkfjkfikfijeghdikeikehidhidegbggcgidghckkfhidcd_bb^hidijeikeijdegbikelmhlmhikeghdhidikfosohjegidklgikeklgjkfefaikfegbhiejkfikfmoiijeikfjkgghcegbfgcghdiieghdkmhoqmprooqmjlgghdggdhiegidiieikelmhkmhikffgbefbdeaegbkokosnijelmikkhhidfgcegbghdikfhiegiecd`deaeealmkmnjhidefaefbghdikeghcggcghcggbklgefbegbijeikehidilglmiijelmhlmgefaghclmhklgghcghdhidiiemnifgbbb^hidiidghcefbijeghcefbqsnnokjkfjkfjkfikfijeghdikeikehidhidegbggcgidghckkfhidcd_bb^hidijeikeijdegbikelmhlmhikeghdhidikfosohjegidklgikeklgjkfefaikfegbhiejkfikfmoiijeikfjkgghcegbfgcghdiieghdkmhoqmprooqmjlgghdggdhiegidiieikelmhkmhikffgbefbdeaegbkokosnijelmikkhhidfgcegbghdikfhiegiecd`deaeealmkmnjhidefaefbghdikeghcggcghcggbklgefbegbijeikehidilglmiijelmhlmgefaghclmhklgefabc_^_[YYUSTPDEB775EFBPQMYZW`a]bc^ab^kkgrtpjkgjkfjkfggbdeafgbce`bc_efadeaghcefagickmgmnihidgicijegicde`ikfjkgikfgicefahjegidghcijegicopktxsghcde`efaefaklgee`efagidfhcgicdeadeaghcfgbdd_iieijefgcab^_`\gidnpljmggicegaefanplpqnjkgijfegcefafgbffafgbfgbfgcceadeaeeadfafjeegccc_ab^de`ce_de`gicjkfhiefgbefagiceebtusghcklgjkgdeacd_cd_cc_ab^de`ijeefacd_egakkgijebc^fhckkfjkgijeefaefafgbjlfijeijeghcefaikfjkgcc_bc^gicijejkgjkgghccd_kkgrtpjkgjkfjkfggbdeafgbce`bc_efadeaghcefagickmgmnihidgicijegicde`ikfjkgikfgicefahjegidghcijegicopktxsghcde`efaefaklgee`efagidfhcgicdeadeaghcfgbdd_iieijefgcab^_`\gidnpljmggicegaefanplpqnjkgijfegcefafgbffafgbfgbfgcceadeaeeadfafjeegccc_ab^de`ce_de`gicjkfhiefgbefagiceebtusghcklgjkgdeacd_cd_cc_ab^de`ijeefacd_egakkgijebc^fhckkfjkgijeefaefafgbjlfijeghcbc^[\XYZVQROBB@785EEBPPLXYT]^Z`b]efamojjmhhidijeefaac]ab]ab]ab]de`fgcce`ac]de`egaegacd^ghcde`de_bc^ac]bc^fgcfgchjecd_ac]de`egaegaac]hkfilhegaghcde`fgbefaefahhdefaegbcd_ce_de`efaghcefacc_ce_ce`efacd_egace`efaefaegbhjedeahiehjeac]cd`ac]ac]cd_cd_cd_deaegcghdcda^_ZY[X]_[__[ab]hieegbfhcefaegbghcce_de`cd_hiertpdeafgcfgcdeaaa]__[fgceea^_Zhjefgbggbijeghccd_cfafgbghcghdggbfgahieghcgidfgafgaefaegbcd_cc_bc_bc^ggchhdhidghcegbghcmojjmhhidijeefaac]ab]ab]ab]de`fgcce`ac]de`egaegacd^ghcde`de_bc^ac]bc^fgcfgchjecd_ac]de`egaegaac]hkfilhegaghcde`fgbefaefahhdefaegbcd_ce_de`efaghcefacc_ce_ce`efacd_egace`efaefaegbhjedeahiehjeac]cd`ac]ac]cd_cd_cd_deaegcghdcda^_ZY[X]_[__[ab]hieegbfhcefaegbghcce_de`cd_hiertpdeafgcfgcdeaaa]__[fgceea^_Zhjefgbggbijeghccd_cfafgbghcghdggbfgahieghcgidfgade_`a\[]YSTPLLIBB@785DDALLIRSO\]Y^_[ab^ab^ijecd`ac^`a\^`[bc_cea`b^bd_`a\ac^^`[^`[_`\ac^de`cd_ab^ac^_`\`a]^`[\^Yce`egaac^_`\ac^`a\ab]cd_eiccea`a\bd^ce`cd_`a]`a\`a\ac^`a]cd``a\ab^bc^de`ab^``\bd`ac_`b]ce`^`[_`[ab^aa^ce`deabc_aa^bc^`a\deaeeacc_deacd`ce`bd_bc_ce``b^``\`b]eicefa`a^_`\ceajlheeaac^`a^deagid_`[`a]ije`a\ac^`a]`a\cd`aa^aa]cc^de`bd_``\`a\ce_egaehcdgabc^bc^`a\ab]de`fgade`de`de`_`[`b]ac^aa^^_[`a]bc^efacc`ab^fgbcd_cd_ab^ijecd`ac^`a\^`[bc_cea`b^bd_`a\ac^^`[^`[_`\ac^de`cd_ab^ac^_`\`a]^`[\^Yce`egaac^_`\ac^`a\ab]cd_eiccea`a\bd^ce`cd_`a]`a\`a\ac^`a]cd``a\ab^bc^de`ab^``\bd`ac_`b]ce`^`[_`[ab^aa^ce`deabc_aa^bc^`a\deaeeacc_deacd`ce`bd_bc_ce``b^``\`b]eicefa`a^_`\ceajlheeaac^`a^deagid_`[`a]ije`a\ac^`a]`a\cd`aa^aa]cc^de`bd_``\`a\ce_egaehcdgabc^bc^`a\ab]de`fgade`de`de`^^Z[]YXZURROHIF@A>785BC@IIFMNIUVQ[[W]^Z_a[efa_`[_`[ac_ab]aa]_a]^`[]_[[]X[\X[]X[\X_a\`a]_a[_a\bc__a[ac^ac]`a\]_Y`a\bd_`b]_`[\]X]]X`a\`a\`c]ac^]^X_`[bd_^`[_a\ac]]_Z__[^_Z^_Z__[[]X\]X`a]^`[]^Y]_[_`[_a[`a\cd_cc_`a\__[]_Y]_Yab]_`\\]Y`a]cd_de`ab]]^Y[\W]_Y^_[]^Y\]Y]^Yac_ac]ceaac_`a]_`[__[`a]cd_cd_`a\_`[ab]ad_]^Ybd_`a]\]Yab]^`[`a]__[]^Y]^X`a[ac^\_[^b]^a\`b\aa\cc]cd_ab]ab\`a\_`[`a[bd__`[\]X`a\ac]_`[]_Z[]X]^Y]_Ycd`_`[[\W^_Y_`[^_[_a[efa_`[_`[ac_ab]aa]_a]^`[]_[[]X[\X[]X[\X_a\`a]_a[_a\bc__a[ac^ac]`a\]_Y`a\bd_`b]_`[\]X]]X`a\`a\`c]ac^]^X_`[bd_^`[_a\ac]]_Z__[^_Z^_Z__[[]X\]X`a]^`[]^Y]_[_`[_a[`a\cd_cc_`a\__[]_Y]_Yab]_`\\]Y`a]cd_de`ab]]^Y[\W]_Y^_[]^Y\]Y]^Yac_ac]ceaac_`a]_`[__[`a]cd_cd_`a\_`[ab]ad_]^Ybd_`a]\]Yab]^`[`a]__[]^Y]^X`a[ac^\_[^b]^a\`b\aa\cc]cd_ab]ab\`a\_`[`a[bd__`[\]X^_[\^YVWRNPLFGC>?<452<=:FFCMMIQQMVWSZZVbc^`a]]^Y^_[[\W^_Z]_[]^ZZ\W[\W^_[[\XY[W\]Y^`\Y[WXYT\]W^`[]^Z]^Y_`[^_Z]]YY[U\]Y`b]^`\Y[V[\W]_Z]^Ydf`kok[\W\^Y\]Y]_[[]X\]Y^`[^^Z^`[]^Z\]X]^Z[]X[]XZ[W^_[[\WYZU]]Y^`[_`\^_[\]Y[\WY[UZ[VZ[W]_[[\W[]XZ[WWXT]^[`b]^`[`a]ab^]^Z\]X[]X]^ZVXTUWSWXS\]X]]Y\\X^^[_`\bb^_`[]^Y^^Z`b]^`[df`]^YZ[V]^Y^`[^`[[\W^_[`a\bd_^b]\^Y\^Y]^Y[\W^`[`a]^^Ybc^``[]^Y]]X]^X]_Z[[V[[W^`[\]Y]_[[\WXYU]^Z^`\Y[V[\W[[WYYUZ[W[[Wbc^`a]]^Y^_[[\W^_Z]_[]^ZZ\W[\W^_[[\XY[W\]Y^`\Y[WXYT\]W^`[]^Z]^Y_`[^_Z]]YY[U\]Y`b]^`\Y[V[\W]_Z]^Ydf`kok[\W\^Y\]Y]_[[]X\]Y^`[^^Z^`[]^Z\]X]^Z[]X[]XZ[W^_[[\WYZU]]Y^`[_`\^_[\]Y[\WY[UZ[VZ[W]_[[\W[]XZ[WWXT]^[`b]^`[`a]ab^]^Z\]X[]X]^ZVXTUWSWXS\]X]]Y\\X^^[_`\bb^_`[]^Y^^Z`b]^`[df`]^YZ[V]^Y^`[^`[[\W^_[`a\bd_^b]\^Y\^Y]^Y[\W^`[`a]^^Ybc^``[]^Y]]X]^X]_Z[[V[[W]^ZXYUTVRMNICDA>?<564896EEBIIEQQLXYT]^Ybc_]^Z[\XZ[VXYUXZUZ[V[]XVWSVXSXZUTUQVWS\^YXZVY\V]`[Z\VYZU[\W[\W\]XZ\V]^ZYZUVWSZ\V^`\\^YZ\W\^YYZV]^Zbe`^`[\]XXZU\]XZ\WXYU\^YYZV[\X[\X[]XY[VWXSWXTUVSVVRWXSWXTXYT^`\Z\XWXSUVRXYUXZUZZVYZVWYUXXUUUQXZUZ[V]^Z`b^^`\\^Y^`[`b]`b]]^YVVSLNISUPXXTYZVZ\WYZUZZV\\X^`\]^Y^`ZXZUZ\W``\ike\]YYYU\]XXZUVXSXZU\_Z`c^^`ZXZUTUPVVQZ\V\]X[\WZ\V]^Z\]X\]XZZVYZUZ[VVXSYZUXXTUUPYZUZZVVVQZ\V\]X_`[TUPZZVVWRYYT\]X^`Zbc_]^Z[\XZ[VXYUXZUZ[V[]XVWSVXSXZUTUQVWS\^YXZVY\V]`[Z\VYZU[\W[\W\]XZ\V]^ZYZUVWSZ\V^`\\^YZ\W\^YYZV]^Zbe`^`[\]XXZU\]XZ\WXYU\^YYZV[\X[\X[]XY[VWXSWXTUVSVVRWXSWXTXYT^`\Z\XWXSUVRXYUXZUZZVYZVWYUXXUUUQXZUZ[V]^Z`b^^`\\^Y^`[`b]`b]]^YVVSLNISUPXXTYZVZ\WYZUZZV\\X^`\]^Y^`ZXZUZ\W``\ike\]YYYU\]XXZUVXSXZU\_Z`c^^`ZXZUTUPVVQZ\V\]X[\WZ\V]^Z\]X\]XZZVYZUZ[VVXSYZUXXTTTOUVQRRNIIDEFB>>;563::7CC@IJEPQLTUPYZWZ[WXYTTUQTVQVXSVWRXZUTUPTTPTTPSTOVXRWXRXZUQRNTUPYZV\_[X[XRTOXYTZZUYZVZ[VXZUVWRTUPXZUZ[WWYTUWRVWRPRMTUPac]UWQUVQZ]XUVRTTPSTPRTOTTPRTNTUPXZUZ[VZ[WWXTQRNVVQTTORRNWYTXYTWXTUVQXYTVXSVVRTVQTTPWXSXYT[[W[\W[]XZ[VVXTVXSTUPTUPUVQUVQVXTUXSWYTUVQTTOSTOVVRRRNTUQZ[W[]XVXRRSNTUP_a]hjfVVRYZVVWRVXTZ\X\^ZZ[VXZTUVQRRNONKVXRZ[VZ[VXYTUVRVXRUVQYZUZZV[\XXYTUVQVXRUVQVXSVXTVWRTVPWXRVWR[\XVWRWXTVXRXYTXYTZ[XZ[WXYTTUQTVQVXSVWRXZUTUPTTPTTPSTOVXRWXRXZUQRNTUPYZV\_[X[XRTOXYTZZUYZVZ[VXZUVWRTUPXZUZ[WWYTUWRVWRPRMTUPac]UWQUVQZ]XUVRTTPSTPRTOTTPRTNTUPXZUZ[VZ[WWXTQRNVVQTTORRNWYTXYTWXTUVQXYTVXSVVRTVQTTPWXSXYT[[W[\W[]XZ[VVXTVXSTUPTUPUVQUVQVXTUXSWYTUVQTTOSTOVVRRRNTUQZ[W[]XVXRRSNTUP_a]hjfVVRYZVVWRVXTZ\X\^ZZ[VXZTUVQRRNONKVXRZ[VZ[VXYTUVRVXRUVQYZUZZV[\XXYTUVQVXRUVQUWRRTPNOJGICCC?::7341886??:BB>GHCHIEMOKNQLNPKRTPPQLNPJQRMKLHPPLTVQRTOOPKRSNRTNNPKRTNOPLNPKPPKNNJRTOSVQORNNPLOPJPQLNPKRSNQRNNPKLNHLNHIJFMNIIJEJKGHHCHHDMNHNNIMMIPQLRTNTTPSTPRRNSUOWZU[_[^c_\_[STPPQLRUOTUPPRMPRLLNHLNIPQLNNJPRLSTPPPLPRMPRMNPJLNILNIPRMPQLSTORSNOPKQRMGHEHJEMNJRTOTVSSTOMNHMNIMNJMNJQRNOPLPQMRTNVXU^a]UWRNPKOPLOPLLMHLLHGGCFGCPPLPRLOQLRTORSNOPJPQLRTORSNPQLPQMNOJPQLRSNPRLPPLPQLPQLTUPPQLRTNRTORTOPQLPQMPQLNNJNOJLMHNPLNQLNPKRTPPQLNPJQRMKLHPPLTVQRTOOPKRSNRTNNPKRTNOPLNPKPPKNNJRTOSVQORNNPLOPJPQLNPKRSNQRNNPKLNHLNHIJFMNIIJEJKGHHCHHDMNHNNIMMIPQLRTNTTPSTPRRNSUOWZU[_[^c_\_[STPPQLRUOTUPPRMPRLLNHLNIPQLNNJPRLSTPPPLPRMPRMNPJLNILNIPRMPQLSTORSNOPKQRMGHEHJEMNJRTOTVSSTOMNHMNIMNJMNJQRNOPLPQMRTNVXU^a]UWRNPKOPLOPLLMHLLHGGCFGCPPLPRLOQLRTORSNOPJPQLRTORSNPQLPQMNOJPQLRSNPRLPPLPQLOPKPQLHIEEGB?@<785--+441<=9?A>DF@KLGOPLNOJPQMMNJMNIKKGGGCMNJNOKNPKKMHOPKRTNMNIKLGNPKPQMOQMIKEIJEKMHMNJMPKPSNMOJKLGMNINOKNPKPRMMNIJKGKMGFGCGGCIIDFGBJJELMGMNIJKEOPJQSMPRLPRLSUOW[U\b]_caRTPPRMLMIOPLPRMRRNLMHOPKPPKMNILMINPKMNJNOKKMIKLGHJEIKFNNJPRMOPLPRMNPKMNIKMGKLGKMHMNIKLGMNIJKGNOLJKGHIEKLGNOKNPMLNINPKNOJMNIPRMPRMKMHJKGIJEKLGMNIKMHGGCFGBOPKNPKQSNNOKJKEMNHJKGMNIMNIMNIOPKMNIJKGKLGMMIKLGMOKOQMLMIMNJNOJRSNMNIMNIOPKKMIKMGOPKPQMNOJPQMMNJMNIKKGGGCMNJNOKNPKKMHOPKRTNMNIKLGNPKPQMOQMIKEIJEKMHMNJMPKPSNMOJKLGMNINOKNPKPRMMNIJKGKMGFGCGGCIIDFGBJJELMGMNIJKEOPJQSMPRLPRLSUOW[U\b]_caRTPPRMLMIOPLPRMRRNLMHOPKPPKMNILMINPKMNJNOKKMIKLGHJEIKFNNJPRMOPLPRMNPKMNIKMGKLGKMHMNIKLGMNIJKGNOLJKGHIEKLGNOKNPMLNINPKNOJMNIPRMPRMKMHJKGIJEKLGMNIKMHGGCFGBOPKNPKQSNNOKJKEMNHJKGMNIMNIMNIOPKMNIJKGKLGMMIKLGLNJKMIEFBAB><<9784+,)341896@B=AC?GHEIJEHHDIJEKLGJLFHHDFGCJKFJLFGHCHIDNOJKMHIJEHIDJKELLHNOJNOJHIDFHCKLGMNINQLLOJJLHLMIDEACD?HIDIJFHIDIJFGHDFGBDD@HJDJLFLMHIJEILFORLORLPSLQUNUZU[`\Y]YNNJFHCJLGJLGLMHOPLJLGIJENOJPPKKLGFFBHIDEFAHIDKLGEFAEFCJLHLLHMNJKLHLMHJKFDEAJKFGHCDE@GHCGHDFHCFHCKLHHIEFGCHIDJLGNPLIKFLNIHIDJLFNNJMNJHJEDD???;@A=EGBFGCHIDKLHHJDFHCJLGLLHHIDJJFHIEIJEHIDHIDLNIIKFGHCGHCJLGGHDHJFIJFHIDJKFNPKKLHFFBLMIIJFLNHHJFJLHJKFHHDIJEKLGJLFHHDFGCJKFJLFGHCHIDNOJKMHIJEHIDJKELLHNOJNOJHIDFHCKLGMNINQLLOJJLHLMIDEACD?HIDIJFHIDIJFGHDFGBDD@HJDJLFLMHIJEILFORLORLPSLQUNUZU[`\Y]YNNJFHCJLGJLGLMHOPLJLGIJENOJPPKKLGFFBHIDEFAHIDKLGEFAEFCJLHLLHMNJKLHLMHJKFDEAJKFGHCDE@GHCGHDFHCFHCKLHHIEFGCHIDJLGNPLIKFLNIHIDJLFNNJMNJHJEDD???;@A=EGBFGCHIDKLHHJDFHCJLGLLHHIDJJFHIEIJEHIDHIDLNIIKFGHCGHCJLGGHDGIEFGCAB>>?;<=9230''%332684;<8?@KLGEFAAA=DFBGHDFGCFGBFGBGHDDFBEGBGHCFGBEFAIKFGIEGHD@B>EFBGHDGIDIKFKLGJLGGHCCD?DE@@B=EF@GIDHJFHIEGHDGHCGHCFGCGIE@B>GIDLOJLPKOSOLQLPSOQSPLMIGHCFGBKMINPKKMHHIDFGBHIDGHDJKFFFB@AAB>BD>FGBGIDJKGIKFEFBFGBGIEIKGIJFGGCEFBIIFGHDKKGJKFGHDDE@@A<@A<@BCD?DFBDFADD@CD@DD@BB>AB=BB>CD@CD@BC>BC>DE@DGBFHCIKFGHDIKFFGCEFALMKGIDFHCFGBGIFBB>BB>KLGEFAAA=DFBGHDFGCFGBFGBGHDDFBEGBGHCFGBEFAIKFGIEGHD@B>EFBGHDGIDIKFKLGJLGGHCCD?DE@@B=EF@GIDHJFHIEGHDGHCGHCFGCGIE@B>GIDLOJLPKOSOLQLPSOQSPLMIGHCFGBKMINPKKMHHIDFGBHIDGHDJKFFFB@AAB>BD>FGBGIDJKGIKFEFBFGBGIEIKGIJFGGCEFBIIFGHDKKGJKFGHDDE@@A<@A<@BCD?DFBDFADD@CD@DD@BB>AB=BB>CD@CD@BC>BC>DE@CFABD@BD?<<9895//-&'$453563562:;7?@=@A=@A<=>:<<9==9?@BD>BD>DE@DFA>@;AB>DE@DE@DE@BD?@B<<>:>A<>?;BD>FHBBC>BD>DE@BB=DEABD?BC>BC>BB>@B=@A=BD?AB=BB>AB=>@;<=9AB>AB>AB>AC>HJFEHD=>:@A<@B=>@;BC>DE@EFADE?BD>BD?CD?EFBBC>@B=?ABD?AB>DE@BD@BB=@A@;<=9@B=@A<=>:EGBCD@CD@EGCBC>AC>@B==>:=>9>?;@B=DIDEJEBD?>?;BD>CD>@ABD?@A<>>9BC>BC>@A<@B<=>:AB>::7AB=?@;AB>DFABD@@AAC>>@;>?;OQMFGC?@<@B=BD@AB>@A<=>:<<9==9?@BD>BD>DE@DFA>@;AB>DE@DE@DE@BD?@B<<>:>A<>?;BD>FHBBC>BD>DE@BB=DEABD?BC>BC>BB>@B=@A=BD?AB=BB>AB=>@;<=9AB>AB>AB>AC>HJFEHD=>:@A<@B=>@;BC>DE@EFADE?BD>BD?CD?EFBBC>@B=?ABD?AB>DE@BD@BB=@A@;<=9@B=@A<=>:EGBCD@CD@EGCBC>AC>@B==>:=>9>?;@B=DIDEJEBD?>?;BD>CD>@ABD?@A<>>9BC>BC>@A<@B<=>:AB>::7AB=?@;AB>CD@?@=::678413/)*'"#!((&232451895@B>?A>?A<9;5=>9>?:;<7=>9<>9;=8<=9<=9:<7;=8BC??@;?@;=?9=?9:;6?A=?A=5529;5?@;?@;>?:=?9?@;=>9=?:;<7;<8794=>:=?9=?99;5:;7=?:;=8894<=9?A=?@<>@9=?9<=9;=8=?9>?:>?:?@9@A==?:<=89959;7@A=9;6794?@==>9AB?BC?BD?<>9=?:>@;?@?;9;59:5;<7=?:==9;<79;7@B=?A<<=9;<7=?:<=8=>9;<7=>9@B=<=9662;;6=>9=?;;=9==9:;7;<7:;7AC?DEB<=9CDB>@;?@;DFBAC??A<9;5=>9>?:;<7=>9<>9;=8<=9<=9:<7;=8BC??@;?@;=?9=?9:;6?A=?A=5529;5?@;?@;>?:=?9?@;=>9=?:;<7;<8794=>:=?9=?99;5:;7=?:;=8894<=9?A=?@<>@9=?9<=9;=8=?9>?:>?:?@9@A==?:<=89959;7@A=9;6794?@==>9AB?BC?BD?<>9=?:>@;?@?;9;59:5;<7=?:==9;<79;7@B=?A<<=9;<7=?:<=8=>9;<7=>9@B=<=9662;;6=>9=?;:<8::645212.,,*+,)%&$"# +,*/0.563896:;879567477467456255179589556367357334/8959;77847836747949;5552/0,12.67457457357344056378478457457445157379455123/34/5745636847853413409958959<7795674563562551673:;5;=8;=85529;5;<7553674563573563563573573451451451552553563:;77959;7:<8<>9=?;;=88955635734517849;74515749:557334059546333/4516747959<79<7574795674552451574573573784573795:;678411-5529;6552451574795=?;@C???=451:;89:7;=9<=9;=979567477467456255179589556367357334/8959;77847836747949;5552/0,12.67457457357344056378478457457445157379455123/34/5745636847853413409958959<7795674563562551673:;5;=8;=85529;5;<7553674563573563563573573451451451552553563:;77959;7:<8<>9=?;;=88955635734517849;74515749:557334059546333/4516747959<79<7574795674552451574573573784573795:;678411-5529;644112.02../,-/,*,)"#!"#))&/0,13/13/22.22.02.23/02./0,23.02.12.00-01-23/02-02.01-23.22.13.01-./+/0,/0-./,02.-.*..*..+02-/0-./+-.*02..0-02.13.13./0,..)-.)02..0,.0-./+03//0-..+02.23/23.12.,-(/0,23.23.340.0,.0,-.*.0,--)./,./+-.+230341/0--.+-.+02.342340.0,)+(..+.0-.0+02.13.02../+++(-.)12.01-01-02.02.341.0,,-)((%,0,..+./+13/12...*02-/0,..+./+/0-13.23.23/./+-.).0,.0+..+/0+02./0-,-)/0-23/23/2409<835202./0,/0,..*22.46246234023.22.02.23/02./0,23.02.12.00-01-23/02-02.01-23.22.13.01-./+/0,/0-./,02.-.*..*..+02-/0-./+-.*02..0-02.13.13./0,..)-.)02..0,.0-./+03//0-..+02.23/23.12.,-(/0,23.23.340.0,.0,-.*.0,--)./,./+-.+230341/0--.+-.+02.342340.0,)+(..+.0-.0+02.13.02../+++(-.)12.01-01-02.02.341.0,,-)((%,0,..+./+13/12...*02-/0,..+./+/0-13.23.23/./+-.).0,.0+..+/0+02./0-,-)/0,12./0-,/+/2/&(% #$!%&#*+'*+'*+'*+'+,()+&+,)))&'(%)*&*+'))&+,(,-)()%)+'*+'()%&($()%&(%()%))%))&()%))&()%()%+,())%&($()%+,('(%()&)+')+')*&+,(,-)()%'(%()%%&#*+(.0,*+(&($()%&($+,(+,)()%++(*+(*+')+')*&)*&()%)*&'(%$%"()&%&"&&#'(%)+'*,(+,)+,)&'$&'$()%&'$&&#((%+,(,-)+,()*',,*,,),,)++()*&+,),.*&'$$%")*&()&+,)+.+&'$)*&'(%$$!()%*+'()%((%+,(+,)+,())&)*&'(%&($&($%%"%&#))&()%,,)*,)*,)*,(*,(&'$)+(+,)'(%&'$)*&()%+,)*+',.*+,(*+'*+'+,()+&+,)))&'(%)*&*+'))&+,(,-)()%)+'*+'()%&($()%&(%()%))%))&()%))&()%()%+,())%&($()%+,('(%()&)+')+')*&+,(,-)()%'(%()%%&#*+(.0,*+(&($()%&($+,(+,)()%++(*+(*+')+')*&)*&()%)*&'(%$%"()&%&"&&#'(%)+'*,(+,)+,)&'$&'$()%&'$&&#((%+,(,-)+,()*',,*,,),,)++()*&+,),.*&'$$%")*&()&+,)+.+&'$)*&'(%$$!()%*+'()%((%+,(+,)+,())&)*&'(%&($&($%%"%&#))&()%,,)*,)*,))*'')%"# "#! !!"!"%&###!$%"$$" !"#"# #$""#!"!""#  " "## #$ !"#$! """# "# #$!#$!"# !" ! #$ #$  !"!""# !" !"# %&#%&#!""# "" !" ! "!"!""#""#$ !"# !" !#$ #$ !" "#$!!" ! $$"$%"&($$%"')&()&&&$#$!$$!"#"# !!"!"$%" ! #$! $%"%&#"" !$%"$%" ! !"# !"#$  " "## "# &(%&(%!"!"  !#$ !" "$%" #$ $%"%&$$$"&'$$$!$%"$$" !"#"# #$""#!"!""#  " "## #$ !"#$! """# "# #$!#$!"# !" ! #$ #$  !"!""# !" !"# %&#%&#!""# "" !" ! "!"!""#""#$ !"# !" !#$ #$ !" "#$!!" ! $$"$%"&($$%"')&()&&&$#$!$$!"#"# !!"!"$%" ! #$! $%"%&#"" !$%"$%" ! !"# !"#$  " "## "# &(%&(%!! ! 2 | TRUEVISION-XFILE. -------------------------------------------------------------------------------- /core/Castbar.lua: -------------------------------------------------------------------------------- 1 | --Aimed Shot workaround based on rais_Autoshot. All credit for that goes straight to raisnilt. 2 | 3 | function Punsch_Castbar_Create() 4 | local db = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Castbar"] 5 | PunschEntities["Castbar"] = {} 6 | local e = PunschEntities["Castbar"] 7 | e.Type = "Castbar" 8 | Punsch_Bar_Create(e,db) 9 | 10 | e.text3 = e.TextFrame:CreateFontString(nil,"OVERLAY") 11 | e.text3:SetFont(GameFontHighlight:GetFont(), 10) 12 | e.text3:SetText("+0.0") 13 | 14 | e.lagBG = e.ContentFrame:CreateTexture(nil,"ARTWORK") 15 | e.lagBG:SetPoint("BOTTOMRIGHT",e.ContentFrame) 16 | e.lagBG:SetPoint("TOP",e.ContentFrame) 17 | e.lagBG:SetWidth(5) 18 | 19 | e.lagtxt = e.TextFrame:CreateFontString(nil,"OVERLAY") 20 | e.lagtxt:SetFont(GameFontHighlight:GetFont(), 8) 21 | e.lagtxt:SetText("0ms") 22 | e.lagtxt:SetPoint("RIGHT",e.lagBG,"BOTTOMRIGHT") 23 | 24 | e.Tooltip = CreateFrame("GameTooltip","Punsch_Castbar_Tooltip",UIParent,"GameTooltipTemplate") 25 | e.Tooltip:SetOwner(UIParent,"ANCHOR_NONE") 26 | 27 | e.isCasting = false 28 | e.isChannel = false 29 | e.spellName = "" 30 | e.delayedBy = 0 31 | e.fadeTimeleft = 0 32 | 33 | --keeps track of max spellranks 34 | e.spellDB = {} 35 | 36 | --keeps track of recently cast spells to provide icons and ranks in macros/spellbook 37 | e.recentlyCastSpells = {} 38 | 39 | --keeps track of icons for 40 | e.spellRankIcons = {} 41 | 42 | --initializing ranged haste for aimedshot workaround 43 | e.HasteFromBerserking = 1 44 | e.HasteFromQuickShots = 1 45 | e.HasteFromKiss = 1 46 | e.HasteFromRapid = 1 47 | e.HasteFromAncientDespair = 1 48 | 49 | --Channeling Ticks 50 | e.TickIndicators = {} 51 | 52 | e.TicksShown = 0 53 | 54 | for i=1,15 do 55 | e.TickIndicators[i] = {} 56 | 57 | e.TickIndicators[i].texture = e.ContentFrame:CreateTexture(nil,"OVERLAY") 58 | e.TickIndicators[i].texture:SetTexture(0,0,0,1) 59 | e.TickIndicators[i].texture:Hide() 60 | end 61 | 62 | --Hooks 63 | PunschEntities["Castbar"].OriginalUseAction = UseAction 64 | UseAction = Punsch_Castbar_HookUseAction 65 | 66 | PunschEntities["Castbar"].OriginalCastSpell = CastSpell 67 | CastSpell = Punsch_Castbar_HookCastSpell 68 | 69 | PunschEntities["Castbar"].OriginalCastSpellByName = CastSpellByName 70 | CastSpellByName = Punsch_Castbar_HookCastSpellByName 71 | 72 | PunschEntities["Castbar"].OriginalDoTradeSkill = DoTradeSkill 73 | DoTradeSkill = Punsch_Castbar_HookDoTradeSkill 74 | 75 | e.self:SetScript("OnEvent",Punsch_Castbar_OnEvent) 76 | e.self:SetScript("OnUpdate",Punsch_Castbar_OnUpdate) 77 | 78 | e.self:RegisterEvent("SPELLCAST_CHANNEL_START") 79 | e.self:RegisterEvent("SPELLCAST_CHANNEL_STOP") 80 | e.self:RegisterEvent("SPELLCAST_CHANNEL_UPDATE") 81 | e.self:RegisterEvent("SPELLCAST_DELAYED") 82 | e.self:RegisterEvent("SPELLCAST_FAILED") 83 | e.self:RegisterEvent("SPELLCAST_INTERRUPTED") 84 | e.self:RegisterEvent("SPELLCAST_START") 85 | e.self:RegisterEvent("SPELLCAST_STOP") 86 | 87 | --keeps track of spellbook changes for macro icon/ranks 88 | e.self:RegisterEvent("SPELLS_CHANGED") 89 | 90 | --keeps track of buffs on self 91 | e.self:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_SELF") 92 | e.self:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS") 93 | e.self:RegisterEvent("PLAYER_DEAD") 94 | 95 | --e.self:RegisterEvent("UNIT_MANA") 96 | end 97 | 98 | local RomanNumerals = { 99 | "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII" 100 | } 101 | 102 | function Punsch_Castbar_Update(e) 103 | local db = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Castbar"] 104 | 105 | if db.HideBlizzardBar then 106 | CastingBarFrame:UnregisterEvent("SPELLCAST_START") 107 | CastingBarFrame:UnregisterEvent("SPELLCAST_STOP") 108 | CastingBarFrame:UnregisterEvent("SPELLCAST_FAILED") 109 | CastingBarFrame:UnregisterEvent("SPELLCAST_INTERRUPTED") 110 | CastingBarFrame:UnregisterEvent("SPELLCAST_DELAYED") 111 | CastingBarFrame:UnregisterEvent("SPELLCAST_CHANNEL_START") 112 | CastingBarFrame:UnregisterEvent("SPELLCAST_CHANNEL_UPDATE") 113 | CastingBarFrame:UnregisterEvent("SPELLCAST_CHANNEL_STOP") 114 | else 115 | CastingBarFrame:RegisterEvent("SPELLCAST_START") 116 | CastingBarFrame:RegisterEvent("SPELLCAST_STOP") 117 | CastingBarFrame:RegisterEvent("SPELLCAST_FAILED") 118 | CastingBarFrame:RegisterEvent("SPELLCAST_INTERRUPTED") 119 | CastingBarFrame:RegisterEvent("SPELLCAST_DELAYED") 120 | CastingBarFrame:RegisterEvent("SPELLCAST_CHANNEL_START") 121 | CastingBarFrame:RegisterEvent("SPELLCAST_CHANNEL_UPDATE") 122 | CastingBarFrame:RegisterEvent("SPELLCAST_CHANNEL_STOP") 123 | end 124 | 125 | e.lagBG:SetTexture(Punschrulle_GetTexture(db.Texture)) 126 | e.lagBG:SetVertexColor(db.Lag.r,db.Lag.g,db.Lag.b,db.Lag.a) 127 | 128 | e.ShowLag = db.ShowLag 129 | e.TickEnable = db.Tick.Enable 130 | e.TickWidth = db.Tick.Width 131 | e.TickTop = db.Tick.TopAnchor 132 | e.TickBot = db.Tick.BotAnchor 133 | 134 | e.ShowRank = db.ShowRank 135 | e.RankAsRoman =db.RankAsRoman 136 | e.RankAsShort = db.RankAsShort 137 | e.UCSN = db.UpperCaseSpellName 138 | 139 | e.multishot = db.ShowMultiShot 140 | e.aimedshot = db.ShowAimedShot 141 | 142 | e.fadeTolerance = db.Fade.Tolerance 143 | e.fadesht = db.Fade.SuccessHoldTime 144 | e.fadefht = db.Fade.FailureHoldTime 145 | e.PlayerInterruptAsFailure = db.PlayerInterruptAsFailure 146 | e.fadeshowlag = db.Fade.ShowLagWhileFading 147 | 148 | e.CountUpOnChannel = db.CountUpOnChannel 149 | e.CountUpOnCast = db.CountUpOnCast 150 | 151 | e.channelDelayToDuration = db.ChannelDelayToDuration 152 | 153 | e.text3:SetFont(Punschrulle_GetFont(db.TextDelay.Font), db.TextDelay.FontSize) 154 | e.text3:SetShadowOffset(db.TextDelay.FontShadowX,db.TextDelay.FontShadowY) 155 | if db.TextDelay.AnchorToDuration then 156 | e.text3:SetPoint(db.TextDelay.Point, e.text2,db.TextDelay.rPoint,db.TextDelay.X,db.TextDelay.Y) 157 | else 158 | e.text3:SetPoint(db.TextDelay.Point, e.self,db.TextDelay.rPoint,db.TextDelay.X,db.TextDelay.Y) 159 | end 160 | e.text3:SetTextColor(db.TextDelay.r,db.TextDelay.g,db.TextDelay.b,db.TextDelay.a) 161 | e.text3:SetShadowColor(db.TextDelay.sr,db.TextDelay.sg,db.TextDelay.sb,db.TextDelay.sa) 162 | e.text3:SetText("+0.0") 163 | 164 | e.lagtxt:SetFont(Punschrulle_GetFont(db.TextLag.Font), db.TextLag.FontSize) 165 | e.lagtxt:SetShadowOffset(db.TextLag.FontShadowX,db.TextLag.FontShadowY) 166 | e.lagtxt:SetTextColor(db.TextLag.r,db.TextLag.g,db.TextLag.b,db.TextLag.a) 167 | e.lagtxt:SetShadowColor(db.TextLag.sr,db.TextLag.sg,db.TextLag.sb,db.TextLag.sa) 168 | 169 | --needed for shadowoffset to properly update. 170 | local t = e.lagtxt:GetText() 171 | e.lagtxt:SetText("") 172 | e.lagtxt:SetText(t) 173 | 174 | Punsch_Bar_Update(e,db) 175 | if e.ShowIcon then 176 | e.self:SetPoint(db.Anchor.Point, 177 | UIParent, 178 | db.Anchor.rPoint, 179 | db.Anchor.X+db.Height, 180 | db.Anchor.Y) 181 | else 182 | e.self:SetPoint(db.Anchor.Point, 183 | UIParent, 184 | db.Anchor.rPoint, 185 | db.Anchor.X, 186 | db.Anchor.Y) 187 | end 188 | 189 | --if db.MultiLineSpellName then 190 | -- e.text1:SetPoint("RIGHT",e.text3,"LEFT") 191 | -- e.text1:SetNonSpaceWrap(false) 192 | 193 | --e.text1:SetWordWrap(true) 194 | --end 195 | 196 | for i=1,15 do 197 | --Tick.ShowLag 198 | if db.Tick.AsSolidColor then 199 | e.TickIndicators[i].texture:SetTexture(db.Tick.r,db.Tick.g,db.Tick.b,db.Tick.a) 200 | e.TickIndicators[i].texture:SetVertexColor(1,1,1,1) 201 | else 202 | e.TickIndicators[i].texture:SetTexture(Punschrulle_GetTexture(db.Texture)) 203 | e.TickIndicators[i].texture:SetVertexColor(db.Tick.r,db.Tick.g,db.Tick.b,db.Tick.a) 204 | end 205 | 206 | e.TickIndicators[i].texture:SetPoint("TOP",e.self,"TOP",0,-e.self:GetHeight()*e.TickTop) 207 | e.TickIndicators[i].texture:SetPoint("BOTTOM",e.self,"BOTTOM",0,e.self:GetHeight()*(1-e.TickBot)) 208 | 209 | e.TickIndicators[i].texture:SetWidth(e.TickWidth) 210 | end 211 | 212 | --update the ticks currently shown to new width, purely cosmetic 213 | for i=1,e.TicksShown do 214 | e.TickIndicators[i].texture:SetPoint("LEFT",e.self,"RIGHT",(-i*(e.self:GetWidth()/(e.TicksShown)))-(e.TickWidth/2),0) 215 | e.TickIndicators[i].texture:SetWidth(e.TickWidth) 216 | end 217 | end 218 | 219 | local debugCastbar = nil 220 | function Punsch_Castbar_OnEvent() 221 | if (event == "SPELLCAST_CHANNEL_START") then 222 | -- arg1 casttime in ms 223 | -- arg2 cast name (almost exclusively "Channeling") 224 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_CHANNEL_START " .. arg1 .. " " .. arg2) end 225 | Punsch_Castbar_OnChannelStart(arg2,arg1) 226 | elseif (event == "SPELLCAST_START") then 227 | --arg1 spell name 228 | --arg2 casttime in ms 229 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_START " .. arg1 .. " " .. arg2) end 230 | Punsch_Castbar_OnCastStart(arg1,arg2) 231 | elseif (event == "SPELLCAST_CHANNEL_STOP") then 232 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_CHANNEL_STOP ") end 233 | Punsch_Castbar_OnChannelStop() 234 | elseif (event == "SPELLCAST_CHANNEL_UPDATE") then 235 | --arg1 timeleft in ms 236 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_CHANNEL_UPDATE " ..arg1) end 237 | Punsch_Castbar_OnChannelUpdate(arg1) 238 | elseif (event == "SPELLCAST_DELAYED") then 239 | --arg1 delayed by in ms 240 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_DELAYED " ..arg1) end 241 | Punsch_Castbar_OnCastDelayed(arg1) 242 | elseif (event == "SPELLCAST_FAILED") then 243 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_FAILED ") end 244 | Punsch_Castbar_OnCastFailed() 245 | elseif (event == "SPELLCAST_INTERRUPTED") then 246 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_INTERRUPTED") end 247 | Punsch_Castbar_OnCastInterrupted() 248 | elseif (event == "SPELLCAST_STOP") then 249 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("SPELLCAST_STOP") end 250 | Punsch_Castbar_OnCastStop() 251 | PunschEntities["Castbar"].recentlyCastSpells = {} 252 | elseif (event == "CHAT_MSG_SPELL_AURA_GONE_SELF") then 253 | local buffName = strsub(arg1,0, -17) 254 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("CHAT_MSG_SPELL_AURA_GONE_SELF '" .. buffName .. "'") end 255 | if buffName == "Berserking" then 256 | PunschEntities["Castbar"].HasteFromBerserking = 1 257 | elseif buffName == "Quick Shots" then 258 | PunschEntities["Castbar"].HasteFromQuickShots = 1 259 | elseif buffName == "Kiss of the Spider" then 260 | PunschEntities["Castbar"].HasteFromKiss = 1 261 | elseif buffName == "Rapid Fire" then 262 | PunschEntities["Castbar"].HasteFromRapid = 1 263 | end 264 | elseif (event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS") then 265 | local _,nameend = strfind(arg1 .. " ", ".", -1) 266 | local buffName = strsub(arg1,10, nameend -2) 267 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS '" .. buffName .. "'") end 268 | if buffName == "Berserking" then 269 | if((UnitHealth("player")/UnitHealthMax("player")) >= 0.40) then 270 | PunschEntities["Castbar"].HasteFromBerserking = 1.3 - ((UnitHealth("player")/UnitHealthMax("player"))-0.4) * 5/3 * 0.2 271 | else 272 | PunschEntities["Castbar"].HasteFromBerserking = 1.30 273 | end 274 | elseif buffName == "Quick Shots" then 275 | PunschEntities["Castbar"].HasteFromQuickShots = 1.3 276 | elseif buffName == "Kiss of the Spider" then 277 | PunschEntities["Castbar"].HasteFromKiss = 1.2 278 | elseif buffName == "Rapid Fire" then 279 | PunschEntities["Castbar"].HasteFromRapid = 1.4 280 | end 281 | elseif (event =="PLAYER_DEAD") then 282 | if debugCastbar then DEFAULT_CHAT_FRAME:AddMessage("PLAYER_DEAD") end 283 | PunschEntities["Castbar"].HasteFromBerserking = 1 284 | PunschEntities["Castbar"].HasteFromQuickShots = 1 285 | PunschEntities["Castbar"].HasteFromKiss = 1 286 | PunschEntities["Castbar"].HasteFromRapid = 1 287 | PunschEntities["Castbar"].HasteFromAncientDespair = 1 288 | elseif (event == "SPELLS_CHANGED") then 289 | PunschEntities["Castbar"].spellDB = {} 290 | else 291 | DEFAULT_CHAT_FRAME:AddMessage("unhandled: " .. event .. ", " .. tostring(arg1).. tostring(arg2).. tostring(arg3).. tostring(arg4)) 292 | end 293 | end 294 | 295 | function Punsch_Castbar_HookDoTradeSkill(index, repeatTimes) 296 | local e = PunschEntities["Castbar"] 297 | e.LastTradeskillName = GetTradeSkillInfo(index) 298 | e.LastTradeskillIcon = GetTradeSkillIcon(index) 299 | e.LastTradeskillRepeatTimes = repeatTimes 300 | e.LastTradeskillRepeatedTimes = 0 301 | PunschEntities["Castbar"].OriginalDoTradeSkill(index, repeatTimes) 302 | end 303 | 304 | function Punsch_Castbar_HookUseAction(slot, checkCursor, onSelf) 305 | local e = PunschEntities["Castbar"] 306 | if not IsCurrentAction(slot) then 307 | e.LastSpellDropOnLoseIsCurrentAction = nil 308 | e.LastSpellSetOnLoseIsTargeting = nil 309 | e.LastSpellLocalCast = nil 310 | e.LastSpellIcon = nil 311 | e.LastSpellRank = nil 312 | e.OriginalUseAction(slot,checkCursor,onSelf) 313 | else 314 | e.OriginalUseAction(slot,checkCursor,onSelf) 315 | return 316 | end 317 | 318 | --detecting Aimed Shot 319 | if IsCurrentAction(slot) then 320 | if GetActionText(slot) == nil then 321 | Punsch_Castbar_TooltipTextLeft1:SetText() 322 | Punsch_Castbar_TooltipTextRight1:SetText() 323 | e.Tooltip:SetAction(slot) 324 | local spellName = Punsch_Castbar_TooltipTextLeft1:GetText() 325 | if ( spellName == "Aimed Shot" ) then 326 | Punsch_Castbar_CastAimedShot() 327 | elseif ( spellName == "Multi-Shot" ) then 328 | Punsch_Castbar_CastMultiShot() 329 | end 330 | end 331 | --lag, icons, rank 332 | if not IsAttackAction(slot) then 333 | if GetActionText(slot) == nil then 334 | e.LastSpellRank = Punsch_Castbar_TooltipTextRight1:GetText() 335 | e.LastSpellIcon = GetActionTexture(slot) 336 | else 337 | e.LastSpellRank = "macro" 338 | e.LastSpellIcon = "macro" 339 | end 340 | e.LastUseActionSlot = slot 341 | if SpellIsTargeting() then -- await targeting ending, should happen when player has set a target 342 | e.LastSpellSetOnLoseIsTargeting = true 343 | else --tentatively keep it until next spellcast or slot is no longer "IsCurrentAction" 344 | e.LastSpellLocalCast = GetTime() 345 | e.LastSpellDropOnLoseIsCurrentAction = true 346 | end 347 | end 348 | end 349 | end 350 | 351 | function Punsch_Castbar_HookCastSpell(spellID, spellTab) 352 | local e = PunschEntities["Castbar"] 353 | e.LastSpellDropOnLoseIsCurrentAction = nil 354 | e.LastSpellSetOnLoseIsTargeting = nil 355 | e.LastSpellLocalCast = nil 356 | e.LastSpellIcon = nil 357 | e.LastSpellRank = nil 358 | local name,rank = GetSpellName(spellID, spellTab) 359 | 360 | --remembers spellname to match with later casts 361 | if e.ShowRank or e.ShowIcon then 362 | e.recentlyCastSpells[strlower(name)] = {} 363 | e.recentlyCastSpells[strlower(name)].texture = GetSpellTexture(spellID, spellTab) 364 | e.recentlyCastSpells[strlower(name)].rank = rank 365 | end 366 | 367 | --detecting Aimed Shot 368 | if name == "Aimed Shot" then 369 | Punsch_Castbar_CastAimedShot() 370 | elseif name == "Multi-Shot" then 371 | Punsch_Castbar_CastMultiShot() 372 | end 373 | 374 | e.OriginalCastSpell(spellID, spellTab) 375 | end 376 | 377 | function Punsch_Castbar_HookCastSpellByName(spellName,target) 378 | local e = PunschEntities["Castbar"] 379 | 380 | --remembers spellname to match with later casts 381 | if e.ShowRank or e.ShowIcon then 382 | local _,_,sn,sr = strfind(strlower(spellName), "(.+)%((rank %d+)%)") 383 | if sn and sr then 384 | e.recentlyCastSpells[sn] = {} 385 | e.recentlyCastSpells[sn].rank = sr 386 | e.recentlyCastSpells[sn].texture = Punsch_Castbar_GetSpellRankIcon(sn,sr) 387 | else 388 | local spellInfo = Punsch_Castbar_GetSpellMaxRankInfo(spellName) 389 | if spellInfo then 390 | e.recentlyCastSpells[strlower(spellName)] = {} 391 | e.recentlyCastSpells[strlower(spellName)].texture = spellInfo.icon 392 | e.recentlyCastSpells[strlower(spellName)].rank = spellInfo.rank 393 | end 394 | end 395 | end 396 | 397 | --detecting Aimed Shot 398 | if spellName == "Aimed Shot" then 399 | Punsch_Castbar_CastAimedShot() 400 | elseif spellName == "Multi-Shot" then 401 | Punsch_Castbar_CastMultiShot() 402 | end 403 | 404 | e.OriginalCastSpellByName(spellName,target) 405 | end 406 | 407 | function Punsch_Castbar_CastAimedShot() 408 | local e = PunschEntities["Castbar"] 409 | if not e.isCasting and e.aimedshot then 410 | local AimedCastTime = 3000/e.HasteFromBerserking/e.HasteFromQuickShots/e.HasteFromKiss/e.HasteFromRapid/e.HasteFromAncientDespair 411 | Punsch_Castbar_OnCastStart("Aimed Shot",AimedCastTime) 412 | end 413 | end 414 | 415 | function Punsch_Castbar_CastMultiShot() 416 | local e = PunschEntities["Castbar"] 417 | if not e.isCasting and e.multishot then 418 | Punsch_Castbar_OnCastStart("Multi-Shot",500) 419 | end 420 | end 421 | 422 | function Punsch_Castbar_GetLastSpellInfo() 423 | local e = PunschEntities["Castbar"] 424 | if e.LastSpellLocalCast then 425 | local lag = GetTime() - e.LastSpellLocalCast 426 | local icon = e.LastSpellIcon 427 | local rank = e.LastSpellRank 428 | e.LastSpellLocalCast = nil 429 | e.LastSpellIcon = nil 430 | e.LastSpellRank = nil 431 | e.LastSpellDropOnLoseIsCurrentAction = nil 432 | e.LastSpellSetOnLoseIsTargeting = nil 433 | return lag, icon, rank 434 | end 435 | end 436 | 437 | function Punsch_Castbar_OnUpdate() 438 | local e = PunschEntities["Castbar"] 439 | if e.LastSpellDropOnLoseIsCurrentAction then 440 | if not IsCurrentAction(e.LastUseActionSlot) then 441 | e.LastSpellLocalCast = nil 442 | e.LastSpellIcon = nil 443 | e.LastSpellRank = nil 444 | e.LastSpellDropOnLoseIsCurrentAction = nil 445 | end 446 | elseif e.LastSpellSetOnLoseIsTargeting then 447 | if not SpellIsTargeting() then 448 | e.LastSpellLocalCast = GetTime() 449 | e.LastSpellSetOnLoseIsTargeting = nil 450 | e.LastSpellDropOnLoseIsCurrentAction = true -- drop next frame unless spell has been locally cast by then. 451 | end 452 | end 453 | 454 | if e.isFading == true then 455 | if e.holdTime > 0 then 456 | e.holdTime = e.holdTime-arg1 457 | if e.holdTime < 0 then 458 | e.fadeTimeleft = e.fadeTimeleft + e.holdTime 459 | end 460 | else 461 | e.fadeTimeleft = e.fadeTimeleft-arg1 462 | end 463 | if e.fadeTimeleft <=0 then 464 | Punsch_Bar_FadeStop(e) 465 | if not e.AlwaysShow then e.ContentFrame:Hide() end 466 | else 467 | e.ContentFrame:SetAlpha(1- (e.fadeTime - e.fadeTimeleft) / e.fadeTime) 468 | end 469 | end 470 | 471 | if not e.isCasting == true then return end 472 | local time = GetTime() 473 | if e.isChannel == true then 474 | if e.channelDelayToDuration then 475 | Punsch_Bar_SetPercent(e,0,((e.endTime - time)/e.duration)) 476 | else 477 | Punsch_Bar_SetPercent(e,-1*(e.delayedBy/e.duration),((e.endTime - time)/e.duration)) 478 | end 479 | --gradually hide ticks 480 | for i=1,e.TicksShown do 481 | if e.TickIndicators[i].texture:GetLeft() > e.selfFill:GetRight() then --ERROR HERE when channeling supposedly. 482 | e.TickIndicators[i].texture:Hide() 483 | elseif e.TickIndicators[i].texture:GetRight() > e.selfFill:GetRight() then 484 | local w = e.TickIndicators[i].texture:GetWidth() -(e.TickIndicators[i].texture:GetRight() - e.selfFill:GetRight()) 485 | e.TickIndicators[i].texture:SetWidth(w) 486 | e.TickIndicators[i].texture:SetTexCoord( 487 | e.TickIndicators[i].ltc, 488 | ((e.endTime - time)/e.duration), 489 | e.TickTop, 490 | e.TickBot) 491 | end 492 | end 493 | 494 | if e.delayedBy < 0 then 495 | e.text3:SetText(string.format("%." .. e.decimals .. "f",e.delayedBy)) 496 | end 497 | else 498 | Punsch_Bar_SetPercent(e,0,1-((e.endTime - time)/e.duration)) 499 | if e.delayedBy > 0 then 500 | e.text3:SetText("+" .. string.format("%." .. e.decimals .. "f",e.delayedBy)) 501 | end 502 | end 503 | 504 | local t = e.endTime - time 505 | if t < 0 then t = 0 end 506 | 507 | if (e.isChannel and e.CountUpOnChannel) or (not e.isChannel and e.CountUpOnCast) then 508 | e.text2:SetText(string.format("%." .. e.decimals .. "f",e.duration-t) .. e.DurationTextSpacing .. "/" .. e.DurationTextSpacing .. string.format("%." .. e.decimals .. "f",e.duration)) 509 | else 510 | e.text2:SetText(string.format("%." .. e.decimals .. "f",t) .. e.DurationTextSpacing .."/" .. e.DurationTextSpacing .. string.format("%." .. e.decimals .. "f",e.duration)) 511 | end 512 | end 513 | 514 | function Punsch_Castbar_OnChannelStart(name,duration) 515 | local e = PunschEntities["Castbar"] 516 | Punsch_Bar_FadeStop(e) 517 | e.isCasting = true 518 | e.isChannel = true 519 | e.spellName = name 520 | e.duration = duration/1000 521 | e.startTime = GetTime() 522 | e.delayedBy = 0 523 | e.endTime = e.startTime + e.duration 524 | e.selfFill:SetWidth(e.self:GetWidth()) 525 | e.selfFill:SetPoint("TOPLEFT",e.self) 526 | e.selfFill:SetVertexColor(PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Castbar"].FillChannel.r, 527 | PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Castbar"].FillChannel.g, 528 | PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Castbar"].FillChannel.b, 529 | PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Castbar"].FillChannel.a) 530 | e.selfFillShown = true 531 | e.selfFill:Show() 532 | if e.ShowSpark then e.spark:Show() end 533 | 534 | e.lag, e.icontexture, e.rank = Punsch_Castbar_GetLastSpellInfo() 535 | if e.lag and e.ShowLag then 536 | if e.lag < 0.001 then 537 | e.lagBG:Hide() 538 | else 539 | e.lagBG:ClearAllPoints() 540 | e.lagBG:SetPoint("BOTTOM",e.ContentFrame) 541 | e.lagBG:SetPoint("TOPLEFT",e.ContentFrame) 542 | local lagpct = e.lag/e.duration 543 | if lagpct > 1 then lagpct = 1 end 544 | 545 | e.lagBG:SetWidth(lagpct * e.self:GetWidth()) 546 | e.lagBG:SetTexCoord(0,e.lag/e.duration,0,1) 547 | e.lagBG:Show() 548 | end 549 | 550 | e.lagtxt:SetText(string.format("%.0f",e.lag*1000) .. "ms") 551 | e.lagtxt:ClearAllPoints() 552 | e.lagtxt:SetPoint("BOTTOMLEFT",e.lagBG,"BOTTOMLEFT") 553 | e.lagtxt:Show() 554 | else 555 | e.lagBG:Hide() 556 | e.lagtxt:Hide() 557 | end 558 | 559 | --setting icon, getting name from icon 560 | if e.icontexture then 561 | if e.ShowIcon then e.icon:SetTexture(e.icontexture) end 562 | if e.spellName == "Channeling" then 563 | --try to find a class specific channel 564 | local _,class = UnitClass("player") 565 | if Punsch_Tables_KnownChannels.ByIcon[class] then 566 | local getname = Punsch_Tables_KnownChannels.ByIcon[class][e.icontexture] 567 | if getname then e.spellName = getname end 568 | end 569 | --if its stil channeling, check shared list 570 | if e.spellName == "Channeling" then 571 | local getname = Punsch_Tables_KnownChannels.ByIcon["SHARED"][e.icontexture] 572 | if getname then e.spellName = getname end 573 | end 574 | end 575 | elseif e.spellName and Punsch_Tables_KnownChannels.ByName[e.spellName] and Punsch_Tables_KnownChannels.ByName[e.spellName]["Icon"] then 576 | if e.ShowIcon then e.icon:SetTexture(Punsch_Tables_KnownChannels.ByName[e.spellName]["Icon"]) end 577 | else 578 | if e.ShowIcon then e.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark") end 579 | end 580 | 581 | for i=1,e.TicksShown do 582 | e.TickIndicators[i].texture:Hide() 583 | end 584 | e.TicksShown = 0 585 | 586 | if e.spellName ~= "Channeling" and e.TickEnable then 587 | local tickinfo = Punsch_Tables_KnownChannels.ByName[e.spellName] 588 | if tickinfo then 589 | if tickinfo.Tick == "time" then 590 | if e.spellName == "Arcane Missiles" and duration == 3000 then 591 | tickinfo.TickCount = 3 592 | elseif e.spellName == "Arcane Missiles" and duration == 4000 then 593 | tickinfo.TickCount = 4 594 | end 595 | e.TicksShown = tickinfo.TickCount 596 | for i=1,tickinfo.TickCount do 597 | if i == tickinfo.TickCount then 598 | e.TickIndicators[i].texture:SetPoint("LEFT",e.self) 599 | e.TickIndicators[i].texture:SetWidth(e.TickWidth/2) 600 | else 601 | e.TickIndicators[i].texture:SetPoint("LEFT",e.self,"RIGHT",(-i*(e.self:GetWidth()/(tickinfo.TickCount)))-(e.TickWidth/2),0) 602 | e.TickIndicators[i].texture:SetWidth(e.TickWidth) 603 | end 604 | e.TickIndicators[i].ltc = ((tickinfo.TickCount-i)/tickinfo.TickCount)-(e.TickWidth/2)/e.self:GetWidth() 605 | e.TickIndicators[i].texture:SetTexCoord( 606 | e.TickIndicators[i].ltc, 607 | ((tickinfo.TickCount-i)/tickinfo.TickCount)+(e.TickWidth/2)/e.self:GetWidth(), 608 | e.TickTop, 609 | e.TickBot) 610 | e.TickIndicators[i].texture:Show() 611 | end 612 | elseif tickinfo.Tick == "mana" then 613 | 614 | end 615 | end 616 | end 617 | 618 | --spellname text formatting and ranks 619 | local spellNameText = e.spellName 620 | if e.rank and e.ShowRank then 621 | local _,_,r = strfind(strlower(e.rank),"rank (%S+)") 622 | if r then 623 | if e.RankAsRoman then r = RomanNumerals[tonumber(r)] end 624 | if not e.RankAsShort then 625 | spellNameText = spellNameText .. " Rank " .. r 626 | else 627 | spellNameText = spellNameText .. " " .. r 628 | end 629 | end 630 | end 631 | if e.UCSN then spellNameText = strupper(spellNameText) end 632 | e.text1:SetText(spellNameText) 633 | 634 | e.icontexture = nil 635 | e.text2:SetText(0.0 .."/" .. e.duration, 1) 636 | e.text3:SetText("") 637 | e.ContentFrame:Show() 638 | end 639 | 640 | function Punsch_Castbar_OnChannelStop() 641 | local e = PunschEntities["Castbar"] 642 | if e.isCasting == true and e.isChannel == true then 643 | e.isCasting = false 644 | if not e.AlwaysShow then e.ContentFrame:Hide() end 645 | end 646 | end 647 | 648 | function Punsch_Castbar_OnChannelUpdate(duration) 649 | local e = PunschEntities["Castbar"] 650 | local newEndTime = GetTime() + duration/1000 651 | if e.channelDelayToDuration then 652 | if e.TickEnable then 653 | for i=1,e.TicksShown do 654 | --move the ticks: 655 | e.TickIndicators[i].texture:SetPoint("LEFT",UIParent,"LEFT",e.TickIndicators[i].texture:GetLeft()-(e.self:GetWidth()*((e.endTime- newEndTime)/e.duration )),0) 656 | --hide ticks outside of the castbar 657 | if e.TickIndicators[i].texture:GetRight()= e.duration then 771 | e.lagBG:SetWidth(e.self:GetWidth()) 772 | e.lagBG:SetTexCoord(0,1,0,1) 773 | else 774 | e.lagBG:SetWidth(e.lag/e.duration*e.self:GetWidth()) 775 | e.lagBG:SetTexCoord(1-e.lag/e.duration,1,0,1) 776 | end 777 | if e.lag <= 0.01 then 778 | e.lagBG:Hide() 779 | else 780 | e.lagBG:Show() 781 | end 782 | 783 | e.lagtxt:SetText(string.format("%.0f",e.lag*1000) .. "ms") 784 | e.lagtxt:ClearAllPoints() 785 | e.lagtxt:SetPoint("BOTTOMRIGHT",e.lagBG,"BOTTOMRIGHT") 786 | e.lagtxt:Show() 787 | else 788 | e.lagBG:Hide() 789 | e.lagtxt:Hide() 790 | end 791 | 792 | for i=1,e.TicksShown do 793 | e.TickIndicators[i].texture:Hide() 794 | end 795 | e.TicksShown = 0 796 | 797 | if e.icontexture then 798 | if e.ShowIcon then e.icon:SetTexture(e.icontexture) end 799 | e.icontexture = nil 800 | else 801 | if e.ShowIcon then 802 | --do table lookup HERE of known world objects. 803 | e.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark") 804 | end 805 | end 806 | 807 | e.ContentFrame:Show() 808 | end 809 | 810 | function Punsch_Castbar_OnCastStop() 811 | local e = PunschEntities["Castbar"] 812 | if e.isCasting == true and not e.isChannel == true then 813 | Punsch_Castbar_StartFade(true) 814 | e.isCasting = false 815 | end 816 | end 817 | 818 | function Punsch_Castbar_StartFade(successful) 819 | local e = PunschEntities["Castbar"] 820 | 821 | if not e.fadeEnable then 822 | if not e.AlwaysShow then e.ContentFrame:Hide() end 823 | return 824 | end 825 | local db = PunschrulleDB.Profiles[PunschrulleProfile]["Entities"]["Castbar"].Fade 826 | if successful == true and e.endTime - GetTime() < tonumber(e.fadeTolerance) then 827 | e.selfFill:SetVertexColor(db.Success.r, 828 | db.Success.g, 829 | db.Success.b, 830 | db.Success.a) 831 | if not e.isFading then 832 | e.holdTime = e.fadesht 833 | end 834 | else 835 | e.selfFill:SetVertexColor(db.Failure.r, 836 | db.Failure.g, 837 | db.Failure.b, 838 | db.Failure.a) 839 | if not e.isFading then 840 | e.holdTime = e.fadefht 841 | else 842 | e.holdTime = e.fadefht - (e.fadesht - e.holdTime) 843 | end 844 | end 845 | 846 | if not e.isFading then 847 | e.isFading = true 848 | if e.fadeTime == 0 then 849 | e.fadeTimeLeft = 0.01 850 | else 851 | e.fadeTimeleft = e.fadeTime 852 | end 853 | Punsch_Bar_SetPercent(e,0,1) 854 | if e.ShowSpark then e.spark:Hide() end 855 | if not e.fadeshowlag then e.lagBG:Hide() end 856 | end 857 | end 858 | 859 | function Punsch_Castbar_GetSpellMaxRankInfo(spellName) 860 | local e = PunschEntities["Castbar"] 861 | spellName = strlower(spellName) 862 | if not e.spellDB[spellName] then 863 | local i = 1 864 | while true do 865 | local name, rank = GetSpellName(i, "spell") 866 | if not name then break end 867 | if strlower(name) == spellName and strlower(GetSpellName(i+1, "spell") or "")~=spellName then 868 | e.spellDB[spellName] = {} 869 | e.spellDB[spellName].rank = rank 870 | e.spellDB[spellName].icon = GetSpellTexture(i, "spell") 871 | break 872 | end 873 | i = i + 1 874 | end 875 | end 876 | return e.spellDB[spellName] 877 | end 878 | 879 | function Punsch_Castbar_GetSpellRankIcon(spellName, spellRank) 880 | local e = PunschEntities["Castbar"] 881 | spellName = strlower(spellName) 882 | spellRank = strlower(spellRank) 883 | if not e.spellRankIcons[spellName..spellRank] then 884 | local i = 1 885 | while true do 886 | local name, rank = GetSpellName(i, "spell") 887 | if not name then break end 888 | if strlower(name) == spellName and strlower(rank)==spellRank then 889 | e.spellRankIcons[spellName..spellRank] = GetSpellTexture(i, "spell") 890 | break 891 | end 892 | i = i + 1 893 | end 894 | end 895 | return e.spellRankIcons[spellName..spellRank] 896 | end 897 | 898 | --[[ 899 | _, tmp = UnitStat("player", 4) 900 | TheoryCraft_Data.Stats["intellect"] = tmp 901 | _, tmp = UnitStat("player", 5) 902 | TheoryCraft_Data.Stats["spirit"] = tmp 903 | 904 | 905 | if class == "MAGE" then 906 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/8+6.25 907 | 908 | 909 | local manaregen = TheoryCraft_GetStat("manaperfive")/5 910 | manaregen = manaregen+TheoryCraft_Data.Stats["totalmana"]*TheoryCraft_GetStat("FelEnergy")/4 911 | TheoryCraft_Data.Stats["regen"] = manaregen+TheoryCraft_Data.Stats["regenfromspirit"] 912 | TheoryCraft_Data.Stats["icregen"] = manaregen+(TheoryCraft_Data.Stats["regenfromspirit"])*TheoryCraft_GetStat("ICPercent") 913 | if (class == "MAGE") then 914 | TheoryCraft_Data.Stats["maxtotalmana"] = TheoryCraft_Data.Stats["totalmana"]+TheoryCraft_Data.Stats["regenfromspirit"]*15*8+1100+manaregen*8 915 | end 916 | if (class == "WARLOCK") then 917 | getlifetap(TheoryCraft_Data.Stats) 918 | end 919 | 920 | --]] 921 | 922 | --------------------------------------------------------------------------------