mirror of
https://github.com/evennia/evennia.git
synced 2026-04-04 23:17:17 +02:00
Further cleanup and debugging of olc menu
This commit is contained in:
parent
6126391406
commit
696cb3942b
3 changed files with 69 additions and 43 deletions
|
|
@ -518,14 +518,11 @@ def node_index(caller):
|
|||
can be hard-coded or scripted using |w$protfuncs|n - for example to randomize the value
|
||||
every time the prototype is used to spawn a new entity.
|
||||
|
||||
The prototype fields named 'prototype_*' are not used to create the entity itself but for
|
||||
organizing the template when saving it for you (and maybe others) to use later.
|
||||
The prototype fields whose names start with 'Prototype-' are not fields on the object itself
|
||||
but are used in the template and when saving it for you (and maybe others) to use later.
|
||||
Select prototype field to edit. If you are unsure, start from [|w1|n]. Enter [|wh|n]elp at
|
||||
any menu node for more info.
|
||||
|
||||
Select prototype field to edit. If you are unsure, start from [|w1|n]. At any time you can
|
||||
[|wV|n]alidate that the prototype works correctly and use it to [|wSP|n]awn a new entity. You
|
||||
can also [|wSA|n]ve|n your work or [|wLO|n]oad an existing prototype to use as a base. Use
|
||||
[|wL|n]ook to re-show a menu node. [|wQ|n]uit will always exit the menu and [|wH|n]elp will
|
||||
show context-sensitive help.
|
||||
"""
|
||||
helptxt = """
|
||||
|c- prototypes |n
|
||||
|
|
@ -537,6 +534,13 @@ def node_index(caller):
|
|||
to spawn goblins with different names, looks, equipment and skill, each based on the same
|
||||
`Goblin` typeclass.
|
||||
|
||||
At any time you can [|wV|n]alidate that the prototype works correctly and use it to
|
||||
[|wSP|n]awn a new entity. You can also [|wSA|n]ve|n your work, [|wLO|n]oad an existing
|
||||
prototype to [|wSE|n]arch for existing objects to use as a base. Use [|wL|n]ook to re-show a
|
||||
menu node. [|wQ|n]uit will always exit the menu and [|wH|n]elp will show context-sensitive
|
||||
help.
|
||||
|
||||
|
||||
|c- $protfuncs |n
|
||||
|
||||
Prototype-functions (protfuncs) allow for limited scripting within a prototype. These are
|
||||
|
|
@ -553,11 +557,11 @@ def node_index(caller):
|
|||
{"desc": "|WPrototype-Key|n|n{}".format(
|
||||
_format_option_value("Key", "prototype_key" not in prototype, prototype, None)),
|
||||
"goto": "node_prototype_key"})
|
||||
for key in ('Prototype_parent', 'Typeclass', 'Key', 'Aliases', 'Attrs', 'Tags', 'Locks',
|
||||
for key in ('Prototype_Parent', 'Typeclass', 'Key', 'Aliases', 'Attrs', 'Tags', 'Locks',
|
||||
'Permissions', 'Location', 'Home', 'Destination'):
|
||||
required = False
|
||||
cropper = None
|
||||
if key in ("Prototype_parent", "Typeclass"):
|
||||
if key in ("Prototype_Parent", "Typeclass"):
|
||||
required = ("prototype_parent" not in prototype) and ("typeclass" not in prototype)
|
||||
if key == 'Typeclass':
|
||||
cropper = _path_cropper
|
||||
|
|
@ -1827,7 +1831,7 @@ def node_prototype_locks(caller):
|
|||
# update existing objects node
|
||||
|
||||
|
||||
def _update_spawned(caller, **kwargs):
|
||||
def _apply_diff(caller, **kwargs):
|
||||
"""update existing objects"""
|
||||
prototype = kwargs['prototype']
|
||||
objects = kwargs['objects']
|
||||
|
|
@ -1844,7 +1848,7 @@ def _keep_diff(caller, **kwargs):
|
|||
diff[key] = "KEEP"
|
||||
|
||||
|
||||
def node_update_objects(caller, **kwargs):
|
||||
def node_apply_diff(caller, **kwargs):
|
||||
"""Offer options for updating objects"""
|
||||
|
||||
def _keep_option(keyname, prototype, obj, obj_prototype, diff, objects, back_node):
|
||||
|
|
@ -1886,8 +1890,9 @@ def node_update_objects(caller, **kwargs):
|
|||
consider being conservative (switch to KEEP) or even do the update manually if you are
|
||||
unsure that the results will be acceptable. """
|
||||
|
||||
options = _wizard_options("update_objects", back_node[5:], None)
|
||||
io = 0
|
||||
options = []
|
||||
|
||||
ichanges = 0
|
||||
for (key, inst) in sorted(((key, val) for key, val in diff.items()), key=lambda tup: tup[0]):
|
||||
|
||||
if key in protlib._PROTOTYPE_META_NAMES:
|
||||
|
|
@ -1897,30 +1902,40 @@ def node_update_objects(caller, **kwargs):
|
|||
old_val = utils.crop(str(obj_prototype[key]), width=20)
|
||||
|
||||
if inst == "KEEP":
|
||||
text.append(line.format(iopt='', key=key, old=old_val, sep=" ", new='', change=inst))
|
||||
inst = "|b{}|n".format(inst)
|
||||
text.append(line.format(iopt='', key=key, old=old_val,
|
||||
sep=" ", new='', change=inst))
|
||||
continue
|
||||
|
||||
new_val = utils.crop(str(spawner.init_spawn_value(prototype[key])), width=20)
|
||||
io += 1
|
||||
ichanges += 1
|
||||
if inst in ("UPDATE", "REPLACE"):
|
||||
text.append(line.format(iopt=io, key=key, old=old_val,
|
||||
inst = "|y{}|n".format(inst)
|
||||
text.append(line.format(iopt=ichanges, key=key, old=old_val,
|
||||
sep=" |y->|n ", new=new_val, change=inst))
|
||||
options.append(_keep_option(key, prototype,
|
||||
obj, obj_prototype, diff, update_objects, back_node))
|
||||
elif inst == "REMOVE":
|
||||
text.append(line.format(iopt=io, key=key, old=old_val,
|
||||
inst = "|r{}|n".format(inst)
|
||||
text.append(line.format(iopt=ichanges, key=key, old=old_val,
|
||||
sep=" |r->|n ", new='', change=inst))
|
||||
options.append(_keep_option(key, prototype,
|
||||
obj, obj_prototype, diff, update_objects, back_node))
|
||||
options.extend(
|
||||
[{"key": ("|wu|r update {} objects".format(len(update_objects)), "update", "u"),
|
||||
"goto": (_update_spawned, {"prototype": prototype, "objects": update_objects,
|
||||
"back_node": back_node, "diff": diff})},
|
||||
{"key": ("|wr|neset changes", "reset", "r"),
|
||||
"goto": ("node_update_objects", {"prototype": prototype, "back_node": back_node,
|
||||
"objects": update_objects})},
|
||||
{"key": "|wb|rack ({})".format(back_node[5:], 'b'),
|
||||
"goto": back_node}])
|
||||
[{"key": ("|wu|Wupdate {} objects".format(len(update_objects)), "update", "u"),
|
||||
"goto": (_apply_diff, {"prototye": prototype, "objects": update_objects,
|
||||
"back_node": back_node, "diff": diff})},
|
||||
{"key": ("|wr|Wneset changes", "reset", "r"),
|
||||
"goto": ("node_apply_diff", {"prototype": prototype, "back_node": back_node,
|
||||
"objects": update_objects})}])
|
||||
|
||||
if ichanges < 1:
|
||||
text = ["Analyzed a random sample object (out of {}) - "
|
||||
"found no changes to apply.".format(len(update_objects))]
|
||||
|
||||
options.extend(_wizard_options("update_objects", back_node[5:], None))
|
||||
options.append({"key": "_default",
|
||||
"goto": back_node})
|
||||
|
||||
text = "\n".join(text)
|
||||
|
||||
|
|
@ -1956,7 +1971,7 @@ def node_prototype_save(caller, **kwargs):
|
|||
options = (
|
||||
{"key": ("|wY|Wes|n", "yes", "y"),
|
||||
"desc": "Go to updating screen",
|
||||
"goto": ("node_update_objects",
|
||||
"goto": ("node_apply_diff",
|
||||
{"accept_update": True, "objects": spawned_objects,
|
||||
"prototype": prototype, "back_node": "node_prototype_save"})},
|
||||
{"key": ("[|wN|Wo|n]", "n"),
|
||||
|
|
@ -1995,6 +2010,8 @@ def node_prototype_save(caller, **kwargs):
|
|||
"\n|yValidation errors were found. They need to be corrected before this prototype "
|
||||
"can be saved (or used to spawn).|n")
|
||||
options = _wizard_options("prototype_save", "index", None)
|
||||
options.append({"key": "_default",
|
||||
"goto": "node_index"})
|
||||
return "\n".join(text), options
|
||||
|
||||
prototype_key = prototype['prototype_key']
|
||||
|
|
@ -2044,8 +2061,8 @@ def _spawn(caller, **kwargs):
|
|||
obj = spawner.spawn(prototype)
|
||||
if obj:
|
||||
obj = obj[0]
|
||||
text = "|gNew instance|n {key} ({dbref}) |gspawned.|n".format(
|
||||
key=obj.key, dbref=obj.dbref)
|
||||
text = "|gNew instance|n {key} ({dbref}) |gspawned at location |n{loc}|n|g.|n".format(
|
||||
key=obj.key, dbref=obj.dbref, loc=prototype['location'])
|
||||
else:
|
||||
text = "|rError: Spawner did not return a new instance.|n"
|
||||
return "node_examine_entity", {"text": text, "back": "prototype_spawn"}
|
||||
|
|
@ -2108,11 +2125,13 @@ def node_prototype_spawn(caller, **kwargs):
|
|||
if spawned_objects:
|
||||
options.append(
|
||||
{"desc": "Update {num} existing objects with this prototype".format(num=nspawned),
|
||||
"goto": ("node_update_objects",
|
||||
"goto": ("node_apply_diff",
|
||||
{"objects": list(spawned_objects),
|
||||
"prototype": prototype,
|
||||
"back_node": "node_prototype_spawn"})})
|
||||
options.extend(_wizard_options("prototype_spawn", "index", None))
|
||||
options.append({"key": "_default",
|
||||
"goto": "node_index"})
|
||||
|
||||
return text, options
|
||||
|
||||
|
|
@ -2137,19 +2156,25 @@ def _prototype_load_actions(caller, raw_inp, **kwargs):
|
|||
"""Parse the default Convert prototype to a string representation for closer inspection"""
|
||||
choices = kwargs.get("available_choices", [])
|
||||
prototype, action = _default_parse(
|
||||
raw_inp, choices, ("examine", "e", "l"))
|
||||
raw_inp, choices, ("examine", "e", "l"), ("delete", "del", "d"))
|
||||
|
||||
if prototype:
|
||||
# a selection of parent was made
|
||||
prototype = protlib.search_prototype(key=prototype)[0]
|
||||
|
||||
# which action to apply on the selection
|
||||
if action == 'examine':
|
||||
# examine the prototype
|
||||
prototype = protlib.search_prototype(key=prototype)[0]
|
||||
txt = protlib.prototype_to_str(prototype)
|
||||
kwargs['text'] = txt
|
||||
kwargs['back'] = 'prototype_load'
|
||||
return "node_examine_entity", kwargs
|
||||
return "node_examine_entity", {"text": txt, "back": 'prototype_load'}
|
||||
elif action == 'delete':
|
||||
# delete prototype from disk
|
||||
try:
|
||||
protlib.delete_prototype(prototype, caller=caller)
|
||||
except protlib.PermissionError as err:
|
||||
txt = "|rDeletion error:|n {}".format(err)
|
||||
else:
|
||||
txt = "|gPrototype {} was deleted.|n".format(prototype)
|
||||
return "node_examine_entity", {"text": txt, "back": "prototype_load"}
|
||||
|
||||
return 'node_prototype_load'
|
||||
|
||||
|
|
@ -2162,7 +2187,7 @@ def node_prototype_load(caller, **kwargs):
|
|||
Select a prototype to load. This will replace any prototype currently being edited!
|
||||
|
||||
{actions}
|
||||
""".format(actions=_format_list_actions("examine"))
|
||||
""".format(actions=_format_list_actions("examine", "delete"))
|
||||
|
||||
helptext = """
|
||||
Loading a prototype will load it and return you to the main index. It can be a good idea
|
||||
|
|
@ -2246,7 +2271,7 @@ def start_olc(caller, session=None, prototype=None):
|
|||
"node_location": node_location,
|
||||
"node_home": node_home,
|
||||
"node_destination": node_destination,
|
||||
"node_update_objects": node_update_objects,
|
||||
"node_apply_diff": node_apply_diff,
|
||||
"node_prototype_desc": node_prototype_desc,
|
||||
"node_prototype_tags": node_prototype_tags,
|
||||
"node_prototype_locks": node_prototype_locks,
|
||||
|
|
|
|||
|
|
@ -297,10 +297,10 @@ def init_spawn_value(value, validator=None):
|
|||
for mod in settings.PROTOTYPE_MODULES:
|
||||
# to remove a default prototype, override it with an empty dict.
|
||||
# internally we store as (key, desc, locks, tags, prototype_dict)
|
||||
prots = [(prototype_key, prot) for prototype_key, prot in all_from_module(mod).items()
|
||||
prots = [(prototype_key.lower(), prot) for prototype_key, prot in all_from_module(mod).items()
|
||||
if prot and isinstance(prot, dict)]
|
||||
# assign module path to each prototype_key for easy reference
|
||||
_MODULE_PROTOTYPE_MODULES.update({prototype_key: mod for prototype_key, _ in prots})
|
||||
_MODULE_PROTOTYPE_MODULES.update({prototype_key.lower(): mod for prototype_key, _ in prots})
|
||||
# make sure the prototype contains all meta info
|
||||
for prototype_key, prot in prots:
|
||||
actual_prot_key = prot.get('prototype_key', prototype_key).lower()
|
||||
|
|
@ -409,7 +409,7 @@ def save_prototype(**kwargs):
|
|||
create_prototype = save_prototype
|
||||
|
||||
|
||||
def delete_prototype(key, caller=None):
|
||||
def delete_prototype(prototype_key, caller=None):
|
||||
"""
|
||||
Delete a stored prototype
|
||||
|
||||
|
|
@ -424,14 +424,16 @@ def delete_prototype(key, caller=None):
|
|||
|
||||
"""
|
||||
if prototype_key in _MODULE_PROTOTYPES:
|
||||
mod = _MODULE_PROTOTYPE_MODULES.get(prototype_key, "N/A")
|
||||
mod = _MODULE_PROTOTYPE_MODULES.get(prototype_key.lower(), "N/A")
|
||||
raise PermissionError("{} is a read-only prototype "
|
||||
"(defined as code in {}).".format(prototype_key, mod))
|
||||
|
||||
stored_prototype = DbPrototype.objects.filter(db_key=prototype_key)
|
||||
stored_prototype = DbPrototype.objects.filter(db_key__iexact=prototype_key)
|
||||
|
||||
if not stored_prototype:
|
||||
raise PermissionError("Prototype {} was not found.".format(prototype_key))
|
||||
|
||||
stored_prototype = stored_prototype[0]
|
||||
if caller:
|
||||
if not stored_prototype.access(caller, 'edit'):
|
||||
raise PermissionError("{} does not have permission to "
|
||||
|
|
|
|||
|
|
@ -1145,7 +1145,6 @@ def list_node(option_generator, select=None, pagesize=10):
|
|||
for eopt in decorated_options:
|
||||
cback = ("goto" in eopt and "goto") or ("exec" in eopt and "exec") or None
|
||||
if cback:
|
||||
print("eopt, cback: {} {}".format(eopt, cback))
|
||||
signature = eopt[cback]
|
||||
if callable(signature):
|
||||
# callable with no kwargs defined
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue