mirror of
https://github.com/evennia/evennia.git
synced 2026-04-02 22:17:17 +02:00
Updated contrib to use the Google style docstrings are per #709. Also
remove long deprecated code-block usage in menusystem - use callback functions instead.
This commit is contained in:
parent
64c6d06d0f
commit
3e9263e207
10 changed files with 352 additions and 172 deletions
|
|
@ -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):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
|
|
|
|||
|
|
@ -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"(\+|-|/|\*)")
|
||||
|
|
|
|||
|
|
@ -158,8 +158,16 @@ class ExtendedRoom(DefaultRoom):
|
|||
|
||||
def replace_timeslots(self, raw_desc, curr_time):
|
||||
"""
|
||||
Filter so that only time markers `<timeslot>...</timeslot>` of the
|
||||
correct timeslot remains in the description.
|
||||
Filter so that only time markers `<timeslot>...</timeslot>` 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 <detail>` - 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
|
||||
<detail>` - 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue