various fixes

This commit is contained in:
InspectorCaracal 2022-08-25 11:51:33 -06:00
parent 615809ce05
commit df996885bc
3 changed files with 27 additions and 28 deletions

View file

@ -70,10 +70,10 @@ class ContribCmdCharCreate(MuxAccountCommand):
default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME)
permissions = settings.PERMISSION_ACCOUNT_DEFAULT permissions = settings.PERMISSION_ACCOUNT_DEFAULT
# generate a randomized key so the player can choose a character name later # generate a randomized key so the player can choose a character name later
key = ''.join(choices(string.ascii_letters + string.digits, k=10) key = ''.join(choices(string.ascii_letters + string.digits, k=10))
new_character = create.create_object(_CHARACTER_TYPECLASS, key=key, new_character = create.create_object(_CHARACTER_TYPECLASS, key=key,
location=None, location=None,
home=home, home=default_home,
permissions=permissions) permissions=permissions)
# only allow creator (and developers) to puppet this char # only allow creator (and developers) to puppet this char
new_character.locks.add( new_character.locks.add(
@ -150,7 +150,7 @@ class ContribChargenAccount(DefaultAccount):
) )
if session.sessid == csessid: if session.sessid == csessid:
result.append(f"\n |w* {isess+1}|n {addr}") result.append(f"\n |w* {isess+1}|n {addr}")
else else:
result.append(f"\n {isess+1} {addr}") result.append(f"\n {isess+1} {addr}")
result.append("\n\n |whelp|n - more commands") result.append("\n\n |whelp|n - more commands")
@ -163,7 +163,7 @@ class ContribChargenAccount(DefaultAccount):
if characters: if characters:
result.append( result.append(
"\n |wdchardelete <name>|n - delete a character (cannot be undone!)" "\n |wchardelete <name>|n - delete a character (cannot be undone!)"
) )
plural = "" if len(characters) == 1 else "s" plural = "" if len(characters) == 1 else "s"
result.append("\n |wic <character>|n - enter the game (|wooc|n to return here)") result.append("\n |wic <character>|n - enter the game (|wooc|n to return here)")

View file

@ -95,7 +95,6 @@ _CLASS_INFO_DICT = {
Warriors like to compete by beating each other up for fun. Warriors like to compete by beating each other up for fun.
"""), """),
},
"mage": dedent("""\ "mage": dedent("""\
Mages prefer less combative lines of work, such as showmanship or Mages prefer less combative lines of work, such as showmanship or
selling enchanted charms. Those who choose to be a battle mage are selling enchanted charms. Those who choose to be a battle mage are
@ -104,7 +103,6 @@ _CLASS_INFO_DICT = {
Mage schools, being led by the most academic-minded of mages, are Mage schools, being led by the most academic-minded of mages, are
notorious for intellectual snobbery. notorious for intellectual snobbery.
"""), """),
},
} }
def menunode_info_base(caller): def menunode_info_base(caller):
@ -137,7 +135,7 @@ def menunode_info_class(caller, raw_string, selected_class=None, **kwargs):
return "Something went wrong. Please try again." return "Something went wrong. Please try again."
# Since you have all the info in a nice dict, you can just grab it to display here # Since you have all the info in a nice dict, you can just grab it to display here
text = _CLASS_INFO_DICT[pclass] text = _CLASS_INFO_DICT[selected_class]
help = "If you want option-specific help, you can define it in your info dict and reference it." help = "If you want option-specific help, you can define it in your info dict and reference it."
options = [] options = []
@ -153,7 +151,6 @@ def menunode_info_class(caller, raw_string, selected_class=None, **kwargs):
def _set_class(caller, raw_string, selected_class=None, **kwargs): def _set_class(caller, raw_string, selected_class=None, **kwargs):
"""Set the character's species and define their available features."""
# a class should always be selected here # a class should always be selected here
if not selected_class: if not selected_class:
# go back to the base node for this decision # go back to the base node for this decision
@ -200,7 +197,7 @@ def menunode_categories(caller, **kwargs):
options.append({"desc": f"Choose your |c{category}|n", "goto": ("menunode_category_options", { "category": category })}) options.append({"desc": f"Choose your |c{category}|n", "goto": ("menunode_category_options", { "category": category })})
# since this node goes in and out of sub-nodes, you need an option to proceed to the next step # since this node goes in and out of sub-nodes, you need an option to proceed to the next step
options.append({"key": "(Next)", "next", "n"), "desc": "Continue to the next step.", "goto": "menunode_multi_choice"}) options.append({"key": ("(Next)", "next", "n"), "desc": "Continue to the next step.", "goto": "menunode_multi_choice"})
# once past the first decision, it's also a good idea to include a "back to previous step" option # once past the first decision, it's also a good idea to include a "back to previous step" option
options.append({"key": ("(Back)", "back", "b"), "desc": "Go back to the previous step", "goto": "menunode_info_base"}) options.append({"key": ("(Back)", "back", "b"), "desc": "Go back to the previous step", "goto": "menunode_info_base"})
return (text, help), options return (text, help), options
@ -213,8 +210,8 @@ def menunode_category_options(caller, raw_string, category=None, **kwargs):
# for mechanics-related choices, you can combine this with the # for mechanics-related choices, you can combine this with the
# informational options approach to give specific info # informational options approach to give specific info
text = "Choose your {category}:" text = f"Choose your {category}:"
help = "This will define your {category}." help = f"This will define your {category}."
options = [] options = []
# build the list of options from the right category of your dictionary # build the list of options from the right category of your dictionary
@ -265,17 +262,17 @@ def menunode_multi_choice(caller, raw_string, **kwargs):
selected options. selected options.
""") """)
help = "This is a good place to specify how many choices are allowed or required." help = "This is a good place to specify how many choices are allowed or required. This example requires exactly 3."
options = [] options = []
for option in _SKILL_OPTIONS: for option in _SKILL_OPTIONS:
# check if the option has been selected # check if the option has been selected
if option in selected: if option in selected:
# if it's been selected, we want to highlight that # if it's been selected, we want to highlight that
opt_desc = f"|y({option}) (selected)|n" opt_desc = f"|y{option} (selected)|n"
else: else:
opt_desc = option opt_desc = option
options.append({"desc": opt_desc, "goto": ( _set_multichoice, {"selected": selected, "option": option, "add": add})}) options.append({"desc": opt_desc, "goto": ( _set_multichoice, {"selected": selected, "option": option})})
# only display the Next option if the requirements are met! # only display the Next option if the requirements are met!
# for this example, you need exactly 3 choices, but you can use an inequality for "no more than X", or "at least X" # for this example, you need exactly 3 choices, but you can use an inequality for "no more than X", or "at least X"
@ -294,7 +291,7 @@ def _set_multichoice(caller, raw_string, selected=[], **kwargs):
selected.remove(option) selected.remove(option)
# otherwise, we're adding it # otherwise, we're adding it
else: else:
selected.add(option) selected.append(option)
# now that the options are updated, save it to the character # now that the options are updated, save it to the character
# this is just setting an attribute but it could be anything # this is just setting an attribute but it could be anything
@ -357,7 +354,7 @@ def menunode_choose_objects(caller, raw_string, **kwargs):
for proto in _EXAMPLE_PROTOTYPES: for proto in _EXAMPLE_PROTOTYPES:
# use the key as the option description, but pass the whole prototype # use the key as the option description, but pass the whole prototype
options.append({"desc": f"Choose {_INFLECT.an(option['key'])", "goto": ( _set_object_choice, {"proto": proto})}) options.append({"desc": f"Choose {_INFLECT.an(proto['key'])}", "goto": ( _set_object_choice, {"proto": proto})})
options.append({"key": ("(Back)", "back", "b"), "desc": "Go back to the previous step", "goto": "menunode_multi_choice"}) options.append({"key": ("(Back)", "back", "b"), "desc": "Go back to the previous step", "goto": "menunode_multi_choice"})
@ -371,7 +368,7 @@ def _set_object_choice(caller, raw_string, proto, **kwargs):
caller.new_char.db.starter_weapon = proto caller.new_char.db.starter_weapon = proto
# continue to the next step # continue to the next step
return "menunode_select_name" return "menunode_choose_name"
######################################################### #########################################################
@ -380,11 +377,12 @@ def _set_object_choice(caller, raw_string, proto, **kwargs):
def menunode_choose_name(caller, raw_string, **kwargs): def menunode_choose_name(caller, raw_string, **kwargs):
"""Name selection""" """Name selection"""
char = caller.new_char
# 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("""/ text = dedent("""\
|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
@ -418,8 +416,8 @@ def menunode_check_charname(caller, raw_string, **kwargs):
text = f"|w{charname}|n is available! Confirm?" text = f"|w{charname}|n is available! Confirm?"
# let players change their mind and go back to the name choice, if they want # let players change their mind and go back to the name choice, if they want
options = [ options = [
{ "key": "Yes", "goto": "menunode_end" }, { "key": ("Yes", "y"), "goto": "menunode_end" },
{ "key": "No", "goto": "menunode_choose_name" }, { "key": ("No", "n"), "goto": "menunode_choose_name" },
] ]
return text, options return text, options

