cleanup and revisions
This commit is contained in:
parent
ce41753cde
commit
0d50f9bcf8
4 changed files with 70 additions and 30 deletions
|
|
@ -8,8 +8,8 @@ This contrib is designed to be used in MULTISESSION_MODE = 2 or higher, where ch
|
||||||
In your game folder `commands/default_cmdsets.py`, import and add `ContribCmdCharCreate` to your `AccountCmdSet`.
|
In your game folder `commands/default_cmdsets.py`, import and add `ContribCmdCharCreate` to your `AccountCmdSet`.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```py
|
```python
|
||||||
from evennia.contrib.base_systems.character_creator.character_creator import ContribCmdCharCreate
|
from evennia.contrib.rpg.character_creator.character_creator import ContribCmdCharCreate
|
||||||
|
|
||||||
class AccountCmdSet(default_cmds.AccountCmdSet):
|
class AccountCmdSet(default_cmds.AccountCmdSet):
|
||||||
|
|
||||||
|
|
@ -23,18 +23,21 @@ In your game folder `typeclasses/accounts.py`, import and inherit from `ContribC
|
||||||
(Alternatively, you can copy the `at_look` method directly into your own class.)
|
(Alternatively, you can copy the `at_look` method directly into your own class.)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```py
|
```python
|
||||||
from evennia.contrib.base_systems.character_creator.character_creator import ContribChargenAccount
|
from evennia.contrib.rpg.character_creator.character_creator import ContribChargenAccount
|
||||||
|
|
||||||
class Account(ContribChargenAccount):
|
class Account(ContribChargenAccount):
|
||||||
# your Account class code
|
# your Account class code
|
||||||
```
|
```
|
||||||
|
|
||||||
Lastly, in your `settings.py` file, define `CHARGEN_MENU` to your character creation menu module's location.
|
By default, the new `charcreate` command will reference the example menu provided by the contrib, so you can test it
|
||||||
|
out before building your own menu. You can reference [the example menu here]() for ideas on how to build your own.
|
||||||
|
|
||||||
Example:
|
Once you have your own menu, just add it to your settings to use it. e.g. if your menu is in mygame/word/chargen_menu.py,
|
||||||
```py
|
you'd add the following to your settings file:
|
||||||
CHARGEN_MENU = "evennia.contrib.base_systems.character_creator.example_menu"
|
|
||||||
|
```python
|
||||||
|
CHARGEN_MENU = "world.chargen_menu"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
@ -75,7 +78,7 @@ The contrib overrides the character creation command - `charcreate` - to use a c
|
||||||
### Changes to `Account.at_look`
|
### Changes to `Account.at_look`
|
||||||
|
|
||||||
The contrib version works mostly the same as core evennia, but adds an additional check to recognize an in-progress character. If you've modified your own `at_look` hook, it's an easy addition to make: just add this section to the playable character list loop.
|
The contrib version works mostly the same as core evennia, but adds an additional check to recognize an in-progress character. If you've modified your own `at_look` hook, it's an easy addition to make: just add this section to the playable character list loop.
|
||||||
```py
|
```python
|
||||||
for char in characters:
|
for char in characters:
|
||||||
# contrib code starts here
|
# contrib code starts here
|
||||||
if char.db.chargen_step:
|
if char.db.chargen_step:
|
||||||
|
|
@ -27,7 +27,11 @@ from evennia.objects.models import ObjectDB
|
||||||
from evennia.utils import create, search
|
from evennia.utils import create, search
|
||||||
from evennia.utils.evmenu import EvMenu
|
from evennia.utils.evmenu import EvMenu
|
||||||
|
|
||||||
_CHARACTER_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
|
_CHARACTER_TYPECLASS = settings.BASE_CHARACTER_TYPECLASS
|
||||||
|
try:
|
||||||
|
_CHARGEN_MENU = settings.CHARGEN_MENU
|
||||||
|
except AttributeError:
|
||||||
|
_CHARGEN_MENU = "evennia.contrib.rpg.character_creator.example_menu"
|
||||||
|
|
||||||
class ContribCmdCharCreate(MuxAccountCommand):
|
class ContribCmdCharCreate(MuxAccountCommand):
|
||||||
"""
|
"""
|
||||||
|
|
@ -97,7 +101,7 @@ class ContribCmdCharCreate(MuxAccountCommand):
|
||||||
account.execute_cmd("ic {}".format(char.key))
|
account.execute_cmd("ic {}".format(char.key))
|
||||||
|
|
||||||
EvMenu(session,
|
EvMenu(session,
|
||||||
settings.CHARGEN_MENU,
|
_CHARGEN_MENU,
|
||||||
startnode=startnode,
|
startnode=startnode,
|
||||||
cmd_on_exit=finish_char_callback)
|
cmd_on_exit=finish_char_callback)
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ def menunode_welcome(caller):
|
||||||
game wiki if you have one.
|
game wiki if you have one.
|
||||||
""")
|
""")
|
||||||
help = "You can explain the commands for exiting and resuming more specifically here."
|
help = "You can explain the commands for exiting and resuming more specifically here."
|
||||||
options = [{"desc": "Let's begin!", "goto": "menunode_info_base"}]
|
options = {"desc": "Let's begin!", "goto": "menunode_info_base"}
|
||||||
return (text, help), options
|
return (text, help), options
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -231,7 +231,6 @@ def _set_category_opt(caller, raw_string, category, value, **kwargs):
|
||||||
# go back to the base node for the categories choice to pick another
|
# go back to the base node for the categories choice to pick another
|
||||||
return "menunode_categories"
|
return "menunode_categories"
|
||||||
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# Multiple Choice
|
# Multiple Choice
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|
@ -301,6 +300,18 @@ def _set_multichoice(caller, raw_string, selected=[], **kwargs):
|
||||||
return ("menunode_multi_choice", {"selected": selected})
|
return ("menunode_multi_choice", {"selected": selected})
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################
|
||||||
|
# Simple List Options
|
||||||
|
#########################################################
|
||||||
|
|
||||||
|
# If you just want a straightforward list of options, without any of the
|
||||||
|
# back-and-forth navigation or modifying of option text, evennia has an
|
||||||
|
# easy to use decorator available: `@list_node`
|
||||||
|
|
||||||
|
# For an example of how to use it, check out the documentation for
|
||||||
|
# evennia.utils.evmenu - there's lots of other useful EvMenu tools too!
|
||||||
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# Starting Objects
|
# Starting Objects
|
||||||
#########################################################
|
#########################################################
|
||||||
|
|
@ -381,47 +392,69 @@ def menunode_choose_name(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
# another decision, so save the resume point
|
# another decision, so save the resume point
|
||||||
char.db.chargen_step = "menunode_choose_name"
|
char.db.chargen_step = "menunode_choose_name"
|
||||||
|
|
||||||
text = dedent("""\
|
# check if an error message was passed to the node. if so, you'll want to include it
|
||||||
|
# into your "name prompt" at the end of the node text.
|
||||||
|
if error := kwargs.get("error"):
|
||||||
|
prompt_text = f"{error}. Enter a different name."
|
||||||
|
else:
|
||||||
|
# there was no error, so just ask them to enter a name.
|
||||||
|
prompt_text = "Enter a name here to check if it's available."
|
||||||
|
|
||||||
|
# this will print every time the player is prompted to choose a name,
|
||||||
|
# including the prompt text defined above
|
||||||
|
text = dedent(f"""\
|
||||||
|wChoosing a Name|n
|
|wChoosing a Name|n
|
||||||
|
|
||||||
Especially for roleplaying-centric games, being able to choose your
|
Especially for roleplaying-centric games, being able to choose your
|
||||||
character's name after deciding everything else, instead of before,
|
character's name after deciding everything else, instead of before,
|
||||||
is really useful.
|
is really useful.
|
||||||
|
|
||||||
Enter a name here to check if it's available.
|
{prompt_text}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
help = "You'll have a chance to change your mind before confirming, even if the name is free."
|
help = "You'll have a chance to change your mind before confirming, even if the name is free."
|
||||||
# since this is a free-text field, we just have the one
|
# since this is a free-text field, we just have the one
|
||||||
options = [ { "key": "_default", "goto": "menunode_check_charname" } ]
|
options = { "key": "_default", "goto": "_check_charname" }
|
||||||
return (text, help), options
|
return (text, help), options
|
||||||
|
|
||||||
def menunode_check_charname(caller, raw_string, **kwargs):
|
def _check_charname(caller, raw_string, **kwargs):
|
||||||
"""Check and confirm name choice"""
|
"""Check and confirm name choice"""
|
||||||
|
|
||||||
# strip any extraneous whitespace from the raw text
|
# strip any extraneous whitespace from the raw text
|
||||||
# if you want to do any other validation on the name, e.g. no punctuation allowed, this is the place!
|
# if you want to do any other validation on the name, e.g. no punctuation allowed, this is the place!
|
||||||
charname = raw_string.strip()
|
charname = raw_string.strip()
|
||||||
|
|
||||||
|
# aside from validation, the built-in normalization function from the caller's Account does
|
||||||
|
# some useful cleanup on the input, just in case they try something sneaky
|
||||||
|
charname = caller.account.normalize_username(charname)
|
||||||
|
|
||||||
# check to make sure that the name doesn't already exist
|
# check to make sure that the name doesn't already exist
|
||||||
candidates = Character.objects.filter_family(db_key__iexact=charname)
|
candidates = Character.objects.filter_family(db_key__iexact=charname)
|
||||||
if len(candidates):
|
if len(candidates):
|
||||||
# the name is already taken - loop this node with new input to enter another name
|
# the name is already taken - report back with the error
|
||||||
text = f"|w{charname}|n is unavailable.\n\nEnter a different name."
|
return ("menunode_choose_name", {"error": f"|w{charname}|n is unavailable.\n\nEnter a different name."})
|
||||||
options = [ { "key": "_default", "goto": "menunode_check_charname" } ]
|
|
||||||
return text, options
|
|
||||||
else:
|
else:
|
||||||
# it's free! set the character's key to the name to reserve it
|
# it's free! set the character's key to the name to reserve it
|
||||||
caller.new_char.key = charname
|
caller.new_char.key = charname
|
||||||
text = f"|w{charname}|n is available! Confirm?"
|
# continue on to the confirmation node
|
||||||
# let players change their mind and go back to the name choice, if they want
|
return "menunode_confirm_name"
|
||||||
options = [
|
|
||||||
{ "key": ("Yes", "y"), "goto": "menunode_end" },
|
def menunode_confirm_name(caller, raw_string, **kwargs):
|
||||||
{ "key": ("No", "n"), "goto": "menunode_choose_name" },
|
"""Confirm the name choice"""
|
||||||
]
|
char = caller.new_char
|
||||||
return text, options
|
|
||||||
|
# since we reserved the name by assigning it, you can reference the character key
|
||||||
|
# if you have any extra validation or normalization that changed the player's input
|
||||||
|
# this also serves to show the player exactly what name they'll get
|
||||||
|
text = f"|w{char.key}|n is available! Confirm?"
|
||||||
|
# let players change their mind and go back to the name choice, if they want
|
||||||
|
options = [
|
||||||
|
{ "key": ("Yes", "y"), "goto": "menunode_end" },
|
||||||
|
{ "key": ("No", "n"), "goto": "menunode_choose_name" },
|
||||||
|
]
|
||||||
|
return text, options
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# The End
|
# The End
|
||||||
Loading…
Add table
Add a link
Reference in a new issue