Mudlle's On-Line Manual: Events

1. Introduction

Most of the special behaviour in MUME are coded as reactions to events received. When an action occurs in MUME, the appropriate event is generated and sent to a number of entities. If an entity has a reaction to that particular event, that reaction is executed. If more than one reaction is found, all reactions are executed.

Event recipients can be:

roomthe room where the action occurs
objan instance of an object class
moban instance of a mobile class
globalthe global event handler

The global event handler is a special case - its associated mudlle file is not attached to any class, and is accessible only at imp-level. Note also that players cannot receive events, since no mudlle files are attached to players.

Events can be broadly classified as:

immediatesent at the time the action occurs
delayedsent after completion of the action causing the event

Actions which send immediate events have a chance of being aborted.

The generic syntax for a reaction procedure is:

react_event(fn (me, arg1, arg2 .. argn) [ ... ],
            "short explanation of reaction",
            )
where 'me' is the event recipient.

You can write any number of reaction procedures on a class. Typically, the complete code on a class is no more than a collection of relevant reactions, plus the declaration of some local variables and functions.

Code example:

[

| master, greet_master |

master = "Vivriel";

greet_master = fn (who)
[
    if (!string_icmp(get_char_name(who), master))
        send_char(who, "Welcome home, Master!\n\r");
];

react_event(fn (me, who)
    [
        greet_master(who);
    ], "greet master on entrance", EVENT_ENTER);

]

You can write reactions within functions which are then called in the associated file of a MUME class, but you cannot embed a reaction in another reaction. This is because reactions are registered on the class at load time, and do not change dynamically after.

Reactions to events not handled by the class and reactions not called on a class are ignored.

2. Predefined Events

For all events, the first argument 'me' (the event recipient) is always sent and is assumed. Only additional arguments are listed. Where 'p' is used, it means either a player or a mobile. Events which differentiate between the two will use the term 'player' or 'mob'.

Immediate events:

If any of the event recipients has a reaction procedure which calls 'override()', the action is aborted. Otherwise it is executed normally after all reactions have been processed.

EVENT_COMMANDsent when p types a command to objs equipped by p, room, mobs in room, objs in room (but not to objs in inventories) (args: p, command, command_args)
p

is the player or mobile issuing the command

command is an integer usually represented by a global constant CMD_???

God commands are represented by GODCMD_???, with values < 0.

command_args command_args is the string passed as argument to the command.
For example, when Vivriel types "say hello world", the event is sent with the arguments ({player Vivriel}, CMD_SAY, " hello world"). Note that special abbreviations of commands have their own numbers, e.g. the "say" abbreviation ' is number 169. If your reaction traps CMD_SAY, it must also test for command 169.
EVENT_GOD_COMMAND sent when p types a god command /xxx to objs equipped by p, room, mobs in room, objs in room (args: p, arg_list)
EVENT_HIDEsent when p tries to hide obj to obj, room, all mobs in room (args: p, obj, room)
Destroying the object or moving the person hiding it, also aborts the hide.

Delayed events:

