Documentation › Lua

Game events

An event calls one of your functions when something happens: someone speaks in chat, an effect shows on the screen, you press a key, the CaveBot reaches a label. This way the script reacts right away, without checking in a loop.

How to register#

Game.registerEvent(event, function) binds the function to the event and returns the function itself. Game.unregisterEvent(event, function) unbinds it. Keep the function in a variable if you want to unbind it later. A script can have several functions on the same event: all of them are called, in the order they were registered.

lua
-- Registers, uses and unbinds an event
local function onTalk(name, level, mode, x, y, z, text)
  print(name .. ": " .. text)
end

Game.registerEvent(Game.Events.TALK, onTalk)

-- 60 s later, stops listening to the chat
Timer.new("stop", function()
  Game.unregisterEvent(Game.Events.TALK, onTalk)
  destroyTimer("stop")
end, 60000)

How events arrive#

  • Each script runs on its own thread. Events go into a queue and run on that thread, one at a time, so two events of the same script never run at the same time.
  • The bot only sends an event to a script that has a function registered on it. HUD and window click events go only to the script that created the HUD or the window.
  • An error inside the function shows in the Console as event <number>: <error> and the script keeps running.
  • wait(ms) does not block events: while the script waits, the queued events and timers keep running.

Summary#

EventNumberWhen it fires
TALK0Someone speaks (Default, channels, PM, NPC)
MAGIC_EFFECT1A magic effect shows on a tile
HUD_CLICK2You click a HUD of the script
HOTKEY_SHORTCUT_PRESS3You press a key with the client in focus
TEXT_MESSAGE4The server sends a text message (loot, damage, warnings...)
MODAL_WINDOW5The server opens a window with buttons
CUSTOM_MODAL_WINDOW_BUTTON_CLICK6You click a button in a window of the script
QUEST_LOG9The quest list arrives
QUEST_LINES10The missions of a quest arrive
DISTANCE_SHOOT_EFFECT11A projectile flies from one tile to another
LABEL13The CaveBot reaches a Label waypoint
OPEN_STASH14The server sends the stash contents
HUD_DRAG15You drag a HUD of the script
ALARM20An alarm from the Tools tab fires
CREATURE_HEALTH100A creature's HP changes (DrenoxBot extra)
PLAYER_DATA101Your HP and mana data arrives (DrenoxBot extra)

TALK#

Fires for every speech message the server sends: Default, yell, whisper, channels, PMs and NPC speech.

#ParameterTypeDescription
1nametextWho spoke (empty if the server does not send it)
2levelnumberLevel of who spoke (0 if not sent)
3modenumberSpeech type, as in Enums.TalkTypes
4xnumberPosition of who spoke (0 when the speech has no position, as in PM and channel)
5ynumber
6znumber
7texttextWhat was said
8channelnumberChannel id (0 outside a channel)
lua
-- Flashes the window when someone says your name
Game.registerEvent(Game.Events.TALK, function(name, level, mode, x, y, z, text)
  if text:lower():find(Player.getName():lower(), 1, true) then
    print(name .. " (" .. level .. "): " .. text)
    Client.flashWindow()
  end
end)

MAGIC_EFFECT#

Fires for each magic effect (not projectile) the server draws on a tile.

#ParameterTypeDescription
1idnumberEffect id
2xnumberEffect position
3ynumber
4znumber
lua
-- Shows in the Console the effects around you
Game.registerEvent(Game.Events.MAGIC_EFFECT, function(id, x, y, z)
  local p = Player.getPosition()
  if z == p.z and math.abs(x - p.x) <= 1 and math.abs(y - p.y) <= 1 then
    print("effect " .. id .. " at " .. x .. "," .. y)
  end
end)

HUD_CLICK#

Fires when you click a HUD created by the script. Only the script that owns the HUD receives it. Before the registered functions, the bot calls the HUD's own callback (hud:setCallback), if there is one.

#ParameterTypeDescription
1hudIdnumberId of the clicked HUD (the same as hud:getId())
lua
local button = HUD.new(20, 100, "[ CaveBot ]")

Game.registerEvent(Game.Events.HUD_CLICK, function(hudId)
  if hudId == button:getId() then
    Engine.enableCaveBot(not Engine.isCaveBotEnabled())
  end
end)

HOTKEY_SHORTCUT_PRESS#

Fires when a key is pressed (not while it is held) and the client window is in focus. Modifier keys alone (Ctrl, Alt, Shift, Win, Num Lock) do not fire it: they only go into the mask.

