Add events on exits

This commit is contained in:
Vincent Le Goff 2017-03-26 13:00:42 -07:00 committed by Griatch
parent 9c091b29e9
commit c996e8c4b5
4 changed files with 191 additions and 6 deletions

View file

@ -287,7 +287,7 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
definition = types.get(event_name, (None, "Chain event"))
description = definition[1]
self.msg(description)
self.msg(raw(description))
# Open the editor
event = self.handler.add_event(obj, event_name, "",
@ -356,7 +356,7 @@ class CmdEvent(COMMAND_DEFAULT_CLASS):
# Check the definition of the event
definition = types.get(event_name, (None, "Chained event"))
description = definition[1]
self.msg(description)
self.msg(raw(description))
# Open the editor
event = dict(event)

View file

@ -60,6 +60,23 @@ class EventsHandler(object):
"""
return self.all().get(event_name, [])
def get_variable(self, variable_name):
"""
Return the variable value or None.
Args:
variable_name (str): the name of the variable.
Returns:
Either the variable's value or None.
"""
handler = type(self).script
if handler:
return handler.get_variable(variable_name)
return None
def add(self, event_name, code, author=None, valid=False, parameters=""):
"""
Add a new event for this object.

View file

@ -132,6 +132,31 @@ class EventHandler(DefaultScript):
return types
def get_variable(self, variable_name):
"""
Return the variable defined in the locals.
This can be very useful to check the value of a variable that can be modified in an event, and whose value will be used in code. This system allows additional customization.
Args:
variable_name (str): the name of the variable to return.
Returns:
The variable if found in the locals.
None if not found in the locals.
Note:
This will return the variable from the current locals.
Keep in mind that locals are shared between events. As
every event is called one by one, this doesn't pose
additional problems if you get the variable right after
an event has been executed. If, however, you differ,
there's no guarantee the variable will be here or will
mean the same thing.
"""
return self.ndb.current_locals.get(variable_name)
def add_event(self, obj, event_name, code, author=None, valid=False,
parameters=""):
"""

View file

@ -9,6 +9,105 @@ from evennia.contrib.events.custom import (
create_event_type, patch_hook, create_time_event)
from evennia.contrib.events.handler import EventsHandler
class PatchedCharacter:
"""Patched typeclass for DefaultCharcter."""
@staticmethod
@patch_hook(DefaultCharacter, "announce_move_from")
def announce_move_from(character, destination, msg=None, hook=None):
"""
Called if the move is to be announced. This is
called while we are still standing in the old
location. Customizing the message through events is possible.
Args:
destination (Object): The place we are going to.
msg (optional): a custom message to replace the default one.
"""
if not character.location:
return
if msg:
string = msg
else:
string = "{character} is leaving {origin}, heading for {destination}."
# Get the exit from location to destination
location = character.location
exits = [o for o in location.contents if o.location is location and o.destination is destination]
if exits:
exits[0].events.call("msg_leave", character, exits[0],
location, destination, string)
string = exits[0].events.get_variable("message")
mapping = {
"character": character,
"exit": exits[0] if exits else "somewhere",
"origin": location or "nowhere",
"destination": destination or "nowhere",
}
# If there's no string, don't display anything
# It can happen if the "message" variable in events is set to None
if not string:
return
location.msg_contents(string, exclude=(character, ), mapping=mapping)
@staticmethod
@patch_hook(DefaultCharacter, "announce_move_to")
def announce_move_to(character, source_location, msg=None, hook=None):
"""
Called after the move if the move was not quiet. At this point
we are standing in the new location.
Args:
source_location (Object): The place we came from
msg (str, optional): the default message to be displayed.
"""
if not source_location and character.location.has_player:
# This was created from nowhere and added to a player's
# inventory; it's probably the result of a create command.
string = "You now have %s in your possession." % self.get_display_name(self.location)
character.location.msg(string)
return
if source_location:
if msg:
string = msg
else:
string = "{character} arrives to {destination} from {origin}."
else:
string = "{character} arrives to {destination}."
origin = source_location
destination = character.location
if origin:
exits = [o for o in destination.contents if o.location is destination and o.destination is origin]
if exits:
exits[0].events.call("msg_arrive", character, exits[0],
origin, destination, string)
string = exits[0].events.get_variable("message")
mapping = {
"character": character,
"exit": exits[0] if exits else "somewhere",
"origin": origin or "nowhere",
"destination": destination or "nowhere",
}
# If there's no string, don't display anything
# It can happen if the "message" variable in events is set to None
if not string:
return
destination.msg_contents(string, exclude=(character, ), mapping=mapping)
class PatchedObject(object):
@lazy_property
def events(self):
@ -37,9 +136,8 @@ class PatchedExit(object):
"""
is_character = inherits_from(traversing_object, DefaultCharacter)
script = ScriptDB.objects.get(db_key="event_handler")
if is_character:
allow = script.call_event(exit, "can_traverse", traversing_object,
allow = exit.events.call("can_traverse", traversing_object,
exit, exit.location)
if not allow:
return
@ -48,7 +146,7 @@ class PatchedExit(object):
# After traversing
if is_character:
script.call_event(exit, "traverse", traversing_object,
exit.events.call("traverse", traversing_object,
exit, exit.location, exit.destination)
@ -66,6 +164,51 @@ create_event_type(DefaultExit, "can_traverse", ["character", "exit", "room"],
exit: the exit to be traversed.
room: the room in which stands the character before moving.
""")
create_event_type(DefaultExit, "msg_arrive", ["character", "exit",
"origin", "destination", "message"], """
Customize the message when a character arrives through this exit.
This event is called when a character arrives through this exit.
To customize the message that will be sent to the room where the
character arrives, change the value of the variable "message"
to give it your custom message. The character itself will not be
notified. You can use mapping between braces, like this:
message = "{character} climbs out of a hole."
In your mapping, you can use {character} (the character who has
arrived), {exit} (the exit), {origin} (the room in which
the character was), and {destination} (the room in which the character
now is). If you need to customize the message with other information,
you can also set "message" to None and send something else instead.
Variables you can use in this event:
character: the character who is arriving through this exit.
exit: the exit having been traversed.
origin: the past location of the character.
destination: the current location of the character.
message: the message to be displayed in the destination.
""")
create_event_type(DefaultExit, "msg_leave", ["character", "exit",
"origin", "destination", "message"], """
Customize the message when a character leaves through this exit.
This event is called when a character leaves through this exit.
To customize the message that will be sent to the room where the
character came from, change the value of the variable "message"
to give it your custom message. The character itself will not be
notified. You can use mapping between braces, like this:
message = "{character} falls into a hole!"
In your mapping, you can use {character} (the character who is
about to leave), {exit} (the exit), {origin} (the room in which
the character is), and {destination} (the room in which the character
is heading for). If you need to customize the message with other
information, you can also set "message" to None and send something
else instead.
Variables you can use in this event:
character: the character who is leaving through this exit.
exit: the exit being traversed.
origin: the location of the character.
destination: the destination of the character.
message: the message to be displayed in the location.
""")
create_event_type(DefaultExit, "traverse", ["character", "exit",
"origin", "destination"], """
After the characer has traversed through this exit.
@ -98,4 +241,4 @@ create_event_type(DefaultRoom, "time", ["room"], """
Variables you can use in this event:
room: the room connected to this event.
""", create_time_event)
""", create_time_event)