Fixed a bunch of small issues. The RedButton example hasn't been working for a while, should be ok again now - also cleaned it up a bit.

This commit is contained in:
Griatch 2011-06-24 20:12:59 +00:00
parent 1d93d8295f
commit 334c0b1d08
10 changed files with 87 additions and 94 deletions

View file

@ -10,8 +10,6 @@ cmdset - this way you can often re-use the commands too.
import random import random
from src.commands.cmdset import CmdSet from src.commands.cmdset import CmdSet
from game.gamesrc.commands.basecommand import Command from game.gamesrc.commands.basecommand import Command
from game.gamesrc.scripts.examples import red_button_scripts as scriptexamples
# Some simple commands for the red button # Some simple commands for the red button
@ -70,24 +68,20 @@ class CmdPush(Command):
""" """
if self.obj.db.lid_open: if self.obj.db.lid_open:
# assign the blind state script to the caller.
# this will assign the restricted BlindCmdset to
# the caller at startup, and remove it again
# once the time has run out
self.caller.scripts.add(scriptexamples.BlindedState)
string = "You reach out to press the big red button ..." string = "You reach out to press the big red button ..."
string += "\n\nA BOOM! A bright light blinds you!" string += "\n\nA BOOM! A bright light blinds you!"
string += "\nThe world goes dark ..." string += "\nThe world goes dark ..."
self.caller.msg(string) self.caller.msg(string)
self.caller.location.msg_contents("%s presses the button. BOOM! %s is blinded by a flash!" % self.caller.location.msg_contents("%s presses the button. BOOM! %s is blinded by a flash!" %
(self.caller.name, self.caller.name), exclude=self.caller) (self.caller.name, self.caller.name), exclude=self.caller)
# the button's method will handle all setup of scripts etc.
self.obj.press_button(self.caller)
else: else:
string = "You cannot push the button - there is a glass lid covering it." string = "You cannot push the button - there is a glass lid covering it."
self.caller.msg(string) self.caller.msg(string)
class CmdSmashGlass(Command): class CmdSmashGlass(Command):
""" """
smash glass smash glass
@ -142,22 +136,15 @@ class CmdOpenLid(Command):
if self.obj.db.lid_locked: if self.obj.db.lid_locked:
self.caller.msg("This lid seems locked in place for the moment.") self.caller.msg("This lid seems locked in place for the moment.")
return return
string += "\nA ticking sound is heard, like a winding mechanism. Seems "
string = "\nA ticking sound is heard, like a winding mechanism. Seems "
string += "the lid will soon close again." string += "the lid will soon close again."
self.db.lid_open = False
# add the relevant cmdsets to button
self.obj.cmdset.add(LidClosedCmdsSet)
# add the lid-close ticker script
self.obj.scripts.add(scriptexamples.LidCloseTimer)
# add more info to the button description
desc = self.obj.db.closed_desc
self.obj.db.temp_desc = desc
self.obj.db.desc = "%s\n%s" % (desc, "Its glass cover is open and the button exposed.")
self.caller.msg(string) self.caller.msg(string)
self.caller.location.msg_contents("%s opens the lid of the button." % self.caller.location.msg_contents("%s opens the lid of the button." %
(self.caller.name), exclude=self.caller) (self.caller.name), exclude=self.caller)
# add the relevant cmdsets to button
self.obj.cmdset.add(LidClosedCmdSet)
# call object method
self.obj.open_lid() self.obj.open_lid()
class CmdCloseLid(Command): class CmdCloseLid(Command):
@ -176,12 +163,9 @@ class CmdCloseLid(Command):
def func(self): def func(self):
"Close the lid" "Close the lid"
if self.db.closed_desc: self.obj.close_lid()
self.obj.desc = self.db.closed_desc
self.obj.db.lid_open = False
# this will clean out scripts dependent on lid being open. # this will clean out scripts dependent on lid being open.
self.obj.scripts.validate()
self.caller.msg("You close the button's lid. It clicks back into place.") self.caller.msg("You close the button's lid. It clicks back into place.")
self.caller.location.msg_contents("%s closes the button's lid." % self.caller.location.msg_contents("%s closes the button's lid." %
(self.caller.name), exclude=self.caller) (self.caller.name), exclude=self.caller)
@ -313,8 +297,8 @@ class BlindCmdSet(CmdSet):
def at_cmdset_creation(self): def at_cmdset_creation(self):
"Setup the blind cmdset" "Setup the blind cmdset"
from game.gamesrc.commands.default.general import CmdSay from src.commands.default.general import CmdSay
from game.gamesrc.commands.default.general import CmdPose from src.commands.default.general import CmdPose
self.add(CmdSay()) self.add(CmdSay())
self.add(CmdPose()) self.add(CmdPose())
self.add(CmdBlindLook()) self.add(CmdBlindLook())

View file

@ -25,6 +25,12 @@ class RedButton(Object):
definition in game/gamesrc/events/example.py to blink at regular definition in game/gamesrc/events/example.py to blink at regular
intervals. It also uses a series of script and commands to handle intervals. It also uses a series of script and commands to handle
pushing the button and causing effects when doing so. pushing the button and causing effects when doing so.
The following attributes can be set on the button:
desc_lid_open - description when lid is open
desc_lid_closed - description when lid is closed
desc_lamp_broken - description when lamp is broken
""" """
def at_object_creation(self): def at_object_creation(self):
""" """
@ -43,11 +49,9 @@ class RedButton(Object):
self.db.lamp_works = True self.db.lamp_works = True
self.db.lid_locked = False self.db.lid_locked = False
# set the default cmdset to the object. This will by default surivive self.cmdset.add_default(cmdsetexamples.DefaultCmdSet, permanent=True)
# a server reboot (otherwise we could have used permanent=False).
self.cmdset.add_default(cmdsetexamples.DefaultCmdSet)
# since the other cmdsets relevant to the button are added 'on the fly', # since the cmdsets relevant to the button are added 'on the fly',
# we need to setup custom scripts to do this for us (also, these scripts # we need to setup custom scripts to do this for us (also, these scripts
# check so they are valid (i.e. the lid is actually still closed)). # check so they are valid (i.e. the lid is actually still closed)).
# The AddClosedCmdSet script makes sure to add the Closed-cmdset. # The AddClosedCmdSet script makes sure to add the Closed-cmdset.
@ -57,7 +61,7 @@ class RedButton(Object):
# state-changing methods # state-changing methods
def open_lid(self, feedback=True): def open_lid(self):
""" """
Opens the glass lid and start the timer so it will soon close Opens the glass lid and start the timer so it will soon close
again. again.
@ -65,18 +69,13 @@ class RedButton(Object):
if self.db.lid_open: if self.db.lid_open:
return return
desc = self.db.desc_lid_open
desc = "This is a large red button, inviting yet evil-looking. " if not desc:
desc += "Its glass cover is open and the button exposed." desc = "This is a large red button, inviting yet evil-looking. "
desc += "Its glass cover is open and the button exposed."
self.db.desc = desc self.db.desc = desc
self.db.lid_open = True self.db.lid_open = True
if feedback and self.location:
string = "The lid slides clear of the button with a click."
string += "\nA ticking sound is heard, suggesting the lid might have"
string += " some sort of timed locking mechanism."
self.location.msg_contents(string)
# with the lid open, we validate scripts; this will clean out # with the lid open, we validate scripts; this will clean out
# scripts that depend on the lid to be closed. # scripts that depend on the lid to be closed.
self.scripts.validate() self.scripts.validate()
@ -86,7 +85,7 @@ class RedButton(Object):
# (this one cleans itself after being called once) # (this one cleans itself after being called once)
self.scripts.add(scriptexamples.CloseLidEvent) self.scripts.add(scriptexamples.CloseLidEvent)
def close_lid(self, feedback=True): def close_lid(self):
""" """
Close the glass lid. This validates all scripts on the button, Close the glass lid. This validates all scripts on the button,
which means that scripts only being valid when the lid is open which means that scripts only being valid when the lid is open
@ -95,16 +94,13 @@ class RedButton(Object):
if not self.db.lid_open: if not self.db.lid_open:
return return
desc = self.db.desc_lid_closed
desc = "This is a large red button, inviting yet evil-looking. " if not desc:
desc += "Its glass cover is closed, protecting it." desc = "This is a large red button, inviting yet evil-looking. "
desc += "Its glass cover is closed, protecting it."
self.db.desc = desc self.db.desc = desc
self.db.lid_open = False self.db.lid_open = False
if feedback and self.location:
string = "With a click the lid slides back, securing the button once again."
self.location.msg_contents(string)
# clean out scripts depending on lid to be open # clean out scripts depending on lid to be open
self.scripts.validate() self.scripts.validate()
# add scripts related to the closed state # add scripts related to the closed state
@ -116,11 +112,14 @@ class RedButton(Object):
""" """
self.db.lamp_works = False self.db.lamp_works = False
self.db.desc = "The big red button has stopped blinking for the time being." desc = self.db.desc_lamp_broken
if not desc:
self.db.desc += "\nThe big red button has stopped blinking for the time being."
else:
self.db.desc = desc
if feedback and self.location: if feedback and self.location:
string = "The lamp flickers, the button going dark." self.location.msg_contents("The lamp flickers, the button going dark.")
self.location.msg_contents(string)
self.scripts.validate() self.scripts.validate()
def press_button(self, pobject): def press_button(self, pobject):