#ParameterTypeDescription
1keynumberWindows virtual key code (A = 65, F1 = 112...)
2modifiersnumberSum of Enums.FlagModifiers: Ctrl 1, Alt 2, Shift 4, Num Lock on 8
lua
local ok, mods, key = HotkeyManager.parseKeyCombination("Ctrl+F5")

Game.registerEvent(Game.Events.HOTKEY_SHORTCUT_PRESS, function(k, m)
  if k == key and bit.band(m, 7) == mods then
    Engine.enableTargeting(not Engine.isTargetingEnabled())
  end
end)

TEXT_MESSAGE#

Fires for every text message from the server: loot, damage, healing, experience, green and red warnings, look.

#ParameterTypeDescription
1messagetableThe fields below
FieldTypeDescription
messageTypenumberMessage type, as in Enums.MessageTypes
texttextThe text
channelIdnumberMessage channel
positiontable or nil{x, y, z} when the message has a position (damage, healing)
valuenumberFirst value (damage, healing, xp)
secondValuenumberSecond value
colornumberColor of the first value
secondColornumberColor of the second value
lua
-- Adds up the damage taken
local total = 0
Game.registerEvent(Game.Events.TEXT_MESSAGE, function(msg)
  if msg.messageType == Enums.MessageTypes.MESSAGE_DAMAGE_RECEIVED then
    total = total + (msg.value or 0)
    print("total damage: " .. total)
  end
end)

Fires when the server opens a window with buttons and choices (NPCs, quests, OT systems). Answer with Game.modalWindowAnswer.

#ParameterTypeDescription
1windowtableThe fields below
FieldTypeDescription
idnumberWindow id, for Game.modalWindowAnswer
titletextTitle
messagetextWindow text
buttonslistButtons {id, text}
choiceslistList options {id, text}
defaultEnterButtonnumberEnter button
defaultEscapeButtonnumberEsc button
prioritybooleanWhether the window has priority
lua
-- Presses "Yes" on every window that has that button
Game.registerEvent(Game.Events.MODAL_WINDOW, function(window)
  for _, b in ipairs(window.buttons) do
    if b.text == "Yes" then
      Game.modalWindowAnswer(window.id, b.id, 0)
    end
  end
end)

CUSTOM_MODAL_WINDOW_BUTTON_CLICK#

Fires when you click a button in a window created by the script with CustomModalWindow. The window closes with the click. Only the owner script receives it, and the window's callback (setCallback) is called first.

#ParameterTypeDescription
1windowIdnumberWindow id (window:getId())
2buttonnumberButton index, starting at 0, in addButton order
lua
local window = CustomModalWindow.new("Refill", "Go back to town?")
window:addButton("Yes")  -- 0
window:addButton("No")  -- 1

Game.registerEvent(Game.Events.CUSTOM_MODAL_WINDOW_BUTTON_CLICK, function(id, button)
  if id == window:getId() and button == 0 then
    CaveBot.GoTo("refill")
  end
end)

QUEST_LOG#

Fires when the server sends the quest list, for example after Game.requestQuestLog().

#ParameterTypeDescription
1questslistOne table per quest: id, name, completed (boolean) and state (1 completed, 0 pending, as Enums.QuestState)
lua
Game.registerEvent(Game.Events.QUEST_LOG, function(quests)
  for _, q in ipairs(quests) do
    if not q.completed then print("pending: " .. q.name) end
  end
end)
Game.requestQuestLog()

QUEST_LINES#

Fires when the server sends the missions of a quest, for example after Game.requestQuestLines(id).

#ParameterTypeDescription
1questIdnumberQuest id
2missionslistOne table per mission: id, name, description
lua
Game.registerEvent(Game.Events.QUEST_LINES, function(questId, missions)
  for _, m in ipairs(missions) do
    print(m.name .. ": " .. m.description)
  end
end)

DISTANCE_SHOOT_EFFECT#

Fires for each projectile (arrow, rune, distance spell) the server draws.

#ParameterTypeDescription
1idnumberProjectile id
2fromXnumberStart position
3fromYnumber
4fromZnumber
5toXnumberEnd position
6toYnumber
7toZnumber
lua
-- Warns when a projectile lands on your tile
Game.registerEvent(Game.Events.DISTANCE_SHOOT_EFFECT, function(id, fx, fy, fz, tx, ty, tz)
  local p = Player.getPosition()
  if tx == p.x and ty == p.y and tz == p.z then
    print("projectile " .. id .. " on you")
  end
end)

LABEL#

Fires when the CaveBot reaches a Label waypoint, and only if some script has a function registered on this event. The CaveBot pauses before sending the event and stays stopped until a script calls CaveBot.pause(0). If the script that registered the event stops, the pause ends by itself.

