--[[ **************************************************************** Scrolling Combat Text - Damage 2.0 Author: Grayhoof **************************************************************** Official Site: http://grayhoof.wowinterface.com ****************************************************************]] --embedded libs local parser = ParserLib:GetInstance("1.1") --global name SCTD = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceConsole-2.0", "AceHook-2.0"); --Add new frame to SCT SCT.FRAME3 = 3; local arrAniData3 = {}; tinsert(SCT.ArrayAniData, arrAniData3); local MSG_Y_OFFSET = 0; local arrMsgData = { ["MSGTEXT1"] = {size=1, xoffset=0, yoffset=0, align="CENTER", height=5, duration=1}, } local default_config = { ["SCTD_VERSION"] = SCTD.Version, ["SCTD_ENABLED"] = 1, ["SCTD_SHOWMELEE"] = 1, ["SCTD_SHOWPERIODIC"] = 1, ["SCTD_SHOWSPELL"] = 1, ["SCTD_SHOWPET"] = 1, ["SCTD_SHOWCOLORCRIT"] = false, ["SCTD_FLAGDMG"] = false, ["SCTD_SHOWDMGTYPE"] = false, ["SCTD_SHOWSPELLNAME"] = 1, ["SCTD_SHOWRESIST"] = 1, ["SCTD_SHOWTARGETS"] = false, ["SCTD_DMGFONT"] = 1, ["SCTD_TARGET"] = false, ["SCTD_PVPDMG"] = false, ["SCTD_USESCT"] = 1, ["SCTD_STICKYCRIT"] = 1, ["SCTD_SPELLCOLOR"] = false }; local default_config_colors = { ["SCTD_SHOWMELEE"] = {r = 1.0, g = 1.0, b = 1.0}, ["SCTD_SHOWPERIODIC"] = {r = 1.0, g =1.0, b = 0.0}, ["SCTD_SHOWSPELL"] = {r = 1.0, g = 1.0, b = 0.0}, ["SCTD_SHOWPET"] = {r = 0.6, g = 0.6, b = 0.0}, ["SCTD_SHOWCOLORCRIT"] = {r = 0.2, g = 0.4, b = 0.6} } local default_frame_config = { ["FONT"] = 1, ["FONTSHADOW"] = 2, ["ALPHA"] = 100, ["ANITYPE"] = 1, ["ANISIDETYPE"] = 1, ["XOFFSET"] = 0, ["YOFFSET"] = 210, ["DIRECTION"] = false, ["TEXTSIZE"] = 24, ["FADE"] = 1.5 } local arrShadowOutline = { [1] = "", [2] = "OUTLINE", [3] = "THICKOUTLINE" } ---------------------- --Called on login function SCTD:OnEnable() --check SCT version if (not SCT) or (tonumber(SCT.db.profile["VERSION"]) < 5) then StaticPopupDialogs["SCTD_VERSION"] = { text = SCTD.LOCALS.Version_Warning, button1 = TEXT(OKAY) , timeout = 0, whileDead = 1, hideOnEscape = 1, showAlert = 1 }; StaticPopup_Show("SCTD_VERSION"); if (SCTOptionsFrame_Misc103) then SCTOptionsFrame_Misc103:Hide(); end self:OnDisable(); return; end self:RegisterSelfEvents(); end ---------------------- -- Disable all events, not using AceDB, but may as well name it right. function SCTD:OnDisable() -- no more events to handle parser:UnregisterAllEvents("sctd") self:UnregisterAllEvents() end ---------------------- --Called when addon loaded function SCTD:OnInitialize() --slash commands local main = { type="group", args = { menu = { name = "Menu", type = 'execute', desc = "Display SCT Option Menu", func = function() self:ShowSCTDMenu(); end }, } } local menu = { type = 'execute', desc = "Display SCTD Option Menu", func = function() self:ShowSCTDMenu(); end } self:RegisterChatCommand({"/sctd"}, main); self:RegisterChatCommand({"/sctdmenu"}, menu); --register with other mods self:RegisterOtherMods(); --Hook SCT show menu self:Hook(SCT, "ShowMenu") --update old values self:UpdateValues(); --setup msgs self:MsgInit(); end ---------------------- -- Show the Option Menu function SCTD:ShowSCTDMenu() local loaded, message = LoadAddOn("sct_options"); if (loaded) then --if options page exsists (not disabled) if (SCTDOptions) then PlaySound("igMainMenuOpen"); --Hook SCT ShowExample if (not SCTD:IsHooked(SCT, "ShowExample")) then SCTD:Hook(SCT, "ShowExample"); end --show options SCTDOptions:Show(); --update animation options SCTD:UpdateAnimationOptions() else PlaySound("TellMessage"); SCTD:Print(SCTD.LOCALS.Load_Error); end else PlaySound("TellMessage"); SCTD:Print(SCT.LOCALS.Load_Error.." "..message); end; end ---------------------- --Reset everything to default for SCTD function SCTD:ShowMenu() SCTD:UpdateValues(); --open sct menu self.hooks[SCT].ShowMenu.orig(); --Hook SCT ShowExample if (not self:IsHooked(SCT, "ShowExample") and SCT.ShowExample) then self:Hook(SCT, "ShowExample"); end --if window is showing, reload it if (SCTDOptions) and (SCTDOptions:IsVisible()) then SCTDOptions:Hide(); SCTDOptions:Show(); end end ---------------------- -- display ddl or chxbox based on type function SCTD:UpdateAnimationOptions() --get scroll down checkbox local chkbox = getglobal("SCTOptionsFrame_CheckButton113"); --get anime type dropdown local ddl1 = getglobal("SCTOptionsFrame_Selection103"); --get animside type dropdown local ddl2 = getglobal("SCTOptionsFrame_Selection104"); --get item local id = UIDropDownMenu_GetSelectedID(ddl1) if (id == 1 or id == 6) then chkbox:Show(); ddl2:Hide(); else chkbox:Hide(); ddl2:Show(); end end ---------------------- --Hide the Option Menu function SCTD:HideMenu() PlaySound("igMainMenuClose"); SCTDOptions:Hide(); SCTD_EXAMPLEMSG:Hide(); end --------------------- --Show SCT Example function SCTD:ShowExample() self.hooks[SCT].ShowExample.orig(); self:MsgInit() self:SetDamageFlags(); --animated example for options that may need it local option = this.SCTVar or "SCTD_SHOWMELEE"; if (string.find(option,"SCTD_SHOW")) then self:DisplayText(option, self.LOCALS.EXAMPLE); end --show msg frame SCTD_EXAMPLEMSG:Show(); --show example FRAME3 --get object example = getglobal("SCTDMsgExample1"); --set text size SCT:SetFontSize(example, SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["FONT"], SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["TEXTSIZE"], SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["FONTSHADOW"]); --set the color example:SetTextColor(1, 1, 1); --set alpha example:SetAlpha(SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["ALPHA"]/100); --Position example:SetPoint("CENTER", "UIParent", "CENTER", SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["XOFFSET"], SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["YOFFSET"]); --Set the text to display example:SetText(self.LOCALS.EXAMPLE); --update animation options self:UpdateAnimationOptions() end ---------------------- --Update old values for new versions function SCTD:UpdateValues() local i, var; --set defaults for i in default_config do if(SCT.db.profile[i] == nil) then SCT.db.profile[i] = default_config[i]; end end --set colors for i in default_config_colors do var = SCT.db.profile[SCT.COLORS_TABLE][i] or default_config_colors[i]; SCT.db.profile[SCT.COLORS_TABLE][i] = var; end --set frame data if (not SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]) then SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3] = {}; end for i in default_frame_config do if (SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3][i] == nil) then SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3][i] = default_frame_config[i]; end end end ---------------------- -- Event Handler function SCTD:OnEvent() --Player PvP status changed SCTD:SetDamageFlags(); end ---------------------- --Determine if its a "melee" ranged evet function SCTD:IsMeleeRanged(skill) if (skill == ParserLib_MELEE or skill == self.LOCALS.AUTO_SHOT or --skill == self.LOCALS.SHOOT or skill == self.LOCALS.SHOOT_BOW or skill == self.LOCALS.SHOOT_CROSSBOW or skill == self.LOCALS.SHOOT_GUN) then return true; else return false; end end ---------------------- -- Parses all combat events using paserlib function SCTD:ParseCombat(info) --self doesn't work here because of the call from ParserLib local self = SCTD; --exit if not enabled if (not SCT.db.profile["SCTD_ENABLED"]) then return; end --Hits (melee, spell, etc..) if (info.type == "hit") then if (info.source == ParserLib_SELF) then if (self:IsMeleeRanged(info.skill)) then self:DisplayText("SCTD_SHOWMELEE", info.amount, info.isCrit, nil, nil, info.victim); else if (info.isDOT) then self:DisplayText("SCTD_SHOWPERIODIC", info.amount, nil, info.element, info.amountResist, info.victim, info.skill); else self:DisplayText("SCTD_SHOWSPELL", info.amount, info.isCrit, info.element, info.amountResist, info.victim, info.skill); end end elseif (SCT:GetTargetUnit(info.source) == "pet") then if (info.skill == ParserLib_MELEE) then self:DisplayText("SCTD_SHOWPET", info.amount, info.isCrit, info.element, info.amountResist, info.victim, PET); else self:DisplayText("SCTD_SHOWPET", info.amount, info.isCrit, info.element, info.amountResist, info.victim, info.skill); end end --Miss Events elseif (info.type == "miss") then local source; --if its self, player, else see if its pet if (info.source == ParserLib_SELF) then source = "player"; else source = SCT:GetTargetUnit(info.source); end; --remove skill if melee or ranged non-skill if (self:IsMeleeRanged(info.skill)) then info.skill = nil; end --if pet or player if (source == "player") or (source == "pet")then local type = "SCTD_SHOWMELEE"; if (info.skill) then type="SCTD_SHOWSPELL"; end if (source == "pet") then type="SCTD_SHOWPET"; end if (info.missType == "miss") then self:DisplayText(type, MISS, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "dodge") then self:DisplayText(type, DODGE, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "block") then self:DisplayText(type, BLOCK, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "deflect") then self:DisplayText(type, DEFLECT, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "immune") then self:DisplayText(type, IMMUNE, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "evade") then self:DisplayText(type, EVADE, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "parry") then self:DisplayText(type, PARRY, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "resist") then self:DisplayText(type, RESIST, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "reflect") then self:DisplayText(type, REFLECT, nil, nil, nil, info.victim, info.skill); elseif (info.missType == "absorb") then self:DisplayText(type, ABSORB, nil, nil, nil, info.victim, info.skill); end end end end ---------------------- --Display for mainly combat events --Mainly used for short messages function SCTD:DisplayText(option, msg1, crit, damagetype, resisted, target, spell) local rbgcolor, showcrit, showmsg, adat; --if option is on if (SCT.db.profile[option]) then --if show only target if (SCT.db.profile["SCTD_TARGET"]) then if (target ~= UnitName("target")) then return; end end --get options rbgcolor = SCT.db.profile[SCT.COLORS_TABLE][option]; --if damage type if ((damagetype) and (SCT.db.profile["SCTD_SHOWDMGTYPE"])) then msg1 = msg1.." "..damagetype..""; end --if spell color if ((damagetype) and (SCT.db.profile["SCTD_SPELLCOLOR"])) then rbgcolor = SCT.SpellColors[damagetype] or rbgcolor; end --if resisted if ((resisted) and (SCT.db.profile["SCTD_SHOWRESIST"])) then msg1 = msg1.." {"..resisted.."}"; end --if target label if ((target) and (SCT.db.profile["SCTD_SHOWTARGETS"])) then msg1 = target..": "..msg1; end --if spell if ((spell) and (SCT.db.profile["SCTD_SHOWSPELLNAME"])) then msg1 = msg1.." ("..spell..")"; end --if flag if (SCT.db.profile["SCTD_FLAGDMG"]) then msg1 = self.LOCALS.SelfFlag..msg1..self.LOCALS.SelfFlag; end --if crit if (crit) then if (SCT.db.profile["SCTD_SHOWCOLORCRIT"]) then rbgcolor = SCT.db.profile[SCT.COLORS_TABLE]["SCTD_SHOWCOLORCRIT"]; end self:Display_Crit_Damage( msg1, rbgcolor ); else self:Display_Damage( msg1, rbgcolor ); end end end ---------------------- --Displays a message at the top of the screen function SCTD:Display_Damage(msg, color) if (SCT.db.profile["SCTD_USESCT"]) then SCT:DisplayText(msg, color, nil, "damage", SCT.FRAME3); else SCTD_MSGTEXT1:SetPoint("CENTER", "UIParent", "CENTER", SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["XOFFSET"], SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["YOFFSET"] + MSG_Y_OFFSET); SCTD_MSGTEXT1:SetTimeVisible(SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["FADE"]); SCTD_MSGTEXT1:AddMessage(msg, color.r, color.g, color.b, 1); end end ---------------------- --Displays a message at the top of the screen function SCTD:Display_Crit_Damage(msg, color) if (SCT.db.profile["SCTD_STICKYCRIT"]) then SCT:DisplayText(msg, color, 1, "damage", SCT.FRAME3); elseif (SCT.db.profile["SCTD_USESCT"]) then SCT:DisplayText("+"..msg.."+", color, nil, "damage", SCT.FRAME3); else SCTD_MSGTEXT1:SetPoint("CENTER", "UIParent", "CENTER", SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["XOFFSET"], SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["YOFFSET"] + MSG_Y_OFFSET); SCTD_MSGTEXT1:SetTimeVisible(SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["FADE"] or 1.5); SCTD_MSGTEXT1:AddMessage("+"..msg.."+", color.r, color.g, color.b, 1); end end ------------------------ --Setup msg arrays function SCTD:MsgInit() for key, value in arrMsgData do value.FObject = getglobal("SCTD_"..key); self:SetMsgFont(value.FObject); end self:SetDamageFlags() end ------------------------ --Setup Damage Flags based on Options function SCTD:SetDamageFlags() --set WoW Damage Flags if (SCT.db.profile["SCTD_DMGFONT"]) then SetCVar("CombatDamage", 0); self:SetPvPDamageFlags(); else SetCVar("CombatDamage", 1); end end ------------------------ --Setup Damage Flags based on Options and PvP status function SCTD:SetPvPDamageFlags() --set WoW Damage Flags if (SCT.db.profile["SCTD_PVPDMG"]) then if (UnitIsPVP("player")) then SetCVar("CombatDamage", 1); SCT.db.profile["SCTD_ENABLED"] = false; else SetCVar("CombatDamage", 0); SCT.db.profile["SCTD_ENABLED"] = 1; end end end ------------------------- --Set the font of an object using msg vars function SCTD:SetMsgFont(object) --set font object:SetFont(SCT.LOCALS.FONTS[SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["FONT"]].path, SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["TEXTSIZE"], arrShadowOutline[SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["FONTSHADOW"]]); --reset size of allow 5 messages object:SetHeight(SCT.db.profile[SCT.FRAMES_DATA_TABLE][SCT.FRAME3]["TEXTSIZE"] * 6) --Set Fade Duration object:SetFadeDuration(1); --set offset to center MSG_Y_OFFSET = object:GetHeight()/2; end ---------------------- --Register All Events function SCTD:RegisterSelfEvents() --core events self:RegisterEvent("UNIT_FACTION", "OnEvent"); self:RegisterEvent("PLAYER_ENTERING_WORLD", "OnEvent"); --core chat events for Parserlib parser:RegisterEvent("sctd", "CHAT_MSG_COMBAT_SELF_HITS", SCTD.ParseCombat) ; parser:RegisterEvent("sctd", "CHAT_MSG_COMBAT_SELF_MISSES", SCTD.ParseCombat) ; parser:RegisterEvent("sctd", "CHAT_MSG_SPELL_SELF_DAMAGE", SCTD.ParseCombat) ; parser:RegisterEvent("sctd", "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE", SCTD.ParseCombat) ; parser:RegisterEvent("sctd", "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE", SCTD.ParseCombat) ; parser:RegisterEvent("sctd", "CHAT_MSG_COMBAT_PET_HITS", SCTD.ParseCombat) ; parser:RegisterEvent("sctd", "CHAT_MSG_COMBAT_PET_MISSES", SCTD.ParseCombat) ; parser:RegisterEvent("sctd", "CHAT_MSG_SPELL_PET_DAMAGE", SCTD.ParseCombat) ; end ------------------------- --Regsiter SCTD with other mods function SCTD:RegisterOtherMods() -- myAddOns support if(myAddOnsFrame_Register) then local SCTDDetails = { name = "sctd", version = SCTD.Version, optionsframe = "SCTDOptions", category = MYADDONS_CATEGORY_COMBAT }; myAddOnsFrame_Register(SCTDDetails); end --Cosmos support if ( EarthFeature_AddButton ) then EarthFeature_AddButton( { id="SCT"; name=self.LOCALS.CB_NAME; text=self.LOCALS.CB_NAME; subtext=self.LOCALS.CB_SHORT_DESC; helptext=self.LOCALS.CB_LONG_DESC; icon=self.LOCALS.CB_ICON; callback=SCTD.ShowSCTDMenu; } ); elseif (Cosmos_RegisterButton) then Cosmos_RegisterButton ( self.LOCALS.CB_NAME, self.LOCALS.CB_SHORT_DESC, self.LOCALS.CB_LONG_DESC, self.LOCALS.CB_ICON, SCTD.ShowSCTDMenu, function() return true; end ); default_config.ENABLED = 0; end -- Add to CTMod Control panel if available if ( CT_RegisterMod ) then CT_RegisterMod(self.LOCALS.CB_NAME, nil, 5, self.LOCALS.CB_ICON, self.LOCALS.CB_LONG_DESC, "switch", nil, SCTD.ShowSCTDMenu); end end