View file

@ -251,7 +251,7 @@ class DeactivateButtonEvent(Script):
(that just controls when at_repeat() is called) (that just controls when at_repeat() is called)
""" """
# closing the lid will also add the ClosedState script # closing the lid will also add the ClosedState script
self.obj.close_lid(feedback=False) self.obj.close_lid()
# lock the lid so other players can't access it until the # lock the lid so other players can't access it until the
# first one's effect has worn off. # first one's effect has worn off.
self.obj.db.lid_locked = True self.obj.db.lid_locked = True

View file

@ -278,13 +278,11 @@ class CmdSetHandler(object):
def add_default(self, cmdset, emit_to_obj=None, permanent=True): def add_default(self, cmdset, emit_to_obj=None, permanent=True):
""" """
Add a new default cmdset. If an old default existed, Add a new default cmdset. If an old default existed,
it is replaced. If permanent is set, a script will be created to it is replaced. If permanent is set, the set will survive a reboot.
add the cmdset to the object.
cmdset - can be a cmdset object or the python path to cmdset - can be a cmdset object or the python path to
an instance of such an object. an instance of such an object.
emit_to_obj - an object to receive error messages. emit_to_obj - an object to receive error messages.
permanent - create a script that assigns this script every permanent - save cmdset across reboots
startup/login.
See also the notes for self.add(), which applies here too. See also the notes for self.add(), which applies here too.
""" """
if callable(cmdset): if callable(cmdset):

View file

@ -181,7 +181,7 @@ class CmdBatchCommands(MuxCommand):
Build from batch-command file Build from batch-command file
Usage: Usage:
@batchcommands[/interactive] <python path to file> @batchcommands[/interactive] <python.path.to.file>
Switch: Switch:
interactive - this mode will offer more control when interactive - this mode will offer more control when

View file

@ -361,7 +361,8 @@ def holds(accessing_obj, accessed_obj, objid, *args, **kwargs):
if dbref and any((True for obj in contains if obj.id == dbref)): if dbref and any((True for obj in contains if obj.id == dbref)):
return True return True
objid = objid.lower() objid = objid.lower()
return any((True for obj in contains if obj.name.lower() == objid)) return any((True for obj in contains
if obj.name.lower() == objid or objid in [al.lower() for al in obj.aliases]))
def carried(accessing_obj, accessed_obj): def carried(accessing_obj, accessed_obj):
""" """
@ -379,8 +380,8 @@ def objcarried(accessing_obj, accessed_obj):
objcarried() objcarried()
Like carried, except this lock looks for a property "obj" on the accessed_obj Like carried, except this lock looks for a property "obj" on the accessed_obj
and tries to determing if *this* is carried by accessing_obj. This works well and tries to determine if *this* is carried by accessing_obj. This works well
for commands and scripts. for accessing commands and scripts.
""" """
return hasattr(accessed_obj, "obj") and accessed_obj.obj and \ return hasattr(accessed_obj, "obj") and accessed_obj.obj and \
hasattr(accessed_obj.obj, "location") and accessed_obj.obj.location == accessing_obj hasattr(accessed_obj.obj, "location") and accessed_obj.obj.location == accessing_obj

