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:
Griatch 2010-08-29 18:46:58 +00:00
parent df29defbcd
commit f83c2bddf8
222 changed files with 22304 additions and 14371 deletions

View 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())

View file

@ -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)

View file

@ -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)

View file

@ -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)