Bring the event system to Evennia-style compliance

This commit is contained in:
Vincent Le Goff 2017-03-20 12:29:04 -07:00 committed by Griatch
parent 629ac73f2b
commit 81f4c590bd
5 changed files with 174 additions and 171 deletions

View file

@ -6,12 +6,12 @@ from datetime import datetime
from django.conf import settings
from evennia import Command
from evennia.contrib.events.custom import get_event_handler
from evennia.utils.ansi import raw
from evennia.utils.eveditor import EvEditor
from evennia.utils.evtable import EvTable
from evennia.utils.utils import class_from_module, time_format
from evennia.contrib.events.custom import get_event_handler
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
# Permissions
@ -20,26 +20,26 @@ WITHOUT_VALIDATION = getattr(settings, "EVENTS_WITHOUT_VALIDATION",
"immortals")
VALIDATING = getattr(settings, "EVENTS_VALIDATING", "immortals")
# Split help file
# Split help text
BASIC_HELP = "Add, edit or delete events."
BASIC_USAGES = [
"@event object name [= event name]",
"@event/add object name = event name [parameters]",
"@event/edit object name = event name [event number]",
"@event/del object name = event name [event number]",
"@event/tasks [object name [= event name [event number]]]",
"@event <object name> [= <event name>]",
"@event/add <object name> = <event name> [parameters]",
"@event/edit <object name> = <event name> [event number]",
"@event/del <object name> = <event name> [event number]",
"@event/tasks [object name [= <event name>]]",
]
BASIC_SWITCHES = [
"add - add and edit a new event",
"edit - edit an existing event",
"del - delete an existing event",
"tasks - show the list of differed tasks",
"add - add and edit a new event",
"edit - edit an existing event",
"del - delete an existing event",
"tasks - show the list of differed tasks",
]
VALIDATOR_USAGES = [
"@event/accept [object name = event name [event number]]",
"@event/accept [object name = <event name> [event number]]",
]
VALIDATOR_SWITCHES = [
@ -50,12 +50,12 @@ BASIC_TEXT = """
This command is used to manipulate events. An event can be linked to
an object, to fire at a specific moment. You can use the command without
switches to see what event are active on an object:
@event self
@event self
You can also specify an event name if you want the list of events associated
with this object of this name:
@event north = can_traverse
You might need to specify a number after the event if there are more than one:
@event here = say 2
@event north = can_traverse
You can also add a number after the event name to see details on one event:
@event here = say 2
You can also add, edit or remove events using the add, edit or del switches.
Additionally, you can see the list of differed tasks created by events
(chained events to be called) using the /tasks switch.
@ -66,27 +66,26 @@ You can also use this command to validate events. Depending on your game
setting, some users might be allowed to add new events, but these events
will not be fired until you accept them. To see the events needing
validation, enter the /accept switch without argument:
@event/accept
@event/accept
A table will show you the events that are not validated yet, who created
it and when. You can then accept a specific event:
@event here = enter
Or, if more than one events are connected here, specify the number:
@event here = enter 3
them and when. You can then accept a specific event:
@event here = enter 1
Use the /del switch to remove events that should not be connected.
"""
class CmdEvent(COMMAND_DEFAULT_CLASS):
"""Command to edit events."""
"""
Command to edit events.
"""
key = "@event"
locks = "cmd:perm({})".format(VALIDATING)
aliases = ["@events", "@ev"]
locks = "cmd:perm({})".format(VALIDATING)
if WITH_VALIDATION:
locks += " or perm({})".format(WITH_VALIDATION)
help_category = "Building"
def get_help(self, caller, cmdset):
"""
Return the help message for this command and this caller.
@ -104,18 +103,18 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
"""
lock = "perm({}) or perm(events_validating)".format(VALIDATING)
validator = caller.locks.check_lockstring(caller, lock)
text = "\n" + BASIC_HELP + "\n\nUsages:\n "
text = "\n" + BASIC_HELP + "\n\nUsages:\n "
# Usages
text += "\n ".join(BASIC_USAGES)
text += "\n ".join(BASIC_USAGES)
if validator:
text += "\n " + "\n ".join(VALIDATOR_USAGES)
text += "\n " + "\n ".join(VALIDATOR_USAGES)
# Switches
text += "\n\nSwitches:\n "
text += "\n ".join(BASIC_SWITCHES)
text += "\n\nSwitches:\n "
text += "\n ".join(BASIC_SWITCHES)
if validator:
text += "\n " + "\n".join(VALIDATOR_SWITCHES)
text += "\n " + "\n ".join(VALIDATOR_SWITCHES)
# Text
text += "\n" + BASIC_TEXT
@ -146,37 +145,25 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
"access the event system.")
return
# Before the equal sign is always an object name
if self.args.strip():
# Before the equal sign, there is an object name or nothing
if self.lhs:
self.obj = caller.search(self.lhs)
if not self.obj:
return
# Switches are mutually exclusive
switch = self.switches and self.switches[0] or ""
if switch == "":
if not self.obj:
caller.msg("Specify an object's name or #ID.")
return
if switch in ("", "add", "edit", "del") and self.obj is None:
caller.msg("Specify an object's name or #ID.")
return
if switch == "":
self.list_events()
elif switch == "add":
if not self.obj:
caller.msg("Specify an object's name or #ID.")
return
self.add_event()
elif switch == "edit":
if not self.obj:
caller.msg("Specify an object's name or #ID.")
return
self.edit_event()
elif switch == "del":
if not self.obj:
caller.msg("Specify an object's name or #ID.")
return
self.del_event()
elif switch == "accept" and validator:
self.accept_event()
@ -198,16 +185,17 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
# Check that the event name can be found in this object
created = events.get(event_name)
if created is None:
self.msg("No event {} has been set on {}.".format(event_name, obj))
self.msg("No event {} has been set on {}.".format(event_name,
obj))
return
if parameters:
# Check that the parameter points to an existing event
try:
parameters = int(parameters) - 1
assert parameters >= 0
event = events[event_name][parameters]
except (AssertionError, ValueError):
number = int(parameters) - 1
assert number >= 0
event = events[event_name][number]
except (ValueError, AssertionError, IndexError):
self.msg("The event {} {} cannot be found in {}.".format(
event_name, parameters, obj))
return
@ -223,10 +211,9 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
updated_on = event.get("updated_on")
updated_on = updated_on.strftime("%Y-%m-%d %H:%M:%S") \
if updated_on else "|gUnknown|n"
number = parameters + 1
msg = "Event {} {} of {}:".format(event_name, number, obj)
msg += "\nCreated by {} at {}.".format(author, created_on)
msg += "\nUpdated by {} at {}".format(updated_by, updated_on)
msg = "Event {} {} of {}:".format(event_name, parameters, obj)
msg += "\nCreated by {} on {}.".format(author, created_on)
msg += "\nUpdated by {} on {}".format(updated_by, updated_on)
if self.is_validator:
if event.get("valid"):
@ -235,7 +222,7 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
msg += "\nThis event |rhasn't been|n accepted yet."
msg += "\nEvent code:\n"
msg += "\n".join([l for l in event["code"].splitlines()])
msg += raw(event["code"])
self.msg(msg)
return
@ -255,8 +242,9 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
updated_on = event.get("created_on")
if updated_on:
updated_on = time_format(
(now - updated_on).total_seconds(), 1)
updated_on = "{} ago".format(time_format(
(now - updated_on).total_seconds(),
4).capitalize())
else:
updated_on = "|gUnknown|n"
parameters = event.get("parameters", "")
@ -330,7 +318,7 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
# If there's only one event, just edit it
if len(events[event_name]) == 1:
parameters = 0
number = 0
event = events[event_name][0]
else:
if not parameters:
@ -340,10 +328,10 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
# Check that the parameter points to an existing event
try:
parameters = int(parameters) - 1
assert parameters >= 0
event = events[event_name][parameters]
except (AssertionError, ValueError):
number = int(parameters) - 1
assert number >= 0
event = events[event_name][number]
except (ValueError, AssertionError, IndexError):
self.msg("The event {} {} cannot be found in {}.".format(
event_name, parameters, obj))
return
@ -355,10 +343,10 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
return
# If the event is locked (edited by someone else)
if (obj, event_name, parameters) in self.handler.db.locked:
if (obj, event_name, number) in self.handler.db.locked:
self.msg("This event is locked, you cannot edit it.")
return
self.handler.db.locked.append((obj, event_name, parameters))
self.handler.db.locked.append((obj, event_name, number))
# Check the definition of the event
definition = types.get(event_name, (None, "Chained event"))
@ -369,7 +357,7 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
event = dict(event)
event["obj"] = obj
event["name"] = event_name
event["number"] = parameters
event["number"] = number
self.caller.db._event = event
EvEditor(self.caller, loadfunc=_ev_load, savefunc=_ev_save,
quitfunc=_ev_quit, key="Event {} of {}".format(
@ -396,7 +384,7 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
# If there's only one event, just delete it
if len(events[event_name]) == 1:
parameters = 0
number = 0
event = events[event_name][0]
else:
if not parameters:
@ -407,10 +395,10 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
# Check that the parameter points to an existing event
try:
parameters = int(parameters) - 1
assert parameters >= 0
event = events[event_name][parameters]
except (AssertionError, ValueError):
number = int(parameters) - 1
assert number >= 0
event = events[event_name][number]
except (ValueError, AssertionError, IndexError):
self.msg("The event {} {} cannot be found in {}.".format(
event_name, parameters, obj))
return
@ -422,14 +410,14 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
return
# If the event is locked (edited by someone else)
if (obj, event_name, parameters) in self.handler.db.locked:
if (obj, event_name, number) in self.handler.db.locked:
self.msg("This event is locked, you cannot delete it.")
return
# Delete the event
self.handler.del_event(obj, event_name, parameters)
self.handler.del_event(obj, event_name, number)
self.msg("The event {} {} of {} was deleted.".format(
obj, event_name, parameters + 1))
obj, event_name, parameters))
def accept_event(self):
"""Accept an event."""
@ -461,8 +449,9 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
updated_on = event.get("created_on")
if updated_on:
updated_on = time_format(
(now - updated_on).total_seconds(), 1)
updated_on = "{} ago".format(time_format(
(now - updated_on).total_seconds(),
4).capitalize())
else:
updated_on = "|gUnknown|n"
@ -492,10 +481,10 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
# Check that the parameter points to an existing event
try:
parameters = int(parameters) - 1
assert parameters >= 0
event = events[event_name][parameters]
except (AssertionError, ValueError):
number = int(parameters) - 1
assert number >= 0
event = events[event_name][number]
except (ValueError, AssertionError, IndexError):
self.msg("The event {} {} cannot be found in {}.".format(
event_name, parameters, obj))
return
@ -504,7 +493,7 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
if event["valid"]:
self.msg("This event has already been accepted.")
else:
self.handler.accept_event(obj, event_name, parameters)
self.handler.accept_event(obj, event_name, number)
self.msg("The event {} {} of {} has been accepted.".format(
event_name, parameters, obj))

