Reworked object command tables.
Object commands used to require re-adding every call in the script parent's __init__ or factory functions, adding the commands to a new command table directly on the object. Since all other attributes can be set up in at_object_creation(), this was both inconsistent and a bit confusing to work with. There is now a method add_commands() directly defined on all objects. It takes the same arguments as the normal add_command()o but use a reserved attribute to create and update a command table on the object. This has the advantange of completely removing the __init__ call in the script parent, all definitions can now be kept in at_object_creation() and are, more importantly, persistent without having to be recreated every call. - I updated the examine command to show all the commands defined on an object (if any). - I updated gamesrc/parents/examples/red_button.py considerably using the new command methodology and also using the updated Events. . Griatch
This commit is contained in:
parent
5f6454ea1e
commit
c7cbc4854e
7 changed files with 252 additions and 53 deletions
|
|
@ -8,41 +8,134 @@ Assuming this script remains in gamesrc/parents/examples, create an object
|
|||
of this type using @create button:examples.red_button
|
||||
|
||||
This file also shows the use of the Event system to make the button
|
||||
send a message to the players at regular intervals. Note that if you create a
|
||||
test button you must drop it before you will see its messages!
|
||||
send a message to the players at regular intervals. To show the use of
|
||||
Events, we are tying two types of events to the red button, one which cause ALL
|
||||
red buttons in the game to blink in sync (gamesrc/events/example.py) and one
|
||||
event which cause the protective glass lid over the button to close
|
||||
again some time after it was opened.
|
||||
|
||||
Note that if you create a test button you must drop it before you can
|
||||
see its messages!
|
||||
"""
|
||||
import traceback
|
||||
from game.gamesrc.parents.base.basicobject import BasicObject
|
||||
from src.objects.models import Object
|
||||
from src.events import IntervalEvent
|
||||
from src import scheduler
|
||||
from src import logger
|
||||
|
||||
# you have to import the event definition(s) from somewhere
|
||||
# covered by @reload, and this is as good a place as any.
|
||||
# Doing this will start the event ticking.
|
||||
|
||||
import game.gamesrc.events.example
|
||||
|
||||
#
|
||||
# commands for using the button object. These are added to
|
||||
# Events
|
||||
#
|
||||
|
||||
# Importing this will start the blink event ticking, only one
|
||||
# blink event is used for all red buttons.
|
||||
import game.gamesrc.events.example
|
||||
|
||||
# We also create an object-specific event.
|
||||
|
||||
class EventCloselid(IntervalEvent):
|
||||
"""
|
||||
This event closes the glass lid over the button
|
||||
some time after it was opened.
|
||||
"""
|
||||
def __init__(self, obj):
|
||||
"""
|
||||
Note how we take an object as an argument,
|
||||
this will allow instances of this event to
|
||||
operate on this object only.
|
||||
"""
|
||||
# we must call super to make sure things work!
|
||||
super(EventCloselid, self).__init__()
|
||||
# store the object reference
|
||||
self.obj_dbref = obj.dbref()
|
||||
# This is used in e.g. @ps to show what the event does
|
||||
self.description = "Close lid on %s" % obj
|
||||
# We make sure that this event survives a reboot
|
||||
self.persistent = True
|
||||
# How many seconds from event creation to closing
|
||||
# the lid
|
||||
self.interval = 20
|
||||
# We only run the event one time before it deletes itself.
|
||||
self.repeats = 1
|
||||
|
||||
def event_function(self):
|
||||
"""
|
||||
This function is called every self.interval seconds.
|
||||
Note that we must make sure to handle all errors from
|
||||
this call to avoid trouble.
|
||||
"""
|
||||
try:
|
||||
# if the lid is open, close it. We have to find the object
|
||||
# again since it might have changed.
|
||||
obj = Object.objects.get_object_from_dbref(self.obj_dbref)
|
||||
if obj.has_flag("LID_OPEN"):
|
||||
obj.scriptlink.close_lid()
|
||||
retval = "The glass cover over the button silently closes by itself."
|
||||
obj.get_location().emit_to_contents(retval)
|
||||
except:
|
||||
# send the traceback to the log instead of letting it by.
|
||||
# It is important that we handle exceptions gracefully here!
|
||||
logger.log_errmsg(traceback.print_exc())
|
||||
|
||||
|
||||
#
|
||||
# Object commands
|
||||
#
|
||||
# Commands for using the button object. These are added to
|
||||
# the object in the class_factory function at the
|
||||
# bottom of this module.
|
||||
#
|
||||
|
||||
def cmd_open_lid(command):
|
||||
"""
|
||||
Open the glass lid cover over the button.
|
||||
"""
|
||||
# In the case of object commands, you can use this to
|
||||
# get the object the command is defined on.
|
||||
obj = command.scripted_obj
|
||||
|
||||
if obj.has_flag("LID_OPEN"):
|
||||
retval = "The lid is already open."
|
||||
else:
|
||||
retval = "You lift the lid, exposing the tempting button."
|
||||
obj.scriptlink.open_lid()
|
||||
command.source_object.emit_to(retval)
|
||||
|
||||
def cmd_close_lid(command):
|
||||
"""
|
||||
Close the lid again.
|
||||
"""
|
||||
obj = command.scripted_obj
|
||||
if not obj.has_flag("LID_OPEN"):
|
||||
retval = "The lid is already open."
|
||||
else:
|
||||
retval = "You secure the glass cover over the button."
|
||||
obj.scriptlink.close_lid()
|
||||
command.source_object.emit_to(retval)
|
||||
|
||||
def cmd_push_button(command):
|
||||
"""
|
||||
|
||||
This is a simple command that handles a user pressing the
|
||||
button by returning a message.
|
||||
button by returning a message. The button can only be
|
||||
"""
|
||||
retval = "There is a loud bang: BOOOM!"
|
||||
command.source_object.emit_to(retval)
|
||||
|
||||
def cmd_pull_button(command):
|
||||
"""
|
||||
An example of a second defined command (for those who
|
||||
don't know how a button works ... ;) )
|
||||
"""
|
||||
retval = "A button is meant to be pushed, not pulled!"
|
||||
obj = command.scripted_obj
|
||||
|
||||
if obj.has_flag("LID_OPEN"):
|
||||
retval = "You press the button ..."
|
||||
retval += "\n ..."
|
||||
retval += "\n BOOOOOM!"
|
||||
obj.scriptlink.close_lid()
|
||||
else:
|
||||
retval = "There is a glass lid covering "
|
||||
retval += "the button as a safety measure. If you "
|
||||
retval += "want to press the button you need to open "
|
||||
retval += "the lid first."
|
||||
command.source_object.emit_to(retval)
|
||||
|
||||
|
||||
#
|
||||
# Definition of the object itself
|
||||
#
|
||||
|
|
@ -53,7 +146,8 @@ class RedButton(BasicObject):
|
|||
It will use the event definition in
|
||||
game/gamesrc/events/example.py to blink
|
||||
at regular intervals until the lightbulb
|
||||
breaks.
|
||||
breaks. It also use the EventCloselid event defined
|
||||
above to close the lid
|
||||
"""
|
||||
def at_object_creation(self):
|
||||
"""
|
||||
|
|
@ -63,10 +157,31 @@ class RedButton(BasicObject):
|
|||
#get stored object related to this class
|
||||
obj = self.scripted_obj
|
||||
|
||||
obj.set_attribute('desc', "This is your standard big red button.")
|
||||
obj.set_attribute("breakpoint", 10)
|
||||
obj.set_attribute('desc', "This is a big red button. It has a glass cover.")
|
||||
obj.set_attribute("breakpoint", 5)
|
||||
obj.set_attribute("count", 0)
|
||||
|
||||
# add the object-based commands to the button
|
||||
obj.add_command("open lid", cmd_open_lid)
|
||||
obj.add_command("lift lid", cmd_open_lid)
|
||||
obj.add_command("close lid", cmd_close_lid)
|
||||
obj.add_command("push button", cmd_push_button)
|
||||
obj.add_command("push the button", cmd_push_button)
|
||||
|
||||
def open_lid(self):
|
||||
"""
|
||||
Open the glass lid and start the timer so it will
|
||||
soon close again.
|
||||
"""
|
||||
self.scripted_obj.set_flag("LID_OPEN")
|
||||
scheduler.add_event(EventCloselid(self.scripted_obj))
|
||||
|
||||
def close_lid(self):
|
||||
"""
|
||||
Close the glass lid
|
||||
"""
|
||||
self.scripted_obj.unset_flag("LID_OPEN")
|
||||
|
||||
def blink(self):
|
||||
"""
|
||||
If the event system is active, it will regularly call this
|
||||
|
|
@ -102,8 +217,4 @@ def class_factory(source_obj):
|
|||
This is a good place for adding new commands to the button since this is
|
||||
where it is actually instantiated.
|
||||
"""
|
||||
button = RedButton(source_obj)
|
||||
# add the object-based commands to the button
|
||||
button.command_table.add_command("push button", cmd_push_button)
|
||||
button.command_table.add_command("pull button", cmd_pull_button)
|
||||
return button
|
||||
return RedButton(source_obj)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue