Trunk: Merged the Devel-branch (branches/griatch) into /trunk. This constitutes a major refactoring of Evennia. Development will now continue in trunk. See the wiki and the past posts to the mailing list for info. /Griatch
This commit is contained in:
parent
df29defbcd
commit
f83c2bddf8
222 changed files with 22304 additions and 14371 deletions
292
game/gamesrc/commands/examples/cmdset_red_button.py
Normal file
292
game/gamesrc/commands/examples/cmdset_red_button.py
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
"""
|
||||
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 if 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 src.commands.cmdset import CmdSet
|
||||
from game.gamesrc.commands.basecommand import Command
|
||||
|
||||
# Some simple commands for the red button
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Commands defined for 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!
|
||||
alias = ["nudge"]
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
nudge the lid.
|
||||
"""
|
||||
rand = random.random()
|
||||
if rand < 0.5:
|
||||
string = "You nudge at the lid. It seems stuck."
|
||||
elif 0.5 <= 0.5 < 0.7:
|
||||
string = "You move the lid back and forth. It won't budge."
|
||||
else:
|
||||
string = "You manage to get a nail under the lid. It pops open."
|
||||
self.obj.open_lid()
|
||||
self.caller.msg(string)
|
||||
|
||||
class CmdPush(Command):
|
||||
"""
|
||||
Push the red button
|
||||
|
||||
Usage:
|
||||
push button
|
||||
|
||||
"""
|
||||
key = "push button"
|
||||
aliases = ["push", "press button", "press"]
|
||||
|
||||
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 tries 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.obj.press_button(self.caller)
|
||||
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)
|
||||
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"]
|
||||
|
||||
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."
|
||||
self.caller.msg(string) # have to be called before breakage since that
|
||||
# also gives a return feedback to the room.
|
||||
self.obj.break_lamp()
|
||||
return
|
||||
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']
|
||||
|
||||
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
|
||||
|
||||
self.caller.location.msg_contents("%s opens the lid of the button." %
|
||||
(self.caller.name), exclude=self.caller)
|
||||
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"]
|
||||
|
||||
def func(self):
|
||||
"Close the lid"
|
||||
self.obj.close_lid()
|
||||
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"]
|
||||
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"
|
||||
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 RedButtonOpen - 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 RedButtonClose - 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"
|
||||
self.add(CmdBlindLook())
|
||||
self.add(CmdBlindHelp())
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
"""
|
||||
This is an example command module for showing the pluggable command
|
||||
system in action.
|
||||
|
||||
You'll need to make sure that this or any new modules you create are
|
||||
added to game/settings.py under CUSTOM_COMMAND_MODULES or
|
||||
CUSTOM_UNLOGGED_COMMAND_MODULES, which are tuples of module import
|
||||
path strings. See src/config_defaults.py for more details.
|
||||
|
||||
E.g. to add this example command for testing, your entry in
|
||||
game/settings.py would look like this:
|
||||
|
||||
CUSTOM_COMMAND_MODULES = ('game.gamesrc.commands.examples.example',)
|
||||
|
||||
(note the extra comma at the end to make this into a Python
|
||||
tuple. It's only needed if you have only one entry.) You need to
|
||||
restart the Evennia server before new files are recognized. Once this
|
||||
is done once, you don't have to restart again, just use
|
||||
@reload/commands to use the changes you make to your modules.
|
||||
"""
|
||||
|
||||
# This is the common global CommandTable object which we'll be adding the
|
||||
# example command(s) to.
|
||||
from src.cmdtable import GLOBAL_CMD_TABLE
|
||||
|
||||
# The main command definition. We can add any number of commands this way in the
|
||||
# same file.
|
||||
def cmd_example(command):
|
||||
"""
|
||||
example - example command
|
||||
|
||||
Usage:
|
||||
@testcommand[/switches] <text>
|
||||
|
||||
switches:
|
||||
(can be any string, e.g. /test1 or /tom/sarah/peter)
|
||||
|
||||
This is the help text for the 'example' command, a command to
|
||||
show how the pluggable command system works.
|
||||
|
||||
For testing, you can try calling this with different switches and
|
||||
arguments, like
|
||||
> example/test/test2 Hello
|
||||
and see what is returned.
|
||||
|
||||
[[example_auto_help]]
|
||||
|
||||
This is a subtopic to the main example command help entry. It is
|
||||
done by the help system splitting the text by markup of the
|
||||
form [ [title ] ] (with no spaces between the square brackets)
|
||||
|
||||
Note that this help entry is auto-added as long as HELP_AUTO
|
||||
is not set to False in your game/settings.py file.
|
||||
Any number of subtopics like this one can be added on the fly
|
||||
using the auto-help system. See help topics on 'help' and
|
||||
'help_markup' for more information and options.
|
||||
"""
|
||||
|
||||
# By building one big string and passing it at once, we cut down on a lot
|
||||
# of emit_to() calls, which is generally a good idea.
|
||||
retval = "----- Example Command -----\n\r"
|
||||
# source_object is the object executing the command
|
||||
retval += " Source object: %s\n\r" % command.source_object
|
||||
# session points to a user Session (session.py) object (if applicable)
|
||||
retval += " Session: %s\n\r" % command.session
|
||||
# The raw, un-parsed input
|
||||
retval += " Raw input: %s\n\r" % command.raw_input
|
||||
# The command name being executed
|
||||
retval += " Command: %s\n\r" % command.command_string
|
||||
# A list of switches provided (if any)
|
||||
retval += " Switches: %s\n\r" % command.command_switches
|
||||
# A string with any arguments provided with the command
|
||||
retval += " Arguments: %s\n\r" % command.command_argument
|
||||
# The function that was looked up via cmdtable.py
|
||||
retval += " Function: %s\n\r" % command.command_function
|
||||
# Extra variables passed with cmdtable.py's add_command().
|
||||
retval += " Extra vars: %s\n\r" % command.extra_vars
|
||||
|
||||
# Some more info for more advanced commands.
|
||||
if not command.command_switches and \
|
||||
command.command_argument:
|
||||
retval += "\n Obs: When no switches, also multi-word\n"
|
||||
retval += " command names are possible. Max allowed\n"
|
||||
retval += " length is set in game/settings.py.\n"
|
||||
retval += " So if there exist a matching command in the\n"
|
||||
retval += " command table, Evennia would also allow\n"
|
||||
retval += " the following as valid commands (and the\n"
|
||||
retval += " argument list would shrink accordingly):\n"
|
||||
multi = ""
|
||||
for arg in command.command_argument.split():
|
||||
multi += " %s" % arg
|
||||
retval += " %s%s\n" % (command.command_string, multi)
|
||||
|
||||
# send string to player
|
||||
command.source_object.emit_to(retval)
|
||||
|
||||
# Add the command to the common global command table. Note that
|
||||
# this will auto-create help entries 'example' and
|
||||
# "example_auto_help" for us.
|
||||
GLOBAL_CMD_TABLE.add_command("@testcommand", cmd_example)
|
||||
|
||||
#
|
||||
# another simple example
|
||||
#
|
||||
def cmd_emote_smile(command):
|
||||
"""
|
||||
smile - break a smile
|
||||
|
||||
Usage:
|
||||
smile
|
||||
|
||||
A 'smile' emote.
|
||||
"""
|
||||
#get the source object (that is, the player using the command)
|
||||
source_object = command.source_object
|
||||
#find name of caller
|
||||
name = source_object.get_name(show_dbref=False)
|
||||
#get the location caller is at
|
||||
location = source_object.get_location()
|
||||
#build the emote
|
||||
text = "%s smiles." % name
|
||||
#emit the emote to everyone at the current location
|
||||
location.emit_to_contents(text)
|
||||
|
||||
# add to global command table (we probably want an auto-help entry
|
||||
# for this, but we are turning auto-help off anyway, to show
|
||||
# how it works)
|
||||
GLOBAL_CMD_TABLE.add_command('smile', cmd_emote_smile,
|
||||
auto_help_override=False)
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
"""
|
||||
This module contains various commands for testing some
|
||||
of Evennia's subsystems. They were used for initial testing
|
||||
but are also instructive for playing around with to learn
|
||||
how different systems work. See also state_example.py.
|
||||
|
||||
To make these commands available in-game, add this module
|
||||
to the CUSTOM_COMMAND_MODULES tuple in game/settings.py
|
||||
as 'game.gamesrc.commands.examples.misc_tests'.
|
||||
|
||||
None of these commands are auto-added to the help database
|
||||
(they have no docstrings) in order to help make it clean.
|
||||
"""
|
||||
|
||||
from src.cmdtable import GLOBAL_CMD_TABLE
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Tests of the event system
|
||||
#------------------------------------------------------------
|
||||
|
||||
def cmd_testevent(command):
|
||||
#
|
||||
# This test allows testing the event system
|
||||
#
|
||||
# Usage:
|
||||
# @testevent [pid]
|
||||
#
|
||||
# Without argument, this command creates
|
||||
# a dummy event in the process table.
|
||||
# Use @ps to see it. Give the equivalent
|
||||
# pid to remove it again (careful though,
|
||||
# this command can also remove useful
|
||||
# events if you give the wrong pid).
|
||||
#
|
||||
from src import events
|
||||
from src import scheduler
|
||||
|
||||
source_object = command.source_object
|
||||
|
||||
if not source_object.is_superuser():
|
||||
# To avoid accidental access to process table
|
||||
source_object.emit_to("This command is superuser only.")
|
||||
return
|
||||
|
||||
if not command.command_argument:
|
||||
# No argument given; create a new test event.
|
||||
event = events.IntervalEvent()
|
||||
event.description = "Test event created with @testevent."
|
||||
event.repeats = 3
|
||||
event.interval = 5
|
||||
pid = scheduler.add_event(event)
|
||||
string = "Event with pid %s added. " % pid
|
||||
string += "It repeats %i times and waits " % event.repeats
|
||||
string += "for %i seconds between each repeat." % event.interval
|
||||
string += "After all repeats, it will delete itself."
|
||||
string += "\nUse @ps to see it and give this "
|
||||
string += "command with the pid as argument to delete it."
|
||||
source_object.emit_to(string)
|
||||
else:
|
||||
# An argument given; assume this is a pid.
|
||||
try:
|
||||
pid = int(command.command_argument)
|
||||
except:
|
||||
source_object.emit_to("Not a valid argument. You must give a number.")
|
||||
return
|
||||
if pid < 3:
|
||||
string = "This low pid might belong to a system process, \n"
|
||||
string += "so as a safety measure you cannot delete it using \n"
|
||||
string += "this test command. Use @delevent instead."
|
||||
source_object.emit_to(string)
|
||||
return
|
||||
pid = command.command_argument
|
||||
scheduler.del_event(pid)
|
||||
string = "Event with pid %s removed (if it existed)." % pid
|
||||
string += " Confirm this worked using @ps."
|
||||
source_object.emit_to(string)
|
||||
GLOBAL_CMD_TABLE.add_command("@testevent", cmd_testevent,
|
||||
auto_help_override=False)
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Test of Cache system
|
||||
#------------------------------------------------------------
|
||||
|
||||
def cmd_testcache(command):
|
||||
#
|
||||
# Tests the cache system by writing to it
|
||||
# back and forth several times.
|
||||
#
|
||||
# Usage:
|
||||
# @testcache [get]
|
||||
#
|
||||
# Use without 'get' to store test data in
|
||||
# caches and with 'get' to read them back
|
||||
# and make sure they all saved as they
|
||||
# should. You might also want to
|
||||
# try shut down the server between
|
||||
# calls to make sure the persistent
|
||||
# cache does survive the shutdown.
|
||||
|
||||
from src.cache import cache
|
||||
from src import gametime
|
||||
|
||||
source_object = command.source_object
|
||||
switches = command.command_switches
|
||||
|
||||
s1 = "Value: Cache: OK"
|
||||
s2 = "Value: PCache 1 (set using property assignment): OK"
|
||||
s3 = "Value: PCache 2 (set using function call): OK"
|
||||
if switches and "get" in switches:
|
||||
# Reading from cache
|
||||
source_object.emit_to("Reading from cache ...")
|
||||
cache.load_pcache()
|
||||
cache_vol = source_object.cache.testcache
|
||||
source_object.emit_to("< volatile cache:\n %s" % cache_vol)
|
||||
cache_perm = source_object.pcache.testcache_perm
|
||||
source_object.emit_to("< persistent cache 1/2:\n %s" % cache_perm)
|
||||
cache_perm2 = cache.get_pcache("permtest2")
|
||||
source_object.emit_to("< persistent cache 2/2:\n %s" % cache_perm2)
|
||||
else:
|
||||
# Saving to cache
|
||||
source_object.emit_to("Save to cache ...")
|
||||
source_object.cache.testcache = s1
|
||||
# using two different ways to set pcache
|
||||
source_object.pcache.testcache_perm = s2
|
||||
cache.set_pcache("permtest2", s3)
|
||||
|
||||
source_object.emit_to("> volatile cache:\n %s" % s1)
|
||||
source_object.emit_to("> persistent cache 1/2:\n %s" % s2)
|
||||
source_object.emit_to("> persistent cache 2/2:\n %s" % s3)
|
||||
cache.save_pcache()
|
||||
string = "Caches saved. Use /get as a switch to read them back."
|
||||
source_object.emit_to(string)
|
||||
source_object.emit_to("Running Gametime: %i" % gametime.time())
|
||||
GLOBAL_CMD_TABLE.add_command("@testcache", cmd_testcache,
|
||||
auto_help_override=False)
|
||||
|
|
@ -1,333 +0,0 @@
|
|||
"""
|
||||
Example of using the state system. The State system allows a player
|
||||
object to be 'trapped' in a special environment where different
|
||||
commands are available than normal. This is very useful in order to
|
||||
implement anything from menus and combat states to npc-conversational
|
||||
choices and inline text-editors.
|
||||
|
||||
This example uses the State system to create a simple menu.
|
||||
|
||||
To test out this example, add this module to the
|
||||
CUSTOM_COMMAND_MODULES tuple in your game/settings.py as
|
||||
'game.gamesrc.commands.examples.state_example' (see ./example.py for
|
||||
another example). You need to restart the Evennia server before new
|
||||
files are recognized.
|
||||
|
||||
Next enter the mud and give the command
|
||||
|
||||
> @testmenu
|
||||
|
||||
Note that the help entries related to this little menu are not part of
|
||||
the normal help database, they are stored with the state and only
|
||||
accessible from inside it. Try 'help entermenu' from outside the state
|
||||
and 'help' and 'info' from inside the menu to see the auto-help system
|
||||
in action.
|
||||
|
||||
To further test the state system, try the command
|
||||
|
||||
> @teststate
|
||||
|
||||
This takes arguments between 1-6 to set up various states with varying
|
||||
access to different global commands.
|
||||
|
||||
See also misc_tests.py for other tests.
|
||||
"""
|
||||
|
||||
# This is the normal command table, accessible by default
|
||||
from src.cmdtable import GLOBAL_CMD_TABLE
|
||||
|
||||
# The statetable contains sets of cmdtables that is made available
|
||||
# only when we are in a particular state (possibly overriding
|
||||
# same-named commands in GLOBAL_CMD_TABLE).
|
||||
from src.statetable import GLOBAL_STATE_TABLE
|
||||
|
||||
#
|
||||
# Implementing a simple 'menu' state
|
||||
#
|
||||
|
||||
#the name of our state, to make sure it's the same everywhere
|
||||
STATENAME = 'menu'
|
||||
|
||||
#
|
||||
# 'entry' command. This takes the player from the normal game
|
||||
# mode into the menu state. This must be added to the
|
||||
# GLOBAL_CMD_TABLE like any other command.
|
||||
#
|
||||
def cmd_entermenu(command):
|
||||
"""
|
||||
entermenu - enter the example menu
|
||||
|
||||
Usage:
|
||||
entermenu
|
||||
|
||||
This is the 'entry' command that takes the player from the normal
|
||||
gameplay mode into the 'menu' state.
|
||||
"""
|
||||
# get the player object calling the command
|
||||
source_object = command.source_object
|
||||
|
||||
# this is important: we use the set_state() command
|
||||
# to shift the player into a state named 'menu'. Other useful
|
||||
# access functions on source_object are get_state()
|
||||
# and clear_state(), the latter returns the player to
|
||||
# the normal mode of gameplay.
|
||||
source_object.set_state(STATENAME)
|
||||
|
||||
#show a welcome text .
|
||||
string = """
|
||||
Welcome to the Demo menu! In this small demo all you can do is
|
||||
select one of the two options so it changes colour. This is just
|
||||
intended to show off the possibilities of the state system. More
|
||||
interesting things should of course happen in a real menu.
|
||||
|
||||
Use @exit to leave the menu.
|
||||
"""
|
||||
source_object.emit_to(string)
|
||||
|
||||
# show the menu
|
||||
source_object.execute_cmd('menu')
|
||||
|
||||
#
|
||||
# Below are commands only available while in the 'menu' state.
|
||||
# Note that the _doc__ strings of the functions
|
||||
# can be read as help entries when in the menu.
|
||||
#
|
||||
def menu_cmd_option1(command):
|
||||
"""
|
||||
option1
|
||||
This command, obviously, selects the first option.
|
||||
"""
|
||||
source_object = command.source_object
|
||||
print_menu(source_object, 1)
|
||||
|
||||
def menu_cmd_option2(command):
|
||||
"""
|
||||
option2
|
||||
This command selects the second option. Duh.
|
||||
"""
|
||||
source_object = command.source_object
|
||||
print_menu(source_object, 2)
|
||||
|
||||
def menu_cmd_menu(command):
|
||||
"""
|
||||
menu
|
||||
|
||||
Clears the options and redraws the menu.
|
||||
|
||||
[[autohelp]]
|
||||
|
||||
Auto-help
|
||||
|
||||
This is an extra topic to test the auto-help functionality. The state-help
|
||||
system supports nested ('related') topics using [ [subtopic] ] markup,
|
||||
just like the normal help index does.
|
||||
"""
|
||||
source_object = command.source_object
|
||||
print_menu(source_object)
|
||||
|
||||
#
|
||||
# helper function
|
||||
#
|
||||
def print_menu(source_obj, choice=None):
|
||||
"""
|
||||
Utility function to print the menu. More interesting things
|
||||
would happen here in a real menu.
|
||||
"""
|
||||
|
||||
if choice == 1:
|
||||
#ansi colouring; see src.ansi
|
||||
chtext = "%s> option1\n %soption2" % ('%ch%cy','%cn%cy')
|
||||
elif choice == 2:
|
||||
chtext = " %soption1\n%s> option2" % ('%cn%cy','%ch%cy')
|
||||
else:
|
||||
chtext = " %soption1\n option2" % ('%cn%cy')
|
||||
|
||||
string ="\n%sMenu: \n%s\n %shelp \n @exit" % ('%ch%cr', chtext, '%cn%cy')
|
||||
source_obj.emit_to(string)
|
||||
|
||||
# Add the 'entry' command to the normal command table
|
||||
GLOBAL_CMD_TABLE.add_command("@testmenu", cmd_entermenu,
|
||||
auto_help_override=False)
|
||||
|
||||
# create the state. We make sure the player can exit it at
|
||||
# any time by @exit.
|
||||
GLOBAL_STATE_TABLE.add_state(STATENAME, exit_command=True)
|
||||
|
||||
# Add the menu commands to the state table by tying them to the 'menu'
|
||||
# state. It is important that the name of the state matches what we
|
||||
# set the player-object to in the 'entry' command.
|
||||
GLOBAL_STATE_TABLE.add_command(STATENAME, "option1", menu_cmd_option1)
|
||||
GLOBAL_STATE_TABLE.add_command(STATENAME, "option2", menu_cmd_option2)
|
||||
GLOBAL_STATE_TABLE.add_command(STATENAME, "menu", menu_cmd_menu)
|
||||
|
||||
|
||||
#
|
||||
# enterstate - testing the depth of the state system
|
||||
#
|
||||
|
||||
# This is a test suite that shows off all the features of the state
|
||||
# system. It sets up a test command @test_state that takes an
|
||||
# argument 1-6 for moving into states with different
|
||||
# characteristics. Note that the only difference as to how the various
|
||||
# states are created lies in the options given to the add_state()
|
||||
# function. Use @exit to leave any state.
|
||||
|
||||
# defining the test-state names so they are the same everywhere
|
||||
TSTATE1 = 'no_globals'
|
||||
TSTATE2 = 'all_globals'
|
||||
TSTATE3 = 'include_some_globals'
|
||||
TSTATE4 = 'exclude_some_globals'
|
||||
TSTATE5 = 'global_allow_exits'
|
||||
TSTATE6 = 'noglobal_allow_exits_obj_cmds'
|
||||
|
||||
#
|
||||
#the test command 'enterstate'
|
||||
#
|
||||
def cmd_test_state(command):
|
||||
"""
|
||||
@teststate - testing the state system
|
||||
|
||||
Usage: @teststate [1 - 6]
|
||||
|
||||
Give arguments 1-6 to enter different game states. Use @exit to
|
||||
get out of the state at any time.
|
||||
|
||||
1: A very limited state; only contains the 'test' state command.
|
||||
2: All global commands are included (so this should be the same as
|
||||
normal operation, except you cannot traverse exits and use
|
||||
object-based cmds)
|
||||
3: /Only/ the global commands 'get' and 'inventory' are included
|
||||
into the state.
|
||||
4: All global commands /except/ 'get' and 'inventory' are available
|
||||
5: All global commands availabe + ability to traverse exits (not use
|
||||
object-based cmds).
|
||||
6: Only the 'test' command available, but ability to
|
||||
both traverse exits and use object-based cmds.
|
||||
|
||||
Ideas for in-game use:
|
||||
1: Try out the '@testmenu' command for an example of this state.
|
||||
2: Could be used in order to stop someone from moving despite exits
|
||||
being open (tied up? In combat?)
|
||||
3: someone incapacitated or blinded might get only limited commands
|
||||
available
|
||||
4: in e.g. a combat state, things like crafting should not be
|
||||
possible.
|
||||
5: Pretty much default operation, just removing some global commands.
|
||||
Maybe limiting the use of magical weapons in a room or similar.
|
||||
6: A state of panic - You can move, but not take in your surroundings.
|
||||
|
||||
... the possibilities are endless.
|
||||
"""
|
||||
source_object = command.source_object
|
||||
args = command.command_argument
|
||||
# check for missing arguments
|
||||
if not args:
|
||||
source_object.emit_to("Usage: @teststate [1 - 6]")
|
||||
return
|
||||
# build up a return string
|
||||
string = "\n Entering state ... \nThis state includes the"
|
||||
string += " commands 'test', 'help', '@exit' and "
|
||||
arg = args.strip()
|
||||
|
||||
# step through the various options
|
||||
if arg == '1':
|
||||
string += "no global commands at all. \nWith some more state commands, "
|
||||
string += "this state would work well for e.g. a "
|
||||
string += "combat state or a menu where the player don't need access "
|
||||
string += "to the normal command definitions. Take a special "
|
||||
string += "look at the help command, which is in fact a "
|
||||
string += "state-only version of the normal help."
|
||||
state = TSTATE1
|
||||
elif arg == '2':
|
||||
string += "all global commands. You should be able to do "
|
||||
string += "everything as normal, but not move around."
|
||||
state = TSTATE2
|
||||
elif arg == '3':
|
||||
string += "the global commands 'inv' and 'get' only."
|
||||
state = TSTATE3
|
||||
elif arg == '4':
|
||||
string += "all global commands *except* 'inv' and 'get' (try "
|
||||
string += "using them). \nThis allows you to disable commands that "
|
||||
string += "should not be possible at a certain time (like starting "
|
||||
string += "to craft while in the middle of a fight or something)."
|
||||
state = TSTATE4
|
||||
elif arg == '5':
|
||||
string += "all global commands as well as the ability to traverse "
|
||||
string += "exits. You do not have the ability to use commands "
|
||||
string += "defined on objects though."
|
||||
state = TSTATE5
|
||||
elif arg == '6':
|
||||
string += "no globals at all, but you have the ability to both "
|
||||
string += "use exits and commands on items. \nThis would maybe be "
|
||||
string += "interesting for a 'total darkness' state or maybe a "
|
||||
string += "'panic' state where you can move around but cannot "
|
||||
string += "actually take in your surroundings."
|
||||
state = TSTATE6
|
||||
else:
|
||||
source_object.emit_to("Usage: enterstate 1 - 6")
|
||||
return
|
||||
#set the state
|
||||
source_object.set_state(state)
|
||||
info = "%s\n (Now in state %s: '%s' ... use @exit to leave the state.)"
|
||||
source_object.emit_to(info % (string, arg, state))
|
||||
#
|
||||
# define a simple command to include in all states.
|
||||
#
|
||||
def cmd_instate_cmd(command):
|
||||
"""
|
||||
test
|
||||
|
||||
Usage:
|
||||
test
|
||||
|
||||
This is the help text for the test command (created with the
|
||||
auto_help sytem). This is a state-only command that does not
|
||||
exist outside this state. Since this state is completely isolated
|
||||
from the normal gameplay, commands can also harmlessly redefine
|
||||
any normal command - so if there was a normal command named
|
||||
'test', it would remain unchanged when we leave the state.
|
||||
"""
|
||||
command.source_object.emit_to("This state command (test) works!")
|
||||
|
||||
#
|
||||
# Create the test states
|
||||
#
|
||||
|
||||
#define some global commands to filter for
|
||||
CMDFILTER = ['get', 'inventory']
|
||||
|
||||
#1: A simple, basic state with no global commands
|
||||
GLOBAL_STATE_TABLE.add_state(TSTATE1, exit_command=True)
|
||||
|
||||
#2: Include all normal commands in the state
|
||||
GLOBAL_STATE_TABLE.add_state(TSTATE2, exit_command=True, global_cmds='all')
|
||||
|
||||
#3: Include only the two global commands in cmdfilter
|
||||
GLOBAL_STATE_TABLE.add_state(TSTATE3, exit_command=True,
|
||||
global_cmds='include', global_filter=CMDFILTER)
|
||||
|
||||
#4: Include all global commands except the ones in cmdfilter
|
||||
GLOBAL_STATE_TABLE.add_state(TSTATE4, exit_command=True,
|
||||
global_cmds='exclude', global_filter=CMDFILTER)
|
||||
|
||||
#5: Include all global commands + ability to traverse exits
|
||||
GLOBAL_STATE_TABLE.add_state(TSTATE5, exit_command=True,
|
||||
global_cmds='all',
|
||||
allow_exits=True)
|
||||
|
||||
#6: No global commands, allow exits and commands defined on objects.
|
||||
GLOBAL_STATE_TABLE.add_state(TSTATE6, exit_command=True,
|
||||
allow_exits=True, allow_obj_cmds=True)
|
||||
|
||||
#append the "test" function to all states
|
||||
GLOBAL_STATE_TABLE.add_command(TSTATE1, 'test', cmd_instate_cmd)
|
||||
GLOBAL_STATE_TABLE.add_command(TSTATE2, 'test', cmd_instate_cmd)
|
||||
GLOBAL_STATE_TABLE.add_command(TSTATE3, 'test', cmd_instate_cmd)
|
||||
GLOBAL_STATE_TABLE.add_command(TSTATE4, 'test', cmd_instate_cmd)
|
||||
GLOBAL_STATE_TABLE.add_command(TSTATE5, 'test', cmd_instate_cmd)
|
||||
GLOBAL_STATE_TABLE.add_command(TSTATE6, 'test', cmd_instate_cmd)
|
||||
|
||||
#create the entry function for testing all states
|
||||
GLOBAL_CMD_TABLE.add_command('@teststate', cmd_test_state)
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue