-
Notifications
You must be signed in to change notification settings - Fork 3
Events
Hook one with @minqlxtended.hook("name"). See Writing Plugins for
registration and return values.
game_start, game_end, round_end, team_switch, kill and death are read out of the
game module, so zmq_stats_enable 1 is not required. The ZMQ listener is only needed by
plugins hooking the raw stats event.
| Event | Arguments |
|---|---|
player_connect |
(player, is_bot) |
player_loaded |
(player) |
player_disconnect |
(player, reason) |
player_spawn |
(player) |
team_switch_attempt |
(player, old_team, new_team, target) |
team_switch |
(player, old_team, new_team) |
userinfo |
(player, changed, infostring) |
kill |
(victim, killer, mod) |
death |
(victim, killer, mod) |
damage |
(target, attacker, damage, dflags, mod) |
weapon_fired |
(player, weapon) |
item_pickup |
(player, item_name) |
objective |
(player, kind, count) |
kamikaze_use |
(player) |
kamikaze_explode |
(player, is_used_on_demand) |
kill fires only when another player was responsible; death always fires, with killer
None when nobody was. Changing team does not raise death.
team_switch_attempt comes from SetTeam, so cancelling prevents the switch outright. It
fires for admin puts, duel-queue promotion, follow-cycling and level exit as well as a player
typing team X. target is the raw argument, which tells a follow1 from an ordinary
spectate. Cancelling it to enforce a team lock blocks admins too.
damage fires after the damage is applied, so the target's health already reflects it.
attacker is None for lava, a trigger_hurt or a fall, and is the target on self-damage.
It cannot be cancelled: G_Damage applies armour, powerups and scoring internally and takes
its direction and impact point by pointer. Damage to shootable world entities is filtered out.
| Event | Arguments |
|---|---|
game_countdown |
() |
game_start |
() |
game_end |
(aborted) |
round_countdown |
(round_number) |
round_start |
(round_number) |
round_end |
(round_number, winning_team, time) |
round_end reports the winner by watching which team's score went up, so it behaves the same
in Clan Arena, Freeze Tag, Red Rover and Attack & Defend, and answers None on a draw. time
is the round's duration in milliseconds. Its round number is the one round_start gave.
aborted is true when the match ended without a result.
| Event | Arguments |
|---|---|
frame |
() |
map |
(map, factory) |
new_game |
() |
spawn_server |
() |
chat |
(player, msg, channel, recipient) |
client_command |
(player, command) |
server_command |
(player, command) |
console_print |
(text) |
set_configstring |
(index, value) |
cvar_changed |
(name, old_value, new_value) |
demo_finished |
(client_id, path, size, discarded, failed) |
unload |
(plugin) |
chat comes from G_Say, so the message arrives exactly as the engine has it and cancelling
stops it being said. Private messages (/tell) raise it too, with recipient set to the
player who was told and None for anything said openly. The channel addresses the speaker, so
a !command typed into a tell answers whoever typed it.
cvar_changed fires only for a write that changed the live value.
demo_finished carries a client id rather than a Player, because the player it recorded has
usually left by then. discarded means the segment held nothing but a gamestate and was
removed, so there is no file at path.
| Event | Arguments |
|---|---|
vote_called |
(player, vote, args) |
vote_started |
(player, vote, args) |
vote |
(player, yes) |
vote_ended |
(votes, vote, args, passed) |
vote_called fires while another vote is already running, and for votes the engine goes on to
reject. Hook vote_started for the votes that actually run. vote fires whether or not a
vote is running. vote_ended also fires for votes abandoned by intermission or a level
change, reported as not passed.
A passing vote's tally is one short: the frame that tips it over the line never records the deciding vote. An expiry reports the true count.
A map change is not one moment. The order is: spawn_server, then the engine tears the old
level down and builds the new one, then map and new_game.
Everything in between still reaches your handlers. SV_SpawnServer drops every bot through
the same path a real disconnect takes, so a devmap raises player_disconnect for each of
them. It writes ten cvars, so cvar_changed fires repeatedly. It prints throughout, so does
console_print. It runs the game module's frame export a few times with the entity hooks live.
Plugin.gameisNonefor the whole of that window. The configstring cache is dropped whenspawn_serverfires andCS_SERVERINFOis not rewritten until the end.
A handler touching minqlxtended.level, an Entity or a GameClient during that window
raises EngineStateError rather than reading freed memory. The game module is genuinely
unmapped for part of it. Hook map or new_game, which are the first events for which the
new world is complete.