View file

@ -175,9 +175,9 @@ CMDSET_OOC = "game.gamesrc.commands.basecmdset.OOCCmdSet"
# Base paths for typeclassed object classes. These paths must be # Base paths for typeclassed object classes. These paths must be
# defined relative evennia's root directory. They will be searched in # defined relative evennia's root directory. They will be searched in
# order to find relative typeclass paths. # order to find relative typeclass paths.
OBJECT_TYPECLASS_PATHS = ["game.gamesrc.objects", "game.gamesrc.objects.examples"] OBJECT_TYPECLASS_PATHS = ["game.gamesrc.objects", "game.gamesrc.objects.examples", "contrib"]
SCRIPT_TYPECLASS_PATHS = ["game.gamesrc.scripts", "game.gamesrc.scripts.examples"] SCRIPT_TYPECLASS_PATHS = ["game.gamesrc.scripts", "game.gamesrc.scripts.examples", "contrib"]
PLAYER_TYPECLASS_PATHS = ["game.gamesrc.objects"] PLAYER_TYPECLASS_PATHS = ["game.gamesrc.objects", "contrib"]
# Typeclass for player objects (linked to a character) (fallback) # Typeclass for player objects (linked to a character) (fallback)
BASE_PLAYER_TYPECLASS = "game.gamesrc.objects.baseobjects.Player" BASE_PLAYER_TYPECLASS = "game.gamesrc.objects.baseobjects.Player"
@ -196,7 +196,7 @@ BASE_EXIT_TYPECLASS = "game.gamesrc.objects.baseobjects.Exit"
# Python path to a directory to be searched for batch scripts # Python path to a directory to be searched for batch scripts
# for the batch processors (.ev and/or .py files). # for the batch processors (.ev and/or .py files).
BASE_BATCHPROCESS_PATH = 'game.gamesrc.world' BASE_BATCHPROCESS_PATHS = ['game.gamesrc.world', 'contrib']
################################################### ###################################################
# Game Time setup # Game Time setup

View file

@ -22,6 +22,7 @@ these to create custom managers.
""" """
import sys
try: try:
import cPickle as pickle import cPickle as pickle
except ImportError: except ImportError:
@ -664,6 +665,7 @@ class TypedObject(SharedMemoryModel):
typeclass = object.__getattribute__(self, "_path_import")(tpath) typeclass = object.__getattribute__(self, "_path_import")(tpath)
if callable(typeclass): if callable(typeclass):
# don't return yet, we must cache this further down. # don't return yet, we must cache this further down.
errstring = ""
break break
elif hasattr(typeclass, '__file__'): elif hasattr(typeclass, '__file__'):
errstring += "\n%s seems to be just the path to a module. You need" % tpath errstring += "\n%s seems to be just the path to a module. You need" % tpath
@ -674,7 +676,7 @@ class TypedObject(SharedMemoryModel):
if not callable(typeclass): if not callable(typeclass):
# Still not a valid import. Fallback to default. # Still not a valid import. Fallback to default.
defpath = object.__getattribute__(self, "default_typeclass_path") defpath = object.__getattribute__(self, "default_typeclass_path")
errstring += " Using Default class '%s'." % defpath errstring += "\n\nUsing Default class '%s'." % defpath
self.db_typeclass_path = defpath self.db_typeclass_path = defpath
self.save() self.save()
logger.log_errmsg(errstring) logger.log_errmsg(errstring)
@ -718,14 +720,20 @@ class TypedObject(SharedMemoryModel):
module = __import__(modpath, fromlist=[class_name]) module = __import__(modpath, fromlist=[class_name])
return module.__dict__[class_name] return module.__dict__[class_name]
except ImportError: except ImportError:
trc = traceback.format_exc() trc = sys.exc_traceback
errstring = "\n%s\nError importing '%s'." % (trc, path) if not trc.tb_next:
# we separate between not finding the module, and finding a buggy one.
errstring += "(Tried path '%s')." % path
else:
# a bug in the module is reported normally.
trc = traceback.format_exc()
errstring += "\n%sError importing '%s'." % (trc, path)
except KeyError: except KeyError:
errstring = "No class '%s' was found in module '%s'." errstring = "No class '%s' was found in module '%s'."
errstring = errstring % (class_name, modpath) errstring = errstring % (class_name, modpath)
except Exception: except Exception:
trc = traceback.format_exc() trc = traceback.format_exc()
errstring = "\n%s\nImporting '%s' failed." % (trc, path) errstring = "\n%sException importing '%s'." % (trc, path)
# return the error. # return the error.
return errstring return errstring

