mirror of
https://github.com/evennia/evennia.git
synced 2026-03-30 12:37:16 +02:00
Reworked Evennia now passes the unit tests
This commit is contained in:
parent
d0ef05202d
commit
515ce71d65
9 changed files with 17 additions and 14 deletions
0
contrib/tutorial_examples/__init__.py
Normal file
0
contrib/tutorial_examples/__init__.py
Normal file
56
contrib/tutorial_examples/batch_cmds.ev
Normal file
56
contrib/tutorial_examples/batch_cmds.ev
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#
|
||||
# This is an example batch build file for Evennia.
|
||||
#
|
||||
# It allows batch processing of normal Evennia commands.
|
||||
# Test it by loading it with the @batchprocess command
|
||||
#
|
||||
# @batchprocess[/interactive] examples.batch_example
|
||||
#
|
||||
# A # as the first symbol on a line begins a comment and
|
||||
# marks the end of a previous command definition (important!).
|
||||
#
|
||||
# All supplied commands are given as normal, on their own line
|
||||
# and accepts arguments in any format up until the first next
|
||||
# comment line begins. Extra whitespace is removed; an empty
|
||||
# line in a command definition translates into a newline.
|
||||
#
|
||||
|
||||
# This creates a red button
|
||||
|
||||
@create button:tutorial_examples.red_button.RedButton
|
||||
|
||||
# This comment ends input for @create
|
||||
# Next command:
|
||||
|
||||
@set button/desc =
|
||||
This is a large red button. Now and then
|
||||
it flashes in an evil, yet strangely tantalizing way.
|
||||
|
||||
A big sign sits next to it. It says:
|
||||
|
||||
|
||||
-----------
|
||||
|
||||
Press me!
|
||||
|
||||
-----------
|
||||
|
||||
|
||||
... It really begs to be pressed, doesn't it? You
|
||||
know you want to!
|
||||
|
||||
# This ends the @set command. Note that line breaks and extra spaces
|
||||
# in the argument are not considered. A completely empty line
|
||||
# translates to a \n newline in the command; two empty lines will thus
|
||||
# create a new paragraph. (note that few commands support it though, you
|
||||
# mainly want to use it for descriptions)
|
||||
|
||||
# Now let's place the button where it belongs (let's say limbo #2 is
|
||||
# the evil lair in our example)
|
||||
|
||||
@teleport #2
|
||||
|
||||
#... and drop it (remember, this comment ends input to @teleport, so don't
|
||||
#forget it!) The very last command in the file need not be ended with #.
|
||||
|
||||
drop button
|
||||
320
contrib/tutorial_examples/cmdset_red_button.py
Normal file
320
contrib/tutorial_examples/cmdset_red_button.py
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
"""
|
||||
This defines the cmdset for the red_button. Here we have defined
|
||||
the commands and the cmdset in the same module, but if you
|
||||
have many different commands to merge it is often better
|
||||
to define the cmdset separately, picking and choosing from
|
||||
among the available commands as to what should be included in the
|
||||
cmdset - this way you can often re-use the commands too.
|
||||
"""
|
||||
|
||||
import random
|
||||
from evennia import Command, CmdSet
|
||||
|
||||
# Some simple commands for the red button
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Commands defined on the red button
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class CmdNudge(Command):
|
||||
"""
|
||||
Try to nudge the button's lid
|
||||
|
||||
Usage:
|
||||
nudge lid
|
||||
|
||||
This command will have you try to
|
||||
push the lid of the button away.
|
||||
"""
|
||||
|
||||
key = "nudge lid" # two-word command name!
|
||||
aliases = ["nudge"]
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
nudge the lid. Random chance of success to open it.
|
||||
"""
|
||||
rand = random.random()
|
||||
if rand < 0.5:
|
||||
self.caller.msg("You nudge at the lid. It seems stuck.")
|
||||
elif 0.5 <= rand < 0.7:
|
||||
self.caller.msg("You move the lid back and forth. It won't budge.")
|
||||
else:
|
||||
self.caller.msg("You manage to get a nail under the lid.")
|
||||
self.caller.execute_cmd("open lid")
|
||||
|
||||
|
||||
class CmdPush(Command):
|
||||
"""
|
||||
Push the red button
|
||||
|
||||
Usage:
|
||||
push button
|
||||
|
||||
"""
|
||||
key = "push button"
|
||||
aliases = ["push", "press button", "press"]
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
Note that we choose to implement this with checking for
|
||||
if the lid is open/closed. This is because this command
|
||||
is likely to be tried regardless of the state of the lid.
|
||||
|
||||
An alternative would be to make two versions of this command
|
||||
and tuck them into the cmdset linked to the Open and Closed
|
||||
lid-state respectively.
|
||||
|
||||
"""
|
||||
|
||||
if self.obj.db.lid_open:
|
||||
string = "You reach out to press the big red button ..."
|
||||
string += "\n\nA BOOM! A bright light blinds you!"
|
||||
string += "\nThe world goes dark ..."
|
||||
self.caller.msg(string)
|
||||
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)
|
||||
# the button's method will handle all setup of scripts etc.
|
||||
self.obj.press_button(self.caller)
|
||||
else:
|
||||
string = "You cannot push the button - there is a glass lid covering it."
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
class CmdSmashGlass(Command):
|
||||
"""
|
||||
smash glass
|
||||
|
||||
Usage:
|
||||
smash glass
|
||||
|
||||
Try to smash the glass of the button.
|
||||
"""
|
||||
|
||||
key = "smash glass"
|
||||
aliases = ["smash lid", "break lid", "smash"]
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
The lid won't open, but there is a small chance
|
||||
of causing the lamp to break.
|
||||
"""
|
||||
rand = random.random()
|
||||
|
||||
if rand < 0.2:
|
||||
string = "You smash your hand against the glass"
|
||||
string += " with all your might. The lid won't budge"
|
||||
string += " but you cause quite the tremor through the button's mount."
|
||||
string += "\nIt looks like the button's lamp stopped working for the time being."
|
||||
self.obj.lamp_works = False
|
||||
elif rand < 0.6:
|
||||
string = "You hit the lid hard. It doesn't move an inch."
|
||||
else:
|
||||
string = "You place a well-aimed fist against the glass of the lid."
|
||||
string += " Unfortunately all you get is a pain in your hand. Maybe"
|
||||
string += " you should just try to open the lid instead?"
|
||||
self.caller.msg(string)
|
||||
self.caller.location.msg_contents("%s tries to smash the glass of the button." %
|
||||
(self.caller.name), exclude=self.caller)
|
||||
|
||||
|
||||
class CmdOpenLid(Command):
|
||||
"""
|
||||
open lid
|
||||
|
||||
Usage:
|
||||
open lid
|
||||
|
||||
"""
|
||||
|
||||
key = "open lid"
|
||||
aliases = ["open button", 'open']
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"simply call the right function."
|
||||
|
||||
if self.obj.db.lid_locked:
|
||||
self.caller.msg("This lid seems locked in place for the moment.")
|
||||
return
|
||||
|
||||
string = "\nA ticking sound is heard, like a winding mechanism. Seems "
|
||||
string += "the lid will soon close again."
|
||||
self.caller.msg(string)
|
||||
self.caller.location.msg_contents("%s opens the lid of the button." %
|
||||
(self.caller.name), exclude=self.caller)
|
||||
# add the relevant cmdsets to button
|
||||
self.obj.cmdset.add(LidClosedCmdSet)
|
||||
# call object method
|
||||
self.obj.open_lid()
|
||||
|
||||
|
||||
class CmdCloseLid(Command):
|
||||
"""
|
||||
close the lid
|
||||
|
||||
Usage:
|
||||
close lid
|
||||
|
||||
Closes the lid of the red button.
|
||||
"""
|
||||
|
||||
key = "close lid"
|
||||
aliases = ["close"]
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"Close the lid"
|
||||
|
||||
self.obj.close_lid()
|
||||
|
||||
# this will clean out scripts dependent on lid being open.
|
||||
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.name), exclude=self.caller)
|
||||
|
||||
|
||||
class CmdBlindLook(Command):
|
||||
"""
|
||||
Looking around in darkness
|
||||
|
||||
Usage:
|
||||
look <obj>
|
||||
|
||||
... not that there's much to see in the dark.
|
||||
|
||||
"""
|
||||
|
||||
key = "look"
|
||||
aliases = ["l", "get", "examine", "ex", "feel", "listen"]
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"This replaces all the senses when blinded."
|
||||
|
||||
# we decide what to reply based on which command was
|
||||
# actually tried
|
||||
|
||||
if self.cmdstring == "get":
|
||||
string = "You fumble around blindly without finding anything."
|
||||
elif self.cmdstring == "examine":
|
||||
string = "You try to examine your surroundings, but can't see a thing."
|
||||
elif self.cmdstring == "listen":
|
||||
string = "You are deafened by the boom."
|
||||
elif self.cmdstring == "feel":
|
||||
string = "You fumble around, hands outstretched. You bump your knee."
|
||||
else:
|
||||
# trying to look
|
||||
string = "You are temporarily blinded by the flash. "
|
||||
string += "Until it wears off, all you can do is feel around blindly."
|
||||
self.caller.msg(string)
|
||||
self.caller.location.msg_contents("%s stumbles around, blinded." %
|
||||
(self.caller.name), exclude=self.caller)
|
||||
|
||||
|
||||
class CmdBlindHelp(Command):
|
||||
"""
|
||||
Help function while in the blinded state
|
||||
|
||||
Usage:
|
||||
help
|
||||
|
||||
"""
|
||||
key = "help"
|
||||
aliases = "h"
|
||||
locks = "cmd:all()"
|
||||
|
||||
def func(self):
|
||||
"Give a message."
|
||||
self.caller.msg("You are beyond help ... until you can see again.")
|
||||
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# Command sets for the red button
|
||||
#---------------------------------------------------------------
|
||||
|
||||
# We next tuck these commands into their respective command sets.
|
||||
# (note that we are overdoing the cdmset separation a bit here
|
||||
# to show how it works).
|
||||
|
||||
class DefaultCmdSet(CmdSet):
|
||||
"""
|
||||
The default cmdset always sits
|
||||
on the button object and whereas other
|
||||
command sets may be added/merge onto it
|
||||
and hide it, removing them will always
|
||||
bring it back. It's added to the object
|
||||
using obj.cmdset.add_default().
|
||||
"""
|
||||
key = "RedButtonDefault"
|
||||
mergetype = "Union" # this is default, we don't really need to put it here.
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"Init the cmdset"
|
||||
self.add(CmdPush())
|
||||
|
||||
|
||||
class LidClosedCmdSet(CmdSet):
|
||||
"""
|
||||
A simple cmdset tied to the redbutton object.
|
||||
|
||||
It contains the commands that launches the other
|
||||
command sets, making the red button a self-contained
|
||||
item (i.e. you don't have to manually add any
|
||||
scripts etc to it when creating it).
|
||||
"""
|
||||
key = "LidClosedCmdSet"
|
||||
# default Union is used *except* if we are adding to a
|
||||
# cmdset named LidOpenCmdSet - this one we replace
|
||||
# completely.
|
||||
key_mergetype = {"LidOpenCmdSet": "Replace"}
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"Populates the cmdset when it is instantiated."
|
||||
self.add(CmdNudge())
|
||||
self.add(CmdSmashGlass())
|
||||
self.add(CmdOpenLid())
|
||||
|
||||
|
||||
class LidOpenCmdSet(CmdSet):
|
||||
"""
|
||||
This is the opposite of the Closed cmdset.
|
||||
"""
|
||||
key = "LidOpenCmdSet"
|
||||
# default Union is used *except* if we are adding to a
|
||||
# cmdset named LidClosedCmdSet - this one we replace
|
||||
# completely.
|
||||
key_mergetype = {"LidClosedCmdSet": "Replace"}
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"setup the cmdset (just one command)"
|
||||
self.add(CmdCloseLid())
|
||||
|
||||
|
||||
class BlindCmdSet(CmdSet):
|
||||
"""
|
||||
This is the cmdset added to the *player* when
|
||||
the button is pushed.
|
||||
"""
|
||||
key = "BlindCmdSet"
|
||||
# we want it to completely replace all normal commands
|
||||
# until the timed script removes it again.
|
||||
mergetype = "Replace"
|
||||
# we want to stop the player from walking around
|
||||
# in this blinded state, so we hide all exits too.
|
||||
# (channel commands will still work).
|
||||
no_exits = True # keep player in the same room
|
||||
no_objs = True # don't allow object commands
|
||||
|
||||
def at_cmdset_creation(self):
|
||||
"Setup the blind cmdset"
|
||||
from evennia.commands.default.general import CmdSay
|
||||
from evennia.commands.default.general import CmdPose
|
||||
self.add(CmdSay())
|
||||
self.add(CmdPose())
|
||||
self.add(CmdBlindLook())
|
||||
self.add(CmdBlindHelp())
|
||||
158
contrib/tutorial_examples/red_button.py
Normal file
158
contrib/tutorial_examples/red_button.py
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
"""
|
||||
|
||||
This is a more advanced example object. It combines functions from
|
||||
script.examples as well as commands.examples to make an interactive
|
||||
button typeclass.
|
||||
|
||||
Create this button with
|
||||
|
||||
@create/drop examples.red_button.RedButton
|
||||
|
||||
Note that you must drop the button before you can see its messages!
|
||||
"""
|
||||
import random
|
||||
from evennia import DefaultObject
|
||||
from contrib.tutorial_examples import red_button_scripts as scriptexamples
|
||||
from contrib.tutorial_examples import cmdset_red_button as cmdsetexamples
|
||||
|
||||
#
|
||||
# Definition of the object itself
|
||||
#
|
||||
|
||||
|
||||
class RedButton(DefaultObject):
|
||||
"""
|
||||
This class describes an evil red button. It will use the script
|
||||
definition in contrib/examples/red_button_scripts to blink at regular
|
||||
intervals. It also uses a series of script and commands to handle
|
||||
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):
|
||||
"""
|
||||
This function is called when object is created. Use this
|
||||
instead of e.g. __init__.
|
||||
"""
|
||||
# store desc (default, you can change this at creation time)
|
||||
desc = "This is a large red button, inviting yet evil-looking. "
|
||||
desc += "A closed glass lid protects it."
|
||||
self.db.desc = desc
|
||||
|
||||
# We have to define all the variables the scripts
|
||||
# are checking/using *before* adding the scripts or
|
||||
# they might be deactivated before even starting!
|
||||
self.db.lid_open = False
|
||||
self.db.lamp_works = True
|
||||
self.db.lid_locked = False
|
||||
|
||||
self.cmdset.add_default(cmdsetexamples.DefaultCmdSet, permanent=True)
|
||||
|
||||
# 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
|
||||
# check so they are valid (i.e. the lid is actually still closed)).
|
||||
# The AddClosedCmdSet script makes sure to add the Closed-cmdset.
|
||||
self.scripts.add(scriptexamples.ClosedLidState)
|
||||
# the script EventBlinkButton makes the button blink regularly.
|
||||
self.scripts.add(scriptexamples.BlinkButtonEvent)
|
||||
|
||||
# state-changing methods
|
||||
|
||||
def open_lid(self):
|
||||
"""
|
||||
Opens the glass lid and start the timer so it will soon close
|
||||
again.
|
||||
"""
|
||||
|
||||
if self.db.lid_open:
|
||||
return
|
||||
desc = self.db.desc_lid_open
|
||||
if not desc:
|
||||
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.lid_open = True
|
||||
|
||||
# with the lid open, we validate scripts; this will clean out
|
||||
# scripts that depend on the lid to be closed.
|
||||
self.scripts.validate()
|
||||
# now add new scripts that define the open-lid state
|
||||
self.scripts.add(scriptexamples.OpenLidState)
|
||||
# we also add a scripted event that will close the lid after a while.
|
||||
# (this one cleans itself after being called once)
|
||||
self.scripts.add(scriptexamples.CloseLidEvent)
|
||||
|
||||
def close_lid(self):
|
||||
"""
|
||||
Close the glass lid. This validates all scripts on the button,
|
||||
which means that scripts only being valid when the lid is open
|
||||
will go away automatically.
|
||||
"""
|
||||
|
||||
if not self.db.lid_open:
|
||||
return
|
||||
desc = self.db.desc_lid_closed
|
||||
if not desc:
|
||||
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.lid_open = False
|
||||
|
||||
# clean out scripts depending on lid to be open
|
||||
self.scripts.validate()
|
||||
# add scripts related to the closed state
|
||||
self.scripts.add(scriptexamples.ClosedLidState)
|
||||
|
||||
def break_lamp(self, feedback=True):
|
||||
"""
|
||||
Breaks the lamp in the button, stopping it from blinking.
|
||||
|
||||
"""
|
||||
self.db.lamp_works = False
|
||||
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:
|
||||
self.location.msg_contents("The lamp flickers, the button going dark.")
|
||||
self.scripts.validate()
|
||||
|
||||
def press_button(self, pobject):
|
||||
"""
|
||||
Someone was foolish enough to press the button!
|
||||
pobject - the person pressing the button
|
||||
"""
|
||||
# deactivate the button so it won't flash/close lid etc.
|
||||
self.scripts.add(scriptexamples.DeactivateButtonEvent)
|
||||
# blind the person pressing the button. Note that this
|
||||
# script is set on the *character* pressing the button!
|
||||
pobject.scripts.add(scriptexamples.BlindedState)
|
||||
|
||||
# script-related methods
|
||||
|
||||
def blink(self):
|
||||
"""
|
||||
The script system will regularly call this
|
||||
function to make the button blink. Now and then
|
||||
it won't blink at all though, to add some randomness
|
||||
to how often the message is echoed.
|
||||
"""
|
||||
loc = self.location
|
||||
if loc:
|
||||
rand = random.random()
|
||||
if rand < 0.2:
|
||||
string = "The red button flashes briefly."
|
||||
elif rand < 0.4:
|
||||
string = "The red button blinks invitingly."
|
||||
elif rand < 0.6:
|
||||
string = "The red button flashes. You know you wanna push it!"
|
||||
else:
|
||||
# no blink
|
||||
return
|
||||
loc.msg_contents(string)
|
||||
275
contrib/tutorial_examples/red_button_scripts.py
Normal file
275
contrib/tutorial_examples/red_button_scripts.py
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
"""
|
||||
Example of scripts.
|
||||
|
||||
These are scripts intended for a particular object - the
|
||||
red_button object type in contrib/examples. A few variations
|
||||
on uses of scripts are included.
|
||||
|
||||
"""
|
||||
from evennia import Script
|
||||
from contrib.tutorial_examples import cmdset_red_button as cmdsetexamples
|
||||
|
||||
#
|
||||
# Scripts as state-managers
|
||||
#
|
||||
# Scripts have many uses, one of which is to statically
|
||||
# make changes when a particular state of an object changes.
|
||||
# There is no "timer" involved in this case (although there could be),
|
||||
# whenever the script determines it is "invalid", it simply shuts down
|
||||
# along with all the things it controls.
|
||||
#
|
||||
# To show as many features as possible of the script and cmdset systems,
|
||||
# we will use three scripts controlling one state each of the red_button,
|
||||
# each with its own set of commands, handled by cmdsets - one for when
|
||||
# the button has its lid open, and one for when it is closed and a
|
||||
# last one for when the player pushed the button and gets blinded by
|
||||
# a bright light. The last one also has a timer component that allows it
|
||||
# to remove itself after a while (and the player recovers their eyesight).
|
||||
|
||||
class ClosedLidState(Script):
|
||||
"""
|
||||
This manages the cmdset for the "closed" button state. What this
|
||||
means is that while this script is valid, we add the RedButtonClosed
|
||||
cmdset to it (with commands like open, nudge lid etc)
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
"Called when script first created."
|
||||
self.desc = "Script that manages the closed-state cmdsets for red button."
|
||||
self.persistent = True
|
||||
|
||||
def at_start(self):
|
||||
"""
|
||||
This is called once every server restart, so we want to add the
|
||||
(memory-resident) cmdset to the object here. is_valid is automatically
|
||||
checked so we don't need to worry about adding the script to an
|
||||
open lid.
|
||||
"""
|
||||
#All we do is add the cmdset for the closed state.
|
||||
self.obj.cmdset.add(cmdsetexamples.LidClosedCmdSet)
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
The script is only valid while the lid is closed.
|
||||
self.obj is the red_button on which this script is defined.
|
||||
"""
|
||||
return not self.obj.db.lid_open
|
||||
|
||||
def at_stop(self):
|
||||
"""
|
||||
When the script stops we must make sure to clean up after us.
|
||||
|
||||
"""
|
||||
self.obj.cmdset.delete(cmdsetexamples.LidClosedCmdSet)
|
||||
|
||||
|
||||
class OpenLidState(Script):
|
||||
"""
|
||||
This manages the cmdset for the "open" button state. This will add
|
||||
the RedButtonOpen
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
"Called when script first created."
|
||||
self.desc = "Script that manages the opened-state cmdsets for red button."
|
||||
self.persistent = True
|
||||
|
||||
def at_start(self):
|
||||
"""
|
||||
This is called once every server restart, so we want to add the
|
||||
(memory-resident) cmdset to the object here. is_valid is
|
||||
automatically checked, so we don't need to worry about
|
||||
adding the cmdset to a closed lid-button.
|
||||
"""
|
||||
#print "In Open at_start (should add cmdset)"
|
||||
self.obj.cmdset.add(cmdsetexamples.LidOpenCmdSet)
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
The script is only valid while the lid is open.
|
||||
self.obj is the red_button on which this script is defined.
|
||||
"""
|
||||
return self.obj.db.lid_open
|
||||
|
||||
def at_stop(self):
|
||||
"""
|
||||
When the script stops (like if the lid is closed again)
|
||||
we must make sure to clean up after us.
|
||||
"""
|
||||
self.obj.cmdset.delete(cmdsetexamples.LidOpenCmdSet)
|
||||
|
||||
|
||||
class BlindedState(Script):
|
||||
"""
|
||||
This is a timed state.
|
||||
|
||||
This adds a (very limited) cmdset TO THE PLAYER, during a certain time,
|
||||
after which the script will close and all functions are
|
||||
restored. It's up to the function starting the script to actually
|
||||
set it on the right player object.
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
We set up the script here.
|
||||
"""
|
||||
self.key = "temporary_blinder"
|
||||
self.desc = "Temporarily blinds the player for a little while."
|
||||
self.interval = 20 # seconds
|
||||
self.start_delay = True # we don't want it to stop until after 20s.
|
||||
self.repeats = 1 # this will go away after interval seconds.
|
||||
self.persistent = False # we will ditch this if server goes down
|
||||
|
||||
def at_start(self):
|
||||
"""
|
||||
We want to add the cmdset to the linked object.
|
||||
|
||||
Note that the RedButtonBlind cmdset is defined to completly
|
||||
replace the other cmdsets on the stack while it is active
|
||||
(this means that while blinded, only operations in this cmdset
|
||||
will be possible for the player to perform). It is however
|
||||
not persistent, so should there be a bug in it, we just need
|
||||
to restart the server to clear out of it during development.
|
||||
"""
|
||||
self.obj.cmdset.add(cmdsetexamples.BlindCmdSet)
|
||||
|
||||
def at_stop(self):
|
||||
"""
|
||||
It's important that we clear out that blinded cmdset
|
||||
when we are done!
|
||||
"""
|
||||
self.obj.msg("You blink feverishly as your eyesight slowly returns.")
|
||||
self.obj.location.msg_contents("%s seems to be recovering their eyesight."
|
||||
% self.obj.name,
|
||||
exclude=self.obj)
|
||||
self.obj.cmdset.delete() # this will clear the latest added cmdset,
|
||||
# (which is the blinded one).
|
||||
|
||||
|
||||
#
|
||||
# Timer/Event-like Scripts
|
||||
#
|
||||
# Scripts can also work like timers, or "events". Below we
|
||||
# define three such timed events that makes the button a little
|
||||
# more "alive" - one that makes the button blink menacingly, another
|
||||
# that makes the lid covering the button slide back after a while.
|
||||
#
|
||||
|
||||
class CloseLidEvent(Script):
|
||||
"""
|
||||
This event closes the glass lid over the button
|
||||
some time after it was opened. It's a one-off
|
||||
script that should be started/created when the
|
||||
lid is opened.
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Called when script object is first created. Sets things up.
|
||||
We want to have a lid on the button that the user can pull
|
||||
aside in order to make the button 'pressable'. But after a set
|
||||
time that lid should auto-close again, making the button safe
|
||||
from pressing (and deleting this command).
|
||||
"""
|
||||
self.key = "lid_closer"
|
||||
self.desc = "Closes lid on a red buttons"
|
||||
self.interval = 20 # seconds
|
||||
self.start_delay = True # we want to pospone the launch.
|
||||
self.repeats = 1 # we only close the lid once
|
||||
self.persistent = True # even if the server crashes in those 20 seconds,
|
||||
# the lid will still close once the game restarts.
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
This script can only operate if the lid is open; if it
|
||||
is already closed, the script is clearly invalid.
|
||||
|
||||
Note that we are here relying on an self.obj being
|
||||
defined (and being a RedButton object) - this we should be able to
|
||||
expect since this type of script is always tied to one individual
|
||||
red button object and not having it would be an error.
|
||||
"""
|
||||
return self.obj.db.lid_open
|
||||
|
||||
def at_repeat(self):
|
||||
"""
|
||||
Called after self.interval seconds. It closes the lid. Before this method is
|
||||
called, self.is_valid() is automatically checked, so there is no need to
|
||||
check this manually.
|
||||
"""
|
||||
self.obj.close_lid()
|
||||
|
||||
class BlinkButtonEvent(Script):
|
||||
"""
|
||||
This timed script lets the button flash at regular intervals.
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Sets things up. We want the button's lamp to blink at
|
||||
regular intervals, unless it's broken (can happen
|
||||
if you try to smash the glass, say).
|
||||
"""
|
||||
self.key = "blink_button"
|
||||
self.desc = "Blinks red buttons"
|
||||
self.interval = 35 #seconds
|
||||
self.start_delay = False #blink right away
|
||||
self.persistent = True #keep blinking also after server reboot
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
Button will keep blinking unless it is broken.
|
||||
"""
|
||||
#print "self.obj.db.lamp_works:", self.obj.db.lamp_works
|
||||
return self.obj.db.lamp_works
|
||||
|
||||
def at_repeat(self):
|
||||
"""
|
||||
Called every self.interval seconds. Makes the lamp in
|
||||
the button blink.
|
||||
"""
|
||||
self.obj.blink()
|
||||
|
||||
class DeactivateButtonEvent(Script):
|
||||
"""
|
||||
This deactivates the button for a short while (it won't blink, won't
|
||||
close its lid etc). It is meant to be called when the button is pushed
|
||||
and run as long as the blinded effect lasts. We cannot put these methods
|
||||
in the AddBlindedCmdSet script since that script is defined on the *player*
|
||||
whereas this one must be defined on the *button*.
|
||||
"""
|
||||
def at_script_creation(self):
|
||||
"""
|
||||
Sets things up.
|
||||
"""
|
||||
self.key = "deactivate_button"
|
||||
self.desc = "Deactivate red button temporarily"
|
||||
self.interval = 21 #seconds
|
||||
self.start_delay = True # wait with the first repeat for self.interval seconds.
|
||||
self.persistent = True
|
||||
self.repeats = 1 # only do this once
|
||||
|
||||
def at_start(self):
|
||||
"""
|
||||
Deactivate the button. Observe that this method is always
|
||||
called directly, regardless of the value of self.start_delay
|
||||
(that just controls when at_repeat() is called)
|
||||
"""
|
||||
# closing the lid will also add the ClosedState script
|
||||
self.obj.close_lid()
|
||||
# lock the lid so other players can't access it until the
|
||||
# first one's effect has worn off.
|
||||
self.obj.db.lid_locked = True
|
||||
# breaking the lamp also sets a correct desc
|
||||
self.obj.break_lamp(feedback=False)
|
||||
|
||||
def at_repeat(self):
|
||||
"""
|
||||
When this is called, reset the functionality of the button.
|
||||
"""
|
||||
# restore button's desc.
|
||||
|
||||
self.obj.db.lamp_works = True
|
||||
desc = "This is a large red button, inviting yet evil-looking. "
|
||||
desc += "Its glass cover is closed, protecting it."
|
||||
self.db.desc = desc
|
||||
# re-activate the blink button event.
|
||||
self.obj.scripts.add(BlinkButtonEvent)
|
||||
# unlock the lid
|
||||
self.obj.db.lid_locked = False
|
||||
self.obj.scripts.validate()
|
||||
Loading…
Add table
Add a link
Reference in a new issue