From 81f4c590bddb95da708490b9bbc8f79e763c78c9 Mon Sep 17 00:00:00 2001 From: Vincent Le Goff Date: Mon, 20 Mar 2017 12:29:04 -0700 Subject: [PATCH] Bring the event system to Evennia-style compliance --- evennia/contrib/events/commands.py | 157 ++++++++++++-------------- evennia/contrib/events/custom.py | 68 ++++------- evennia/contrib/events/helpers.py | 10 +- evennia/contrib/events/scripts.py | 85 +++++++++----- evennia/contrib/events/typeclasses.py | 25 ++-- 5 files changed, 174 insertions(+), 171 deletions(-) diff --git a/evennia/contrib/events/commands.py b/evennia/contrib/events/commands.py index 7ec59983e5..9335af5b19 100644 --- a/evennia/contrib/events/commands.py +++ b/evennia/contrib/events/commands.py @@ -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 [= ]", + "@event/add = [parameters]", + "@event/edit = [event number]", + "@event/del = [event number]", + "@event/tasks [object 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 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)) diff --git a/evennia/contrib/events/custom.py b/evennia/contrib/events/custom.py index 8c0c41a376..7c35c5b2ea 100644 --- a/evennia/contrib/events/custom.py +++ b/evennia/contrib/events/custom.py @@ -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. diff --git a/evennia/contrib/events/helpers.py b/evennia/contrib/events/helpers.py index 5d4badde7a..6675e3ded4 100644 --- a/evennia/contrib/events/helpers.py +++ b/evennia/contrib/events/helpers.py @@ -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: diff --git a/evennia/contrib/events/scripts.py b/evennia/contrib/events/scripts.py index d271a0184f..d0abdc1dc2 100644 --- a/evennia/contrib/events/scripts.py +++ b/evennia/contrib/events/scripts.py @@ -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: diff --git a/evennia/contrib/events/typeclasses.py b/evennia/contrib/events/typeclasses.py index ebe55cb337..191d66f641 100644 --- a/evennia/contrib/events/typeclasses.py +++ b/evennia/contrib/events/typeclasses.py @@ -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).