diff --git a/evennia/contrib/base_systems/character_creator/character_creator.py b/evennia/contrib/base_systems/character_creator/character_creator.py index aa20cb87cd..976b2b176e 100644 --- a/evennia/contrib/base_systems/character_creator/character_creator.py +++ b/evennia/contrib/base_systems/character_creator/character_creator.py @@ -70,10 +70,10 @@ class ContribCmdCharCreate(MuxAccountCommand): default_home = ObjectDB.objects.get_id(settings.DEFAULT_HOME) permissions = settings.PERMISSION_ACCOUNT_DEFAULT # 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, location=None, - home=home, + home=default_home, permissions=permissions) # only allow creator (and developers) to puppet this char new_character.locks.add( @@ -150,7 +150,7 @@ class ContribChargenAccount(DefaultAccount): ) if session.sessid == csessid: result.append(f"\n |w* {isess+1}|n {addr}") - else + else: result.append(f"\n {isess+1} {addr}") result.append("\n\n |whelp|n - more commands") @@ -163,7 +163,7 @@ class ContribChargenAccount(DefaultAccount): if characters: result.append( - "\n |wdchardelete |n - delete a character (cannot be undone!)" + "\n |wchardelete |n - delete a character (cannot be undone!)" ) plural = "" if len(characters) == 1 else "s" result.append("\n |wic |n - enter the game (|wooc|n to return here)") diff --git a/evennia/contrib/base_systems/character_creator/example_menu.py b/evennia/contrib/base_systems/character_creator/example_menu.py index b4d5c6b5af..5217b1431e 100644 --- a/evennia/contrib/base_systems/character_creator/example_menu.py +++ b/evennia/contrib/base_systems/character_creator/example_menu.py @@ -95,7 +95,6 @@ _CLASS_INFO_DICT = { Warriors like to compete by beating each other up for fun. """), - }, "mage": dedent("""\ Mages prefer less combative lines of work, such as showmanship or 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 notorious for intellectual snobbery. """), - }, } 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." # 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." 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): - """Set the character's species and define their available features.""" # a class should always be selected here if not selected_class: # 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 })}) # 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 options.append({"key": ("(Back)", "back", "b"), "desc": "Go back to the previous step", "goto": "menunode_info_base"}) 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 # informational options approach to give specific info - text = "Choose your {category}:" - help = "This will define your {category}." + text = f"Choose your {category}:" + help = f"This will define your {category}." options = [] # 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. """) - 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 = [] for option in _SKILL_OPTIONS: # check if the option has been selected if option in selected: # 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: 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! # 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) # otherwise, we're adding it else: - selected.add(option) + selected.append(option) # now that the options are updated, save it to the character # 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: # 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"}) @@ -371,7 +368,7 @@ def _set_object_choice(caller, raw_string, proto, **kwargs): caller.new_char.db.starter_weapon = proto # 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): """Name selection""" + char = caller.new_char # another decision, so save the resume point char.db.chargen_step = "menunode_choose_name" - text = dedent("""/ + text = dedent("""\ |wChoosing a Name|n 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?" # let players change their mind and go back to the name choice, if they want options = [ - { "key": "Yes", "goto": "menunode_end" }, - { "key": "No", "goto": "menunode_choose_name" }, + { "key": ("Yes", "y"), "goto": "menunode_end" }, + { "key": ("No", "n"), "goto": "menunode_choose_name" }, ] return text, options diff --git a/evennia/contrib/base_systems/character_creator/tests.py b/evennia/contrib/base_systems/character_creator/tests.py index 45076d7162..7cb562be40 100644 --- a/evennia/contrib/base_systems/character_creator/tests.py +++ b/evennia/contrib/base_systems/character_creator/tests.py @@ -1,6 +1,9 @@ +from django.conf import settings from django.test import override_settings +from evennia import DefaultCharacter from evennia.utils import inherits_from from evennia.utils.test_resources import BaseEvenniaCommandTest +from evennia.commands.default import account from . import character_creator class TestAccount(BaseEvenniaCommandTest): @@ -11,7 +14,7 @@ class TestAccount(BaseEvenniaCommandTest): ) if settings.MULTISESSION_MODE == 2: # 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" output = self.call( account.CmdOOCLook(), @@ -21,15 +24,13 @@ class TestAccount(BaseEvenniaCommandTest): ) 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): - account = self.account - session = self.session self.call( character_creator.ContribCmdCharCreate(), "", - caller=account, + caller=self.account, ) - menu = session.ndb._menutree - self.assertNotNone(menu) - self.assertTrue(inherits_from(session.new_char, DefaultCharacter) ) + menu = self.session.ndb._menutree + self.assertNotEqual(menu, None) + self.assertTrue(inherits_from(self.session.new_char, DefaultCharacter) )