diff --git a/evennia/contrib/barter.py b/evennia/contrib/barter.py
index 1fd5a51f76..9430501fef 100644
--- a/evennia/contrib/barter.py
+++ b/evennia/contrib/barter.py
@@ -104,7 +104,9 @@ class TradeTimeout(DefaultScript):
This times out the trade request, in case player B did not reply in time.
"""
def at_script_creation(self):
- "called when script is first created"
+ """
+ Called when script is first created
+ """
self.key = "trade_request_timeout"
self.desc = "times out trade requests"
self.interval = TRADE_TIMEOUT
@@ -113,13 +115,17 @@ class TradeTimeout(DefaultScript):
self.persistent = False
def at_repeat(self):
- "called once"
+ """
+ called once
+ """
if self.ndb.tradeevent:
self.obj.ndb.tradeevent.finish(force=True)
self.obj.msg("Trade request timed out.")
def is_valid(self):
- "Only valid if the trade has not yet started"
+ """
+ Only valid if the trade has not yet started
+ """
return self.obj.ndb.tradeevent and not self.obj.ndb.tradeevent.trade_started
@@ -130,12 +136,19 @@ class TradeHandler(object):
"""
def __init__(self, partA, partB):
"""
- Initializes the trade. This is called when part A tries to initiate
- a trade with part B. The trade will not start until part B repeats
- this command (B will then call the self.join() command)
+ Initializes the trade. This is called when part A tries to
+ initiate a trade with part B. The trade will not start until
+ part B repeats this command (B will then call the self.join()
+ command)
+
+ Args:
+ partA (object): The party trying to start barter.
+ partB (object): The party asked to barter.
+
+ Notes:
+ We also store the back-reference from the respective party
+ to this object.
- We also store the back-reference from the respective party to
- this object.
"""
# parties
self.partA = partA
@@ -152,9 +165,14 @@ class TradeHandler(object):
def msg(self, party, string):
"""
- Relay a message to the other party. This allows
- the calling command to not have to worry about
- which party they are in the handler.
+ Relay a message to the other party. This allows the calling
+ command to not have to worry about which party they are in the
+ handler.
+
+ Args:
+ party (object): One of partA or B. The method will figure
+ out which is which.
+ string (str): Text to send.
"""
if self.partA == party:
self.partB.msg(string)
@@ -165,7 +183,16 @@ class TradeHandler(object):
self.party.msg(string)
def get_other(self, party):
- "Returns the other party of the trade"
+ """
+ Returns the other party of the trade
+
+ Args:
+ partyX (object): One of the parties of the negotiation
+
+ Returns:
+ partyY (object): The other party, not partyX.
+
+ """
if self.partA == party:
return self.partB
if self.partB == party:
@@ -175,6 +202,10 @@ class TradeHandler(object):
def join(self, partB):
"""
This is used once B decides to join the trade
+
+ Args:
+ partB (object): The party accepting the barter.
+
"""
print "join:", self.partB, partB, self.partB == partB, type(self.partB), type(partB)
if self.partB == partB:
@@ -186,7 +217,11 @@ class TradeHandler(object):
def unjoin(self, partB):
"""
- This is used if B decides not to join the trade
+ This is used if B decides not to join the trade.
+
+ Args:
+ partB (object): The party leaving the barter.
+
"""
if self.partB == partB:
self.finish()
@@ -198,6 +233,11 @@ class TradeHandler(object):
Change the current standing offer. We leave it up to the
command to do the actual checks that the offer consists
of real, valid, objects.
+
+ Args:
+ party (object): Who is making the offer
+ args (objects or str): Offerings.
+
"""
if self.trade_started:
# reset accept statements whenever an offer changes
@@ -212,15 +252,25 @@ class TradeHandler(object):
def list(self):
"""
- Returns two lists of objects on offer, separated by partA/B.
+ List current offers.
+
+ Returns:
+ offers (tuple): A tuple with two lists, (A_offers, B_offers).
+
"""
return self.partA_offers, self.partB_offers
def search(self, offername):
"""
- Returns an object on offer, based on a search criterion.
- If the search criterion is an integer, treat it as an
- index to return in the list of offered items
+ Search current offers.
+
+ Args:
+ offername (str or int): Object to search for, or its index in
+ the list of offered items.
+
+ Returns:
+ offer (object): An object on offer, based on the search criterion.
+
"""
all_offers = self.partA_offers + self.partB_offers
if isinstance(offername, int):
@@ -242,7 +292,18 @@ class TradeHandler(object):
"""
Accept the current offer.
- Returns True if this closes the deal, False otherwise
+ Args:
+ party (object): The party accepting the deal.
+
+ Returns:
+ result (object): `True` if this closes the deal, `False`
+ otherwise
+
+ Notes:
+ This will only close the deal if both parties have
+ accepted independently. This is done by calling the
+ `finish()` method.
+
"""
if self.trade_started:
if party == self.partA:
@@ -255,9 +316,20 @@ class TradeHandler(object):
def decline(self, party):
"""
- Remove an previously accepted status (changing ones mind)
+ Decline the offer (or change one's mind).
+
+ Args:
+ party (object): Party declining the deal.
+
+ Returns:
+ did_decline (bool): `True` if there was really an
+ `accepted` status to change, `False` otherwise.
+
+ Notes:
+ If previously having used the `accept` command, this
+ function will only work as long as the other party has not
+ yet accepted.
- returns True if there was really a status to change, False otherwise.
"""
if self.trade_started:
if party == self.partA:
@@ -276,6 +348,12 @@ class TradeHandler(object):
def finish(self, force=False):
"""
Conclude trade - move all offers and clean up
+
+ Args:
+ force (bool, optional): Force cleanup regardless of if the
+ trade was accepted or not (if not, no goods will change
+ hands but trading will stop anyway)
+
"""
fin = False
if self.trade_started and self.partA_accepted and self.partB_accepted:
@@ -303,8 +381,8 @@ class TradeHandler(object):
class CmdTradeBase(Command):
"""
- Base command for Trade commands to inherit from. Implements
- the custom parsing.
+ Base command for Trade commands to inherit from. Implements the
+ custom parsing.
"""
def parse(self):
"""
diff --git a/evennia/contrib/chargen.py b/evennia/contrib/chargen.py
index 6f470873ed..683edd6c0f 100644
--- a/evennia/contrib/chargen.py
+++ b/evennia/contrib/chargen.py
@@ -2,9 +2,9 @@
Contribution - Griatch 2011
-[Note - with the advent of MULTISESSION_MODE=2, this is not really
-as necessary anymore - the ooclook and @charcreate commands in that
-mode replaces this module with better functionality.]
+[Note - with the advent of MULTISESSION_MODE=2, this is not really as
+necessary anymore - the ooclook and @charcreate commands in that mode
+replaces this module with better functionality.]
This is a simple character creation commandset. A suggestion is to
test this together with menu_login, which doesn't create a Character
@@ -18,11 +18,11 @@ while puppeting a Character already before.
Installation:
-Read the instructions in contrib/examples/cmdset.py in
-order to create a new default cmdset module for Evennia to use (copy
-the template up one level, and change the settings file's relevant
-variables to point to the cmdsets inside). If you already have such
-a module you should of course use that.
+Read the instructions in contrib/examples/cmdset.py in order to create
+a new default cmdset module for Evennia to use (copy the template up
+one level, and change the settings file's relevant variables to point
+to the cmdsets inside). If you already have such a module you should
+of course use that.
Next import this module in your custom cmdset module and add the
following line to the end of OOCCmdSet's at_cmdset_creation():
diff --git a/evennia/contrib/dice.py b/evennia/contrib/dice.py
index 9845e5f965..ce943e0530 100644
--- a/evennia/contrib/dice.py
+++ b/evennia/contrib/dice.py
@@ -4,8 +4,8 @@ Dice - rolls dice for roleplaying, in-game gambling or GM:ing
Evennia contribution - Griatch 2012
-This module implements a full-fledged dice-roller and a 'dice' command to
-go with it. It uses standard RPG 'd'-syntax (e.g. 2d6 to roll two
+This module implements a full-fledged dice-roller and a 'dice' command
+to go with it. It uses standard RPG 'd'-syntax (e.g. 2d6 to roll two
six-sided die) and also supports modifiers such as 3d6 + 5.
One can also specify a standard Python operator in order to specify
@@ -39,31 +39,53 @@ def roll_dice(dicenum, dicetype, modifier=None, conditional=None, return_tuple=F
"""
This is a standard dice roller.
- Input:
- dicenum - number of dice to roll (the result to be added)
- dicetype - number of sides of the dice to be rolled
- modifier - tuple (operator, value), where operator is a character string
- with one of +,-,/ or *. The entire result of the dice rolls will
- be modified by this value.
- conditional - tuple (conditional, value), where conditional is a character
- string with one of ==,<,>,>=,<= or !=.
- return_tuple - return result as a tuple containing all relevant info
- return_tuple - (default False) - return a tuple with all individual roll
- results
- All input numbers are converted to integers.
+ Args:
+ dicenum (int): Number of dice to roll (the result to be added).
+ dicetype (int): Number of sides of the dice to be rolled.
+ modifier (tuple): A tuple `(operator, value)`, where operator is
+ one of `"+"`, `"-"`, `"/"` or `"*"`. The result of the dice
+ roll(s) will be modified by this value.
+ conditional (tuple): A tuple `(conditional, value)`, where
+ conditional is one of `"=="`,`"<"`,`">"`,`">="`,`"<=`" or "`!=`".
+ This allows the roller to directly return a result depending
+ on if the conditional was passed or not.
+ return_tuple (bool): Return a tuple with all individual roll
+ results or not.
Returns:
- normally returns the result
- if return_tuple=True, returns a tuple (result, outcome, diff, rolls)
- In this tuple, outcome and diff will be None if conditional is
- not set. rolls is itself a tuple holding all the individual
- rolls in the case of multiple die-rolls.
+ roll_result (int): The result of the roll + modifiers. This is the
+ default return.
+ condition_result (bool): A True/False value returned if `conditional`
+ is set but not `return_tuple`. This effectively hides the result
+ of the roll.
+ full_result (tuple): If, return_tuple` is `True`, instead
+ return a tuple `(result, outcome, diff, rolls)`. Here,
+ `result` is the normal result of the roll + modifiers.
+ `outcome` and `diff` are the boolean result of the roll and
+ absolute difference to the `conditional` input; they will
+ be will be `None` if `conditional` is not set. `rolls` is
+ itself a tuple holding all the individual rolls in the case of
+ multiple die-rolls.
Raises:
TypeError if non-supported modifiers or conditionals are given.
+ Notes:
+ All input numbers are converted to integers.
+
+ Examples:
+ print roll_dice(2, 6) # 2d6
+ <<< 7
+ print roll_dice(1, 100, ('+', 5) # 1d100 + 5
+ <<< 34
+ print roll_dice(1, 20, conditional=('<', 10) # let'say we roll 3
+ <<< True
+ print roll_dice(3, 10, return_tuple=True)
+ <<< (11, None, None, (2, 5, 4))
+ print roll_dice(2, 20, ('-', 2), conditional=('>=', 10), return_tuple=True)
+ <<< (8, False, 2, (4, 6)) # roll was 4 + 6 - 2 = 8
+
"""
- dicelimit = 0 # This is the maximum number of dice that can be used in a single roll.
dicenum = int(dicenum)
dicetype = int(dicetype)
@@ -90,7 +112,10 @@ def roll_dice(dicenum, dicetype, modifier=None, conditional=None, return_tuple=F
if return_tuple:
return (result, outcome, diff, rolls)
else:
- return result
+ if conditional:
+ return outcome
+ else:
+ return result
RE_PARTS = re.compile(r"(d|\+|-|/|\*|<|>|<=|>=|!=|==)")
RE_MOD = re.compile(r"(\+|-|/|\*)")
diff --git a/evennia/contrib/extended_room.py b/evennia/contrib/extended_room.py
index 7f51e9cd51..5c1544fefa 100644
--- a/evennia/contrib/extended_room.py
+++ b/evennia/contrib/extended_room.py
@@ -158,8 +158,16 @@ class ExtendedRoom(DefaultRoom):
def replace_timeslots(self, raw_desc, curr_time):
"""
- Filter so that only time markers `...` of the
- correct timeslot remains in the description.
+ Filter so that only time markers `...` of
+ the correct timeslot remains in the description.
+
+ Args:
+ raw_desc (str): The unmodified description.
+ curr_time (str): A timeslot identifier.
+
+ Returns:
+ description (str): A possibly moified description.
+
"""
if raw_desc:
regextuple = REGEXMAP[curr_time]
@@ -171,14 +179,24 @@ class ExtendedRoom(DefaultRoom):
def return_detail(self, key):
"""
- This will attempt to match a "detail" to look for in the room. A detail
- is a way to offer more things to look at in a room without having to
- add new objects. For this to work, we require a custom `look` command that
- allows for `look ` - the look command should defer to this
- method on the current location (if it exists) before giving up on
- finding the target.
+ This will attempt to match a "detail" to look for in the room.
- Details are not season-sensitive, but are parsed for timeslot markers.
+ Args:
+ key (str): A detail identifier.
+
+ Returns:
+ detail (str or None): A detail mathing the given key.
+
+ Notes:
+ A detail is a way to offer more things to look at in a room
+ without having to add new objects. For this to work, we
+ require a custom `look` command that allows for `look
+ ` - the look command should defer to this method on
+ the current location (if it exists) before giving up on
+ finding the target.
+
+ Details are not season-sensitive, but are parsed for timeslot
+ markers.
"""
try:
detail = self.db.details.get(key.lower(), None)
@@ -192,7 +210,17 @@ class ExtendedRoom(DefaultRoom):
return None
def return_appearance(self, looker):
- "This is called when e.g. the look command wants to retrieve the description of this object."
+ """
+ This is called when e.g. the look command wants to retrieve
+ the description of this object.
+
+ Args:
+ looker (Object): The object looking at us.
+
+ Returns:
+ description (str): Our description.
+
+ """
raw_desc = self.db.raw_desc or ""
update = False
diff --git a/evennia/contrib/gendersub.py b/evennia/contrib/gendersub.py
index 6b21fb2ebd..0d137ee082 100644
--- a/evennia/contrib/gendersub.py
+++ b/evennia/contrib/gendersub.py
@@ -8,8 +8,8 @@ insert custom markers in their text to indicate gender-aware
messaging. It relies on a modified msg() and is meant as an
inspiration and starting point to how to do stuff like this.
-When in use, all messages being sent to the character will make use
-of the character's gender, for example the echo
+When in use, all messages being sent to the character will make use of
+the character's gender, for example the echo
```
char.msg("%s falls on {p face with a thud." % char.key)
diff --git a/evennia/contrib/menu_login.py b/evennia/contrib/menu_login.py
index 1355345552..4bcc491338 100644
--- a/evennia/contrib/menu_login.py
+++ b/evennia/contrib/menu_login.py
@@ -19,8 +19,10 @@ CMDSET_UNLOGGEDIN = "contrib.menu_login.UnloggedInCmdSet"
That's it. Reload the server and try to log in to see it.
-The initial login "graphic" is taken from strings in the module given
-by settings.CONNECTION_SCREEN_MODULE.
+You will want to change the login "graphic", which defaults to give
+information about commands which are not used in this version of the
+login. You can change the screen used by editing
+`mygame/server/conf/connection_screens.py`.
"""
diff --git a/evennia/contrib/menusystem.py b/evennia/contrib/menusystem.py
index f40db50b84..cfeaeffa36 100644
--- a/evennia/contrib/menusystem.py
+++ b/evennia/contrib/menusystem.py
@@ -11,14 +11,29 @@ in one or more columns.
The menu system consists of a MenuTree object populated by MenuNode
objects. Nodes are linked together with automatically created commands
so the player may select and traverse the menu. Each node can display
-text and show options, but also execute arbitrary code to act on the
+text and show options, but also execute a callback to act on the
system and the calling object when they are selected.
-There is also a simple Yes/No function supplied. This will create a
-one-off Yes/No question and executes a given code depending on which
-choice was made.
+There is also a simple Yes/No function as well as a one-level choice
+function supplied. This will create a one-off Yes/No question or a
+one-level choice. These helpers will execute a given callback
+depending on which choice was made.
-To test, add this to the default cmdset
+To start a menu, define the nodes of the menu and then add the
+following to a command `func` you can call:
+
+```python
+
+menu = MenuTree(self.caller, nodes=(...))
+menu.start()
+
+```
+
+This will switch you into menu-mode. See `contrib/menu_login.py` for an
+example of usage.
+
+
+For a simple demonstration, add `CmdMenuTest` from this module to the default cmdset.
"""
from types import MethodType
@@ -49,8 +64,6 @@ class CmdMenuNode(Command):
menutree = None
callback = None
- # deprecated
- code = None
def func(self):
"Execute a selection"
@@ -60,12 +73,6 @@ class CmdMenuNode(Command):
self.callback()
except Exception, e:
self.caller.msg("%s\n{rThere was an error with this selection.{n" % e)
- elif self.code:
- evennia.logger.log_depmsg("menusystem.code is deprecated. Use menusystem.func.")
- try:
- exec(self.code)
- except Exception, e:
- self.caller.msg("%s\n{rThere was an error with this selection.{n" % e)
else:
self.caller.msg("{rThis option is not available.{n")
@@ -173,8 +180,19 @@ class MenuTree(object):
enter and where to exit the menu tree. If nodes is given, it
should be a list of valid node objects to add to the tree.
- exec_end - if not None, will execute the given command string
- directly after the menu system has been exited.
+ caller (Object): The caller triggering the menu
+ nodes (tuple, optional): A tuple of `MenuNode` objects. This need
+ not be in any particular order.
+ startnode (str, optional): The key of the first `MenuNode` to jump
+ to when starting the menu. Defaults to "START".
+ endnode (str, optional): The key of the end node. When
+ instructed to go to this node (by any means), the menu
+ will be gracefully exited. Defaults to "END".
+ exec_end (str, optional): If not `None`, this command name will be executed
+ directly after the menu system has been exited. It is
+ normally useful for making sure the user realizes their UI
+ mode has changed.
+
"""
self.tree = {}
self.startnode = startnode
@@ -187,7 +205,8 @@ class MenuTree(object):
def start(self):
"""
- Initialize the menu
+ Initialize the menu and go to the starting node.
+
"""
self.goto(self.startnode)
@@ -195,6 +214,9 @@ class MenuTree(object):
"""
Add a menu node object to the tree. Each node itself keeps
track of which nodes it is connected to.
+
+ Args:
+ menunode (MenuNode): The node to add.
"""
self.tree[menunode.key] = menunode
@@ -202,6 +224,10 @@ class MenuTree(object):
"""
Go to a key in the tree. This sets up the cmdsets on the
caller so that they match the choices in that node.
+
+ Args:
+ key (str): The node-key to go to.
+
"""
if key == self.endnode:
# if we was given the END node key, we clean up immediately.
@@ -210,7 +236,7 @@ class MenuTree(object):
if self.exec_end is not None:
self.caller.execute_cmd(self.exec_end)
return
- # not exiting, look for a valid code.
+ # not exiting, look for a valid node
node = self.tree.get(key, None)
# make caller available on node
node.caller = self.caller
@@ -222,13 +248,6 @@ class MenuTree(object):
except Exception:
logger.log_trace()
self.caller.msg("{rNode callback could not be executed for node %s. Continuing anyway.{n" % key)
- if node.code:
- # Execute eventual code active on this node. self.caller is available at this point.
- evennia.logger.log_depmsg("menusystem.code is deprecated. Use menusystem.callback.")
- try:
- exec(node.code)
- except Exception:
- self.caller.msg("{rCode could not be executed for node %s. Continuing anyway.{n" % key)
# initialize - this creates new cmdset
node.init(self)
# clean old menu cmdset and replace with the new one
@@ -252,42 +271,48 @@ class MenuNode(object):
"""
def __init__(self, key, text="", links=None, linktexts=None,
keywords=None, cols=1, helptext=None,
- selectcmds=None, callback=None, code="", nodefaultcmds=False, separator=""):
+ selectcmds=None, callback=None, nodefaultcmds=False, separator=""):
"""
- key - the unique identifier of this node.
- text - is the text that will be displayed at top when viewing this
- node.
- links - a list of keys for unique menunodes this is connected to.
- The actual keys will not printed - keywords will be used
- (or a number)
- linktexts - an optional list of texts to describe the links. Must
- match link list if defined. Entries can be None to not
- generate any extra text for a particular link.
- keywords - an optional list of unique keys for choosing links. Must
- match links list. If not given, index numbers will be used.
- Also individual list entries can be None and will be replaed
- by indices. If CMD_NOMATCH or CMD_NOENTRY, no text will be
- generated to indicate the option exists.
- cols - how many columns to use for displaying options.
- helptext - if defined, this is shown when using the help command
- instead of the normal help index.
- selectcmds- a list of custom cmdclasses for handling each option.
- Must match links list, but some entries may be set to None
- to use default menu cmds. The given command's key will be
- used for the menu list entry unless it's CMD_NOMATCH or
- CMD_NOENTRY, in which case no text will be generated. These
- commands have access to self.menutree and so can be used to
- select nodes.
- code - functional code. Deprecated. This will be executed just before this
- node is loaded (i.e. as soon after it's been selected from
- another node). self.caller is available to call from this
- code block, as well as the evennia flat API.
- callback - function callback. This will be called as callback(currentnode) just
- before this node is loaded (i.e. as soon as possible as it's
- been selected from another node). currentnode.caller is available.
- nodefaultcmds - if true, don't offer the default help and look commands
- in the node
- separator - this string will be put on the line between menu nodes.
+ Initialize the node.
+
+ Args:
+ key (str): The unique identifier of this node.
+ text (str, optional): The text that will be displayed at
+ top when viewing this node.
+ Kwargs:
+ links (list): A liist of keys for unique menunodes this is connected to.
+ The actual keys will not printed - keywords will be
+ used (or a number)
+ linktexts (list)- A list of texts to describe the links. Must
+ match order of `links` list if defined. Entries can be
+ None to not generate any extra text for a particular
+ link.
+ keywords (list): A list of unique keys for choosing links. Must
+ match links list. If not given, index numbers will be
+ used. Also individual list entries can be None and
+ will be replaed by indices. If CMD_NOMATCH or
+ CMD_NOENTRY, no text will be generated to indicate the
+ option exists.
+ cols (int): How many columns to use for displaying options.
+ helptext (str): If defined, this is shown when using the help command
+ instead of the normal help index.
+ selectcmds (list): A list of custom cmdclasses for
+ handling each option. Must match links list, but some
+ entries may be set to None to use default menu cmds.
+ The given command's key will be used for the menu list
+ entry unless it's CMD_NOMATCH or CMD_NOENTRY, in which
+ case no text will be generated. These commands have
+ access to self.menutree and so can be used to select
+ nodes.
+ callback (function): Function callback. This will be
+ called as callback(currentnode) just before this node is
+ loaded (i.e. as soon as possible as it's been selected
+ from another node). currentnode.caller is available.
+ nodefaultcmds (bool): If `True`, don't offer the default
+ help and look commands in the node
+ separator (str): This string will be put on the line
+ between menu nodes.
+
"""
self.key = key
self.cmdset = None
@@ -296,15 +321,11 @@ class MenuNode(object):
self.keywords = keywords
self.cols = cols
self.selectcmds = selectcmds
- self.code = code
self.callback = MethodType(callback, self, MenuNode) if callback else None
self.nodefaultcmds = nodefaultcmds
self.separator = separator
Nlinks = len(self.links)
- if code:
- evennia.logger.log_depmsg("menusystem.code is deprecated. Use menusystem.callback.")
-
# validate the input
if not self.links:
self.links = []
@@ -399,17 +420,21 @@ class MenuNode(object):
# make use the node system since there is only one level of choice.
#
-def prompt_yesno(caller, question="", yesfunc=None, nofunc=None, yescode="", nocode="", default="N"):
+def prompt_yesno(caller, question="", yesfunc=None, nofunc=None, default="N"):
"""
This sets up a simple yes/no questionnaire. Question will be
asked, followed by a Y/[N] prompt where the [x] signifies the
- default selection. Note that this isn't making use of the menu
- node system.
+ default selection. Note that this isn't actually making use of the
+ menu node system, but does use the MenuCmdSet.
+
+ Args:
+ caller (Object): The object triggering the prompt.
+ question (str, optional): The Yes/No question asked.
+ yesfunc (function, optional): Callback for a Yes answer.
+ nofunc (functionm optional): Callback for a No answer.
+ default (str, optional): Default used if caller just hits
+ return. Either `"Y"` or `"N"`
- yesfunc - function callback to be called as yesfunc(self) when choosing yes (self.caller is available)
- nofunc - function callback to be called as yesfunc(self) when choosing no (self.caller is available)
- yescode - deprecated, executable code
- nocode - "
"""
# creating and defining commands
@@ -441,14 +466,6 @@ def prompt_yesno(caller, question="", yesfunc=None, nofunc=None, yescode="", noc
self.caller.execute_cmd('%s' % default)
defaultcmd.callback = MethodType(_defaultcmd, defaultcmd, CmdMenuNode)
- # code exec is deprecated:
- if yescode:
- evennia.logger.log_depmsg("yesnosystem.code is deprecated. Use yesnosystem.callback.")
- cmdyes.code = yescode + "\nself.caller.cmdset.delete('menucmdset')\ndel self.caller.db._menu_data"
- if nocode:
- evennia.logger.log_depmsg("yesnosystem.code is deprecated. Use yesnosystem.callback.")
- cmdno.code = nocode + "\nself.caller.cmdset.delete('menucmdset')\ndel self.caller.db._menu_data"
-
# creating cmdset (this will already have look/help commands)
yesnocmdset = MenuCmdSet()
yesnocmdset.add(cmdyes)
@@ -481,33 +498,57 @@ def prompt_choice(caller, question="", prompts=None, choicefunc=None, force_choo
"""
This sets up a simple choice questionnaire. Question will be
asked, followed by a series of prompts. Note that this isn't
- making use of the menu node system.
+ making use of the menu node system but uses the MenuCmdSet.
+
+ Args:
+ caller (object): The object calling and being offered the choice
+ question (str, optional): Text describing the offered choice
+ prompts (list, optional): List of strings defining the available choises.
+ choicefunc (function, optional): A function called as
+ `choicefunc(self)` when a choice is made. Inside this function,
+ `self.caller` is available and `self.prompt_index` is the index
+ (starting with 0) matching the chosen prompt in the `prompts` list.
+ force_choose - force user to make a choice
+
+ Examples:
+
+ ```python
+ def mychoice(self):
+ self.caller.msg("Index of choice is %s." % self.prompt_index)
+
+ prompt_choice(caller, "Make a choice:", prompts=["A","B","C"], choicefunc=mychoice)
+ ```
+
+ When triggering the above from a command or @py prompt you get the following options:
+
+ >>> Make a choice:
+ [1] A
+ [2] B
+ [3] C
+ <<< 2
+ >>> Index of choice is 1.
- caller - the object calling and being offered the choice
- question - text describing the offered choice
- prompts - list of choices
- choicefunc - functions callback to be called as func(self) when
- make choice (self.caller is available) The function's definition
- should be like func(self, menu_node), and menu_node.key is user's
- choice.
- force_choose - force user to make a choice or not
"""
# creating and defining commands
count = 0
choices = ""
commands = []
+
for choice in utils.make_iter(prompts):
+ # create the available choice-commands
count += 1
choices += "\n{lc%d{lt[%d]{le %s" % (count, count, choice)
cmdfunc = CmdMenuNode(key="%d" % count)
+ cmdfunc.prompt_index = count-1
if choicefunc:
cmdfunc.choicefunc = choicefunc
def _choicefunc(self):
self.caller.cmdset.delete('menucmdset')
del self.caller.db._menu_data
self.choicefunc(self)
+ # set a new method "callback" on cmdfunc
cmdfunc.callback = MethodType(_choicefunc, cmdfunc, CmdMenuNode)
commands.append(cmdfunc)
@@ -517,6 +558,7 @@ def prompt_choice(caller, question="", prompts=None, choicefunc=None, force_choo
prompt = question + choices + "\nPlease choose one."
+ # create the error-reporting command
errorcmd = CmdMenuNode(key=CMD_NOMATCH)
if force_choose:
def _errorcmd(self):
@@ -531,6 +573,7 @@ def prompt_choice(caller, question="", prompts=None, choicefunc=None, force_choo
self.choicefunc(self)
errorcmd.callback = MethodType(_errorcmd, errorcmd, CmdMenuNode)
+ # create the fallback command
defaultcmd = CmdMenuNode(key=CMD_NOINPUT)
if force_choose:
def _defaultcmd(self):
@@ -547,7 +590,8 @@ def prompt_choice(caller, question="", prompts=None, choicefunc=None, force_choo
# creating cmdset (this will already have look/help commands)
choicecmdset = MenuCmdSet()
- for cmdfunc in commands: choicecmdset.add(cmdfunc)
+ for cmdfunc in commands:
+ choicecmdset.add(cmdfunc)
choicecmdset.add(errorcmd)
choicecmdset.add(defaultcmd)
choicecmdset.add(CmdMenuLook())
diff --git a/evennia/contrib/talking_npc.py b/evennia/contrib/talking_npc.py
index 71858df044..7ba7d17946 100644
--- a/evennia/contrib/talking_npc.py
+++ b/evennia/contrib/talking_npc.py
@@ -4,22 +4,19 @@ Evennia Talkative NPC
Contribution - Griatch 2011
-This is a simple NPC object capable of holding a
-simple menu-driven conversation. Create it by
-creating an object of typeclass contrib.talking_npc.TalkingNPC,
-For example using @create:
+This is a simple NPC object capable of holding a simple menu-driven
+conversation. Create it by creating an object of typeclass
+contrib.talking_npc.TalkingNPC, For example using @create:
@create John : contrib.talking_npc.TalkingNPC
-Walk up to it and give the talk command
-to strike up a conversation. If there are many
-talkative npcs in the same room you will get to
-choose which one's talk command to call (Evennia
-handles this automatically).
+Walk up to it and give the talk command to strike up a conversation.
+If there are many talkative npcs in the same room you will get to
+choose which one's talk command to call (Evennia handles this
+automatically).
-Note that this is only a prototype class, showcasing
-the uses of the menusystem module. It is NOT a full
-mob implementation.
+Note that this is only a prototype class, showcasing the uses of the
+menusystem module. It is NOT a full mob implementation.
"""
diff --git a/evennia/contrib/tutorial_examples/bodyfunctions.py b/evennia/contrib/tutorial_examples/bodyfunctions.py
index 26b3340de5..70bdf6de6f 100644
--- a/evennia/contrib/tutorial_examples/bodyfunctions.py
+++ b/evennia/contrib/tutorial_examples/bodyfunctions.py
@@ -1,14 +1,12 @@
"""
-Example script for testing. This adds a simple timer that
-has your character make observations and notices at irregular
-intervals.
+Example script for testing. This adds a simple timer that has your
+character make observations and notices at irregular intervals.
To test, use
@script me = examples.bodyfunctions.BodyFunctions
-The script will only send messages to the object it
-is stored on, so make sure to put it on yourself
-or you won't see any messages!
+The script will only send messages to the object it is stored on, so
+make sure to put it on yourself or you won't see any messages!
"""
import random
diff --git a/evennia/contrib/tutorial_examples/red_button.py b/evennia/contrib/tutorial_examples/red_button.py
index 2f3d961fd6..3b2402c9a0 100644
--- a/evennia/contrib/tutorial_examples/red_button.py
+++ b/evennia/contrib/tutorial_examples/red_button.py
@@ -66,6 +66,7 @@ class RedButton(DefaultObject):
"""
Opens the glass lid and start the timer so it will soon close
again.
+
"""
if self.db.lid_open:
@@ -91,6 +92,7 @@ class RedButton(DefaultObject):
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:
@@ -111,6 +113,9 @@ class RedButton(DefaultObject):
"""
Breaks the lamp in the button, stopping it from blinking.
+ Args:
+ feedback (bool): Show a message about breaking the lamp.
+
"""
self.db.lamp_works = False
desc = self.db.desc_lamp_broken
@@ -126,7 +131,10 @@ class RedButton(DefaultObject):
def press_button(self, pobject):
"""
Someone was foolish enough to press the button!
- pobject - the person pressing the button
+
+ Args:
+ pobject (Object): The person pressing the button
+
"""
# deactivate the button so it won't flash/close lid etc.
self.scripts.add(scriptexamples.DeactivateButtonEvent)