EVENT_CREATEsent when room|mob|obj is created to room|mob|obj (args: none)
EVENT_CREATE_GLOBALsent when room|mob|obj is created to global (args: room|mob|obj)
EVENT_EQUIPPEDsent when p equips obj to p, all objs equipped by p including obj (args: p, obj)
EVENT_ENTERsent when player enters a room to room, all mobs in room (args: player)
EVENT_ENTER_GAMEsent when player enters the game to room, global (args: player, room)
EVENT_EXITsent when player exits a room to room, all mobs in room (args: player)
EVENT_I_MOVEDsent when a mob moves to mob (args: none)
EVENT_DOORsent when p does an action on a door to both rooms on the two sides of the door (args: p, action, room, dir)
Action is one of DOOR_OPENED, DOOR_CLOSED, DOOR_LOCKED, DOOR_UNLOCKED or DOOR_KNOCKED.
Room is the room of the action, i.e. where p is
Only the last arg differs for the two rooms: the action room gets the door direction, but the other room gets the opposite direction which may or may not be the direction of a door leading back to the action room. Make an explicit check if you need the opposite door direction.
EVENT_GIVE (a react_give cmd exists)sent when p1 gives p2 an obj to p2, obj (args: p1, p2, obj)
EVENT_GIVE_MONEYsent when p1 gives p2 money to p2 (args: p1, p2, amount)
EVENT_TAKEsent when p takes an obj from room to room, all mobs in room (args: p, obj)
EVENT_TAKE_MONEYsent when p takes money from room to room, all mobs in room (args: p, amount)
EVENT_DROPsent when p drops an obj to p's room, obj (args: p, obj)
EVENT_REVEALsent when p reveals hidden obj to obj, room, all mobs in room (args: p, obj, room)
EVENT_HEARsent when p1 hears a message from p2 to p1 (args: type, p2, message)
Type is one of HEAR_SAY (p2 says), (HEAR_TELL (p2 tells p1) this one has been removed), HEAR_WHISPER (p2 whispers to p1), HEAR_QUESTION (p2 asks p1). The message that p1 gets is suitably encrypted according to his language knowledge.
EVENT_SPELLsent when p casts a spell successfully on x to x and x's eq, if x is a char to x only, if x is an obj to room, otherwise (args: p, spell)
is the spell number represented by SPELL_???.
EVENT_ATTACKsent when p1 attacks p2, whether with weapons or spells to p1's room, all mobs in room (args: p1, p2)
No event is sent when p2 responds to the attack.
EVENT_DEATHsent when p dies to room, all mobs in room (args: p)
Note that since the event is delayed, p does not receive the event.
EVENT_HELP_CRYsent when a citizen cries for help to complain room of town (args: citizen, attacker, 0)
The '0' is there for historical reasons known only to the imps.
EVENT_WEATHERsent at weather changes to global (args: weather_type, value)
Currently defined weather events are:
WEATHER_SUN SUN_RISE when sun rises
SUN_LIGHT when day begins
SUN_SET when sun sets
SUN_DARK when night falls, or Sauron casts his darkness
WEATHER_MOON MOON_RISE when moon rises
MOON_SET when moon sets
EVENT_EATsent when an obj of type FOOD is eaten (args: who, amount, eaten)
This event is sent by the eat & taste commands. Currently, taste doesn't eat any of the object, so amount is 0. But this might return to the old behaviour of eating 1 one day... To know if the object is still there, rely on 'eaten'.

Other events : EVENT_TICK (msg 364), EVENT_TELL (msg 418), EVENT_QUAFF (msg 491), EVENT_SHEATHE(msg 325, but does it really exists?) + hack of the day (see msg502 board 19)

3. Special Events

In rare cases, you may need to trigger reactions to special actions not covered by the pre-defined events. An example is the Harlond-Forlond ferry in Grey Havens; the ferry needs to notify the boarding room of its arrival and departure.

allocate_event (s) create a new event and assign its identifier to a global variable named s

cause_event (n, v, b, dn, dx, ...) send event n with vector of arguments v to destination pairs (dn, dx), immediate if b is TRUE, else delayed

If the event identifier < s > already exists, its former value is restored. Arguments < v > exclude 'me' which is always sent and implied. Destination pairs can be:

EVENT_ROOM, room send to room
EVENT_CHAR, mob send to mob
EVENT_OBJ, obj send to obj
EVENT_IN_ROOM, roomsend to room, all mobs and objs in room

You can specify several destinations for one event.

Code example:

[
| ferry, shore |

allocate_event("EVENT_FERRY");
FERRY_ARRIVE = 1;
...
cause_event(EVENT_FERRY, vector(FERRY_ARRIVE, ferry), FALSE,
            EVENT_ROOM, shore);

]

Corresponding reaction procedure:

react_event(fn (me, type, ferry)
    if (type == FERRY_ARRIVE)
    [
        ...
    ], "ferry arrival", EVENT_FERRY);

Created: April 3rd, 1997 by Vengeance. Last Modified: May 30th, 1997