#ParameterTypeDescription
1indexnumberWaypoint position in the route, starting at 0
2labeltextLabel text
lua
-- At label "check": under 50 mana potions, go to label "refill"
Game.registerEvent(Game.Events.LABEL, function(index, label)
  if label == "check" and Game.getItemCount(268) < 50 then -- 268 = mana potion
    CaveBot.GoTo("refill")
  end
  CaveBot.pause(0) -- releases the route
end)

OPEN_STASH#

Fires when the server sends the contents of your stash (supply stash).

#ParameterTypeDescription
1stashtablestashItems: list of {itemId, count}; freeSlots: free slots
lua
Game.registerEvent(Game.Events.OPEN_STASH, function(stash)
  for _, item in ipairs(stash.stashItems) do
    print(item.itemId .. " x" .. item.count)
  end
end)

HUD_DRAG#

Fires when you drop a draggable HUD (hud:setDraggable(true)) of the script at a new position. The HUD's position is already updated when the event arrives.

#ParameterTypeDescription
1hudIdnumberHUD id
2xnumberNew x position
3ynumberNew y position
lua
local hud = HUD.new(20, 60, "Drag me")
hud:setDraggable(true)

Game.registerEvent(Game.Events.HUD_DRAG, function(id, x, y)
  if id == hud:getId() then print("HUD now at " .. x .. ", " .. y) end
end)

ALARM#

Fires together with an alarm from the Tools tab (the same one that shows in the Console as [ALARM]). If alarms are turned off with Engine.allAlarmsEnable(false), the event does not fire either.

#ParameterTypeDescription
1typenumberWhich alarm, as in Enums.AlarmType
TypeWhen
DISCONNECTED (0)You disconnected
DAMAGE_TAKEN (1)You took damage (at most every 3 s)
LOW_HEALTH (2)HP dropped below the configured limit
PRIVATE_MESSAGE (3)A PM arrived
MONSTER_DETECTED / MONSTER_ON_SCREEN (4 / 5)A monster showed up on the map / on your floor
PLAYER_ATTACK (6)A player attacked you
PLAYER_DETECTED / PLAYER_ON_SCREEN (7 / 8)A player outside the party showed up
PLAYER_STUCK (9)The CaveBot is on and you have not moved
SKULL_DETECTED / SKULL_ON_SCREEN (10 / 11)A player with a skull showed up
ENEMY_DETECTED / ENEMY_ON_SCREEN (12 / 13)An enemy (guild or list) showed up
GM_DETECTED (14)A GM showed up
LOW_CAP (15)Cap dropped below the limit
PLAYER_IDLE (16)You stood still without gaining xp for the configured time
lua
Game.registerEvent(Game.Events.ALARM, function(alarmType)
  if alarmType == Enums.AlarmType.PLAYER_ON_SCREEN then
    Engine.enableCaveBot(false)
    Sound.play("alarm.wav", true)
  end
end)

CREATURE_HEALTH#

DrenoxBot extra (does not exist in ZeroBot). Fires when the server sends a creature's new HP.

#ParameterTypeDescription
1creatureIdnumberCreature id
2hpnumberHP in percent (0 to 100)
lua
local hud = HUD.new(20, 60, "Target: -")
Game.registerEvent(Game.Events.CREATURE_HEALTH, function(id, hp)
  if id == Player.getTargetId() then
    hud:setText(Creature.new(id):getName() .. "  " .. hp .. "%")
  end
end)

PLAYER_DATA#

DrenoxBot extra (does not exist in ZeroBot). Fires every time the server sends the packet with your status data (HP, mana, cap, level...).

#ParameterTypeDescription
1healthnumberCurrent HP
2maxHealthnumberMax HP
3mananumberCurrent mana
4maxMananumberMax mana
lua
Game.registerEvent(Game.Events.PLAYER_DATA, function(hp, maxHp, mana, maxMana)
  if hp < maxHp * 0.3 then
    Client.showMessage("Low HP!")
  end
end)

ZeroBot events that do not fire yet#

Game.Events has all of ZeroBot's names, so registering the events below does not raise an error. But DrenoxBot does not fire any of them yet: the function stays registered and is never called.

EventNumber
IMBUEMENT_DATA7
IMBUEMENT_OPEN_WINDOW8
PARTY_HUNT12
STORE_CATEGORIES16
STORE_OFFERS17
OPEN_DAILY_REWARD18
DAILY_REWARD_DAYS_DATA19
TASK_HUNTING_DATA21
TASK_BOARD_DATA22

See also: Scripting and the function reference.