View file

@ -11,10 +11,10 @@ from textwrap import dedent
from django.conf import settings
from evennia import logger
from evennia import ScriptDB
from evennia.contrib.custom_gametime import UNITS
from evennia.contrib.custom_gametime import real_seconds_until as custom_rsu
from evennia.utils.create import create_script
from evennia.utils.gametime import real_seconds_until as standard_rsu
from evennia.contrib.custom_gametime import UNITS
from evennia.contrib.custom_gametime import real_seconds_until as custom_rsu
hooks = []
event_types = []
@ -24,7 +24,7 @@ def get_event_handler():
try:
script = ScriptDB.objects.get(db_key="event_handler")
except ScriptDB.DoesNotExist:
logger.log_err("Can't get the event handler.")
logger.log_trace("Can't get the event handler.")
script = None
return script
@ -39,10 +39,10 @@ def create_event_type(typeclass, event_name, variables, help_text,
event_name (str): the name of the event to be added.
variables (list of str): a list of variable names.
help_text (str): a help text of the event.
custom_add (function, default None): a callback to call when adding
custom_add (function, optional): a callback to call when adding
the new event.
custom_xcall (function, default None): a callback to call when
preparing to call the events.
custom_call (function, optional): a callback to call when
preparing to call the event.
Events obey the inheritance hierarchy: if you set an event on
DefaultRoom, for instance, and if your Room typeclass inherits
@ -50,42 +50,23 @@ def create_event_type(typeclass, event_name, variables, help_text,
all rooms. Objects of the typeclass set in argument will be
able to set one or more events of that name.
If the event already exists in the typeclass, replace it.
If the event type already exists in the typeclass, replace it.
"""
typeclass_name = typeclass.__module__ + "." + typeclass.__name__
event_types.append((typeclass_name, event_name, variables, help_text,
custom_add, custom_call))
def del_event_type(typeclass, event_name):
"""
Delete the event type for this typeclass.
Args:
typeclass (type): the class defining the typeclass.
event_name (str): the name of the event to be deleted.
If you want to delete an event type, you need to remove it from
the typeclass that defined it: other typeclasses in the inheritance
hierarchy are not affected. This method doesn't remove the
already-created events associated with individual objects.
"""
typeclass_name = typeclass.__module__ + "." + typeclass.__name__
try:
script = ScriptDB.objects.get(db_key="event_handler")
except ScriptDB.DoesNotExist:
logger.log_err("Can't create event {} in typeclass {}, the " \
"script handler isn't defined".format(name, typeclass_name))
return
# Get the event types for this typeclass
event_types = script.ndb.event_types.get(typeclass_name, {})
if event_name in event_types:
del event_types[event_name]
def patch_hook(typeclass, method_name):
"""Decorator to softly patch a hook in a typeclass."""
"""
Decorator to softly patch a hook in a typeclass.
This decorator should not be used, unless for good reasons, outside
of this contrib. The advantage of using decorated soft patchs is
in allowing users to customize typeclasses without changing the
inheritance tree for a couple of methods.
"""
hook = getattr(typeclass, method_name)
def wrapper(method):
"""Wrapper around the hook."""
@ -119,13 +100,14 @@ def connect_event_types():
Connect the event types when the script runs.
This method should be called automatically by the event handler
(the script).
(the script). It might be useful, however, to call it after adding
new event types in typeclasses.
"""
try:
script = ScriptDB.objects.get(db_key="event_handler")
except ScriptDB.DoesNotExist:
logger.log_err("Can't connect event types, the event handler " \
logger.log_trace("Can't connect event types, the event handler " \
"cannot be found.")
return
@ -146,7 +128,7 @@ def connect_event_types():
types[event_name] = (variables, help_text, custom_add, custom_call)
del event_types[0]
# Custom callbacks for specific events
# Custom callbacks for specific event types
def get_next_wait(format):
"""
Get the length of time in seconds before format.
@ -188,7 +170,7 @@ def get_next_wait(format):
break
if not piece.isdigit():
logger.log_err("The time specified '{}' in {} isn't " \
logger.log_trace("The time specified '{}' in {} isn't " \
"a valid number".format(piece, format))
return
@ -205,13 +187,13 @@ def get_next_wait(format):
def create_time_event(obj, event_name, number, parameters):
"""
Create an time-related event.
Create a time-related event.
args:
Args:
obj (Object): the object on which stands the event.
event_name (str): the event's name.
number (int): the number of the event.
parameter (str): the parameter of the event.
parameters (str): the parameter of the event.
"""
seconds, key = get_next_wait(parameters)
@ -229,7 +211,7 @@ def keyword_event(events, parameters):
parameter to add the event type when the event supports keywords
as parameters. Keywords in parameters are one or more words
separated by a comma. For instance, a 'push 1, one' event can
be triggered to trigger when the player 'push 1' or 'push one'.
be set to trigger when the player 'push 1' or 'push one'.
Args:
events (list of dict): the list of events to be called.

View file

@ -1,8 +1,7 @@
"""
Module defining basic helpers for the event system.
Hlpers are just Python function that can be used inside of events. They
Hlpers are just Python functions that can be used inside of events. They
"""
@ -70,9 +69,10 @@ def call(obj, event_name, seconds=0):
seconds (int or float): the number of seconds to wait before calling
the event.
Notice that chained events are designed for this very purpose: they
are never called automatically by the game, rather, they need to be
called from inside another event.
Note:
Chained events are designed for this very purpose: they
are never called automatically by the game, rather, they need
to be called from inside another event.
"""
try:

View file

@ -8,16 +8,24 @@ from Queue import Queue
from django.conf import settings
from evennia import DefaultScript, ScriptDB
from evennia import logger
from evennia.utils.dbserialize import dbserialize
from evennia.utils.utils import all_from_module, delay
from evennia.contrib.events.custom import connect_event_types, \
get_next_wait, patch_hooks
from evennia.contrib.events.exceptions import InterruptEvent
from evennia.contrib.events import typeclasses
from evennia.utils.dbserialize import dbserialize
from evennia.utils.utils import all_from_module, delay
class EventHandler(DefaultScript):
"""Event handler that contains all events in a global script."""
"""
The event handler that contains all events in a global script.
This script shouldn't be created more than once. It contains
event types (in a non-persistent attribute) and events (in a
persistent attribute). The script method would help adding,
editing and deleting these events.
"""
def at_script_creation(self):
self.key = "event_handler"
@ -41,8 +49,9 @@ class EventHandler(DefaultScript):
# Generate locals
self.ndb.current_locals = {}
addresses = ["evennia.contrib.events.helpers"]
self.ndb.fresh_locals = {}
addresses = ["evennia.contrib.events.helpers"]
addresses.extend(getattr(settings, "EVENTS_HELPERS_LOCATIONS", []))
for address in addresses:
self.ndb.fresh_locals.update(all_from_module(address))
@ -56,7 +65,6 @@ class EventHandler(DefaultScript):
delay(seconds, complete_task, task_id)
def get_events(self, obj):
"""
Return a dictionary of the object's events.
@ -64,6 +72,13 @@ class EventHandler(DefaultScript):
Args:
obj (Object): the connected objects.
Returns:
A dictionary of the object's events.
Note:
This method can be useful to override in some contexts,
when several objects would share events.
"""
return self.db.events.get(obj, {})
@ -74,6 +89,14 @@ class EventHandler(DefaultScript):
Args:
obj (Object): the connected object.
Returns:
A dictionary of the object's event types.
Note:
Event types would define what the object can have as
events. Note, however, that chained events will not
appear in event types and are handled separately.
"""
types = {}
event_types = self.ndb.event_types
@ -96,11 +119,11 @@ class EventHandler(DefaultScript):
Add the specified event.
Args:
obj (Object): the Evennia typeclassed object to be modified.
obj (Object): the Evennia typeclassed object to be extended.
event_name (str): the name of the event to add.
code (str): the Python code associated with this event.
author (optional, Character, Player): the author of the event.
valid (optional, bool): should the event be connected?
author (Character or Player, optional): the author of the event.
valid (bool, optional): should the event be connected?
parameters (str, optional): optional parameters.
This method doesn't check that the event type exists.
@ -148,12 +171,15 @@ class EventHandler(DefaultScript):
Edit the specified event.
Args:
obj (Object): the Evennia typeclassed object to be modified.
event_name (str): the name of the event to add.
obj (Object): the Evennia typeclassed object to be edited.
event_name (str): the name of the event to edit.
number (int): the event number to be changed.
code (str): the Python code associated with this event.
author (optional, Character, Player): the author of the event.
valid (optional, bool): should the event be connected?
author (Character or Player, optional): the author of the event.
valid (bool, optional): should the event be connected?
Raises:
RuntimeError if the event is locked.
This method doesn't check that the event type exists.
@ -170,7 +196,7 @@ class EventHandler(DefaultScript):
# If locked, don't edit it
if (obj, event_name, number) in self.db.locked:
raise RunTimeError("this event is locked.")
raise RuntimeError("this event is locked.")
# Edit the event
events[number].update({
@ -186,7 +212,6 @@ class EventHandler(DefaultScript):
elif valid and (obj, event_name, number) in self.db.to_valid:
self.db.to_valid.remove((obj, event_name, number))
def del_event(self, obj, event_name, number):
"""
Delete the specified event.
@ -196,13 +221,16 @@ class EventHandler(DefaultScript):
event_name (str): the name of the event to delete.
number (int): the number of the event to delete.
Raises:
RuntimeError if the event is locked.
"""
obj_events = self.db.events.get(obj, {})
events = obj_events.get(event_name, [])
# If locked, don't edit it
if (obj, event_name, number) in self.db.locked:
raise RunTimeError("this event is locked.")
raise RuntimeError("this event is locked.")
# Delete the event itself
try:
@ -274,9 +302,9 @@ class EventHandler(DefaultScript):
*args: additional variables for this event.
Kwargs:
number (int, default None): call just a specific event.
parameters (str, default ""): call an event with parameters.
locals (dict): a locals replacement.
number (int, optional): call just a specific event.
parameters (str, optional): call an event with parameters.
locals (dict, optional): a locals replacement.
Returns:
True to report the event was called without interruption,
@ -307,7 +335,7 @@ class EventHandler(DefaultScript):
try:
locals[variable] = args[i]
except IndexError:
logger.log_err("event {} of {} ({}): need variable " \
logger.log_trace("event {} of {} ({}): need variable " \
"{} in position {}".format(event_name, obj,
type(obj), variable, i))
return False
@ -348,15 +376,16 @@ class EventHandler(DefaultScript):
the differed delay is called again.
Args:
seconds (int/float): the delay in seconds from now.
seconds (int, float): the delay in seconds from now.
obj (Object): the typecalssed object connected to the event.
event_name (str): the event's name.
Note that the dictionary of locals is frozen and will be
available again when the task runs. This feature, however,
is limited by the database: all data cannot be saved. Lambda
functions, class methods, objects inside an instance and so
on will not be kept in the locals dictionary.
Note:
The dictionary of locals is frozen and will be available
again when the task runs. This feature, however, is limited
by the database: all data cannot be saved. Lambda functions,
class methods, objects inside an instance and so on will
not be kept in the locals dictionary.
"""
now = datetime.now()
@ -399,7 +428,7 @@ class TimeEventScript(DefaultScript):
try:
script = ScriptDB.objects.get(db_key="event_handler")
except ScriptDB.DoesNotExist:
logger.log_err("Can't get the event handler.")
logger.log_trace("Can't get the event handler.")
return
if self.db.event_name and self.db.number is not None:
@ -434,13 +463,13 @@ def complete_task(task_id):
This function should be called automatically for individual tasks.
Args:
task_id (int): the task id.
task_id (int): the task ID.
"""
try:
script = ScriptDB.objects.get(db_key="event_handler")
except ScriptDB.DoesNotExist:
logger.log_err("Can't get the event handler.")
logger.log_trace("Can't get the event handler.")
return
if task_id not in script.db.tasks:

View file

@ -4,9 +4,9 @@ Patched typeclasses for Evennia.
from evennia import DefaultCharacter, DefaultExit, DefaultObject, DefaultRoom
from evennia import ScriptDB
from evennia.utils.utils import inherits_from
from evennia.contrib.events.custom import create_event_type, patch_hook, \
create_time_event
from evennia.utils.utils import inherits_from
class PatchedExit(object):
@ -52,10 +52,12 @@ create_event_type(DefaultExit, "can_traverse", ["character", "exit", "room"],
Can the character traverse through this exit?
This event is called when a character is about to traverse this
exit. You can use the deny() function to deny the character from
using this exit for the time being. The 'character' variable
contains the character who wants to traverse through this exit.
The 'exit' variable contains the exit, the 'room' variable
contains the room in which the character and exit are.
exitting for this time.
Variables you can use in this event:
character: the character that wants to traverse this exit.
exit: the exit to be traversed.
room: the room in which stands the character before moving.
""")
create_event_type(DefaultExit, "traverse", ["character", "exit",
"origin", "destination"], """
@ -64,11 +66,12 @@ create_event_type(DefaultExit, "traverse", ["character", "exit",
exit. Traversing cannot be prevented using 'deny()' at this
point. The character will be in a different room and she will
have received the room's description when this event is called.
The 'character' variable contains the character who has traversed
through this exit. The 'exit' variable contains the exit, the
'origin' variable contains the room in which the character was
before traversing, while 'destination' contains the room in which
the character now is.
Variables you can use in this event:
character: the character who has traversed through this exit.
exit: the exit that was just traversed through.
origin: the exit's location (where the character was before moving).
destination: the character's location after moving.
""")
# Room events
@ -82,7 +85,7 @@ create_event_type(DefaultRoom, "time", ["room"], """
spaces, colons or dashes. Keep it as close from a recognizable
date format, like this:
@event/add here = time 06-15 12:20
This event will fire every year on June 15th at 12 PM (still
This event will fire every year on June the 15th at 12 PM (still
game time). Units have to be specified depending on your set calendar
(ask a developer for more details).