View file

@ -1,6 +1,9 @@
from django.conf import settings
from django.test import override_settings from django.test import override_settings
from evennia import DefaultCharacter
from evennia.utils import inherits_from from evennia.utils import inherits_from
from evennia.utils.test_resources import BaseEvenniaCommandTest from evennia.utils.test_resources import BaseEvenniaCommandTest
from evennia.commands.default import account
from . import character_creator from . import character_creator
class TestAccount(BaseEvenniaCommandTest): class TestAccount(BaseEvenniaCommandTest):
@ -11,7 +14,7 @@ class TestAccount(BaseEvenniaCommandTest):
) )
if settings.MULTISESSION_MODE == 2: if settings.MULTISESSION_MODE == 2:
# test both normal output and also inclusion of in-progress character # test both normal output and also inclusion of in-progress character
account.db._playable_characters = [self.char1] self.account.db._playable_characters = [self.char1]
self.char1.db.chargen_step = "start" self.char1.db.chargen_step = "start"
output = self.call( output = self.call(
account.CmdOOCLook(), account.CmdOOCLook(),
@ -21,15 +24,13 @@ class TestAccount(BaseEvenniaCommandTest):
) )
self.assertIn("|Yin progress|n", output) self.assertIn("|Yin progress|n", output)
@override_settings(CHARGEN_MENU="evennia.contrib.base_systems.example_menu") @override_settings(CHARGEN_MENU="evennia.contrib.base_systems.character_creator.example_menu")
def test_char_create(self): def test_char_create(self):
account = self.account
session = self.session
self.call( self.call(
character_creator.ContribCmdCharCreate(), character_creator.ContribCmdCharCreate(),
"", "",
caller=account, caller=self.account,
) )
menu = session.ndb._menutree menu = self.session.ndb._menutree
self.assertNotNone(menu) self.assertNotEqual(menu, None)
self.assertTrue(inherits_from(session.new_char, DefaultCharacter) ) self.assertTrue(inherits_from(self.session.new_char, DefaultCharacter) )