How to write an add-on that uses ABC

Getting started

This guide assumes you're already familiar with writing add-ons. It also assumes you understand the WoW combat log and know how to work with the COMBAT_LOG_EVENT_UNFILTERED event. Once you're a relatively seasoned author, writing boss mods with ABC is simple. We'll start with the TOC file.

Create a TOC file

Start with a TOC file that looks similar to this:

## Author: Allara
## Interface: 40200
## Notes: Puts a timer in /yell when you...
## Title: Plagued
## Version: 2.0
## Dependencies: AllaraBossCore
## LoadOnDemand: 1
## X-Category: Boss Encounters
## X-AllaraBossCore-LoadZone: Icecrown Citadel
## X-AllaraBossCore-MinimumRevision: 1

Core.lua

X-AllaraBossCore-LoadZone should be set to the English zone name in which you'd like your add-on to load. ABC will automatically localize the name for you across all languages if it's supported (in an effort to slim down ABC, only raid instances from WotLK and on are supported; open a ticket to add zones to the list).

X-AllaraBossCore-MinimumRevision is the minimum revision of ABC your add-on requires. If users aren't running at least this version of ABC, they will get an error message and your add-on will not load. Early revisions of ABC may have various bugs, so it's best to set this value to the revision of ABC you tested your add-on with.

Register your encounter definition

Encounter definitions are registered as a unique key and a table. The easiest way to understand the format is by looking at an example. Below is part of the encounter definition that could be used by Plagued, with extra comments to help you understand it. (Note that Plagued actually doesn't use ABC in order to make it super lightweight, but I did develop a version of Plagued that uses ABC as a proof of concept.)

if not AllaraBossCore then error("Plagued requires AllaraBossCore") return end
local ABC = AllaraBossCore

ABC:RegisterEncounter(
-- This is the key for the encounter.
-- Must be unique across all addons using Allara Boss Core.
"Plagued",
{

 -- A name for the encounter, used for unit tests and debug mode
 name = "Plagued (Professor Putricide)",

 -- The English zone name this encounter belongs to
 zone = "Icecrown Citadel",

 -- (Optional) Set this to false to disable the encounter from starting
 enabled = true,
 
 pull = {
  -- When your raid engages an NPC
  type = "combat",
  -- The NPC ID(s) that cause this encounter to activate
  npcs = { 36678, 37562, 37697 },

  --[[
    Also supported:
    
      type = "yell", -- When a boss yells to the zone
      yells = {
       "Some yell",
       "Some other yell",
      },
  ]]
 },
 
 defeat = {
  -- When your raid kills an NPC
  type = "death",
  -- The NPC ID(s) that cause this encounter to end when dead
  -- (you can also specify a list of IDs for council-style fights)
  npcs = { 36678 },

  --[[
    Also supported:
    
      type = "yell",
      yells = {
       "Some yell", -- When a boss yells to the zone
       "Some other yell",
      },
  ]]
 },

 -- (Optional) The time the entire raid must be dead
 -- or not in combat before a wipe is called
 -- (defaults to 5 seconds)
 wipeTime = 5,
 
 -- Fired when the encounter is activated
 onStart = function(self)
  cancelTimer()
 end,
 
 -- Fired when the encounter is ended, either through wiping or defeating it
 onEnd = function(self)
  cancelTimer()
 end,
 
 -- A list of combat log events you'd like to handle
 combatEvents = {
  SPELL_AURA_APPLIED = true,
  SPELL_AURA_REMOVED = true,
  -- Just specify ALL if you want to process every event:
  --ALL = true,
 },
 
 -- Fired for any combat log events you specified in combatEvents.
 -- All event arguments are passed to this function.
 onCombat = function(self, event, timestamp, eventType, hideCaster, srcGuid, srcName, srcFlags, srcRaidFlags, dstGuid, dstName, dstFlags, dstRaidFlags, spellId, spellName, spellSchool)
  if eventType == "SPELL_AURA_APPLIED" then
   if dstName == UnitName("player") then
    if spellId == 72856 then
     -- Do some stuff
    end
   end
   
  elseif eventType == "SPELL_AURA_REMOVED" then
   if dstName == UnitName("player") then
    if spellId == 72856 then
     -- Do some stuff
    end
   end
   
  end
 end,
 
--[[
 
Other events you can use:
   
 onWipe(self)                 -- Fired when the raid wipes
 onDefeat(self)               -- Fired when the raid defeats the current encounter
 onYell(self, event, ...)     -- Fired for all encounter yell and emote events
 onPower(self)                -- Fired any time the player's power or alternate power level changes
 onDisconnect(self, player)   -- Fired when a player disconnects during the encounter
 onHeartbeat(self)            -- Fired every 1.0 seconds while an encounter is running
 onSync(self, data)           -- Fired whenever your encounter sends a sync message to itself
   
]]
 
})

Encounter definitions as table storage

Encounter definitions are not add-ons in a true sense. Every encounter event takes itself as the first parameter. This lets you use your encounter definition table as a handy way to store data. However, there are a few reserved field names that you shouldn't use directly in your table, because they are used internally by ABC. Feel free to read these fields if you need to, just don't set them.

  • inCombat (set to true when your encounter is active)
  • startDelay (the time in seconds your encounter was delayed from starting after a pull detection)
  • dead (a table with the NPCs that have been killed during the fight)
  • possibleWipe (set to true when the wipe detection logic thinks you probably wiped)
  • _key (set to your encounter's unique key)

Things you can do inside an encounter definition

Get information about players in the raid

ABC provides a constantly up-to-date table containing all information about the raid you're in. You can access the table via AllaraBossCore.raid. Here's the table format (see the GetRaidRosterInfo API for more information on what these values mean):

AllaraBossCore.raid[playerName] = {
 rank,
 subgroup,
 level,
 class,
 zone,
 online,
 isDead,
 role,
 isML,
 valid,
 index
}

Create timers

Use the AllaraBossCore object to create and manage timers. Make sure to hang onto the handle of any timer you create if you need to cancel it later. All timers you create on the AllaraBossCore object will be automatically cancelled when your encounter ends. Example of a simple one-shot timer:

AllaraBossCore:ScheduleTimer(function() print("Doing something") end, 1.0)

See the AceTimer-3.0 API reference for more details. Note: ABC uses LibShefkiTimer-1.0, not AceTimer-3.0. However, the APIs are 100% compatible.

API reference

For all the rest of what you can do, see the API reference.


Comments

Posts Quoted:
Reply
Clear All Quotes