View file

@ -163,29 +163,30 @@ def read_batchfile(pythonpath, file_ending='.py'):
""" """
# open the file # open the file
if pythonpath and not (pythonpath.startswith('src.') or pythonpath.startswith('game.')):
if pythonpath and not (pythonpath.startswith('src.') or abspaths = []
pythonpath.startswith('game.')): for basepath in settings.BASE_BATCHPROCESS_PATHS:
pythonpath = "%s.%s" % (settings.BASE_BATCHPROCESS_PATH, abspaths.append(utils.pypath_to_realpath("%s.%s" % (basepath, pythonpath), file_ending))
pythonpath) else:
abspath = utils.pypath_to_realpath(pythonpath, file_ending) abspaths = [pythonpath]
fobj = None
for file_encoding in ENCODINGS: for file_encoding in ENCODINGS:
# try different encodings, in order # try different encodings, in order
err = None load_errors = []
try: for abspath in abspaths:
# we read the file directly into unicode. # try different paths, until we get a match
fobj = codecs.open(abspath, 'r', encoding=file_encoding)
except IOError:
# try again without the appended file ending
abspath2 = utils.pypath_to_realpath(pythonpath, None)
try: try:
# we read the file directly into unicode.
fobj = codecs.open(abspath, 'r', encoding=file_encoding) fobj = codecs.open(abspath, 'r', encoding=file_encoding)
except IOError: except IOError:
string = "Could not open batchfile '%s', nor '%s'." load_errors.append("Could not open batchfile '%s'." % abspath)
logger.log_errmsg(string % (abspath2, abspath)) continue
return None break
if not fobj:
continue
load_errors = []
err =None
# We have successfully found and opened the file. Now actually # We have successfully found and opened the file. Now actually
# try to decode it using the given protocol. # try to decode it using the given protocol.
try: try:
@ -208,6 +209,8 @@ def read_batchfile(pythonpath, file_ending='.py'):
continue continue
# if we get here, the encoding worked. Stop iteration. # if we get here, the encoding worked. Stop iteration.
break break
if load_errors:
logger.log_errmsg("\n".join(load_errors))
if err: if err:
return err return err
else: else:

View file

@ -104,8 +104,8 @@ def reload_modules():
if unsafe_dir_modified or unsafe_mod_modified: if unsafe_dir_modified or unsafe_mod_modified:
if unsafe_mod_modified: if unsafe_mod_modified:
string += "\n {rModules containing Script classes with a timer component" string += "\n {rModules containing Script classes with a timer component{n"
string += "\n and which has already spawned instances cannot be reloaded safely.{n" string += "\n {rand which has already spawned instances cannot be reloaded safely.{n"
string += "\n {rThese module(s) can only be reloaded by server reboot:{n\n %s\n" string += "\n {rThese module(s) can only be reloaded by server reboot:{n\n %s\n"
string = string % ", ".join(unsafe_dir_modified + unsafe_mod_modified) string = string % ", ".join(unsafe_dir_modified + unsafe_mod_modified)