Finish turnbased combat tutorial text
This commit is contained in:
parent
f70fd64478
commit
09253dce31
10 changed files with 1393 additions and 106 deletions
|
|
@ -101,12 +101,12 @@ You may want to use `ForeignKey` or `ManyToManyField` to relate your new model t
|
||||||
|
|
||||||
To do this we need to specify the app-path for the root object type we want to store as a string (we must use a string rather than the class directly or you'll run into problems with models not having been initialized yet).
|
To do this we need to specify the app-path for the root object type we want to store as a string (we must use a string rather than the class directly or you'll run into problems with models not having been initialized yet).
|
||||||
|
|
||||||
- `"objects.ObjectDB"` for all [Objects](Objects) (like exits, rooms, characters etc)
|
- `"objects.ObjectDB"` for all [Objects](../Components/Objects.md) (like exits, rooms, characters etc)
|
||||||
- `"accounts.AccountDB"` for [Accounts](Accounts).
|
- `"accounts.AccountDB"` for [Accounts](../Components/Accounts.md).
|
||||||
- `"scripts.ScriptDB"` for [Scripts](Scripts).
|
- `"scripts.ScriptDB"` for [Scripts](../Components/Scripts.md).
|
||||||
- `"comms.ChannelDB"` for [Channels](Channels).
|
- `"comms.ChannelDB"` for [Channels](../Components/Channels.md).
|
||||||
- `"comms.Msg"` for [Msg](Msg) objects.
|
- `"comms.Msg"` for [Msg](../Components/Msg.md) objects.
|
||||||
- `"help.HelpEntry"` for [Help Entries](Help-System).
|
- `"help.HelpEntry"` for [Help Entries](../Components/Help-System.md).
|
||||||
|
|
||||||
Here's an example:
|
Here's an example:
|
||||||
|
|
||||||
|
|
@ -225,4 +225,4 @@ To search your new custom database table you need to use its database *manager*
|
||||||
self.caller.msg(match.db_text)
|
self.caller.msg(match.db_text)
|
||||||
```
|
```
|
||||||
|
|
||||||
See the [Beginner Tutorial lesson on Django querying](Beginner-Tutorial-Django-queries) for a lot more information about querying the database.
|
See the [Beginner Tutorial lesson on Django querying](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Django-queries.md) for a lot more information about querying the database.
|
||||||
|
|
@ -183,7 +183,7 @@ class EvAdventureCombatBaseHandler(DefaultScript):
|
||||||
|
|
||||||
combathandler_key = kwargs.pop("key", "combathandler")
|
combathandler_key = kwargs.pop("key", "combathandler")
|
||||||
combathandler = obj.ndb.combathandler
|
combathandler = obj.ndb.combathandler
|
||||||
if not combathandler:
|
if not combathandler or not combathandler.id:
|
||||||
combathandler = obj.scripts.get(combathandler_key).first()
|
combathandler = obj.scripts.get(combathandler_key).first()
|
||||||
if not combathandler:
|
if not combathandler:
|
||||||
# have to create from scratch
|
# have to create from scratch
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,6 @@
|
||||||
# Twitch Combat
|
# Twitch Combat
|
||||||
|
|
||||||
In this lesson we will build upon the basic combat framework we devised [in the previous lesson](./Beginner-Tutorial-Combat-Base.md).
|
In this lesson we will build upon the basic combat framework we devised [in the previous lesson](./Beginner-Tutorial-Combat-Base.md) to create a 'twitch-like' combat system.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
> attack troll
|
> attack troll
|
||||||
You attack the Troll!
|
You attack the Troll!
|
||||||
|
|
@ -48,7 +47,7 @@ You attack the troll with Sword: Roll vs armor(11):
|
||||||
|
|
||||||
The battle is over. You are still standing.
|
The battle is over. You are still standing.
|
||||||
```
|
```
|
||||||
> Documentation doesn't show colors.
|
> Note that this documentation doesn't show in-game colors. If you are interested in an alternative, see the [next lesson](./Beginner-Tutorial-Combat-Turnbased.md), where we'll make a turnbased, menu-based system instead.
|
||||||
|
|
||||||
With "Twitch" combat, we refer to a type of combat system that runs without any clear divisions of 'turns' (the opposite of [Turn-based combat](./Beginner-Tutorial-Combat-Turnbased.md)). It is inspired by the way combat worked in the old [DikuMUD](https://en.wikipedia.org/wiki/DikuMUD) codebase, but is more flexible.
|
With "Twitch" combat, we refer to a type of combat system that runs without any clear divisions of 'turns' (the opposite of [Turn-based combat](./Beginner-Tutorial-Combat-Turnbased.md)). It is inspired by the way combat worked in the old [DikuMUD](https://en.wikipedia.org/wiki/DikuMUD) codebase, but is more flexible.
|
||||||
|
|
||||||
|
|
@ -942,11 +941,11 @@ This is what we need for a minimal test:
|
||||||
- An item (like a potion) we can `use`.
|
- An item (like a potion) we can `use`.
|
||||||
|
|
||||||
```{sidebar}
|
```{sidebar}
|
||||||
You can find an example batch-command script in [evennia/contrib/tutorials/evadventure/batchscripts/combat_demo.ev](evennia.contrib.tutorials.evadventure.batchscript)
|
You can find an example batch-command script in [evennia/contrib/tutorials/evadventure/batchscripts/twitch_combat_demo.ev](evennia.contrib.tutorials.evadventure.batchscripts)
|
||||||
```
|
```
|
||||||
While you can create these manually in-game, it can be convenient to create a [batch-command script](../../../Components/Batch-Command-Processor.md) to set up your testing environment.
|
While you can create these manually in-game, it can be convenient to create a [batch-command script](../../../Components/Batch-Command-Processor.md) to set up your testing environment.
|
||||||
|
|
||||||
> create a new subfolder `evadventure/batchscripts/` (if it doesn't exist)
|
> create a new subfolder `evadventure/batchscripts/` (if it doesn't already exist)
|
||||||
|
|
||||||
|
|
||||||
> create a new file `evadventure/combat_demo.ev` (note, it's `.ev` not `.py`!)
|
> create a new file `evadventure/combat_demo.ev` (note, it's `.ev` not `.py`!)
|
||||||
|
|
@ -1007,7 +1006,7 @@ set dummy/hp = 1000
|
||||||
|
|
||||||
Log into the game with a developer/superuser account and run
|
Log into the game with a developer/superuser account and run
|
||||||
|
|
||||||
> batchcmd evadventure.batchscripts.combat_demo
|
> batchcmd evadventure.batchscripts.twitch_combat_demo
|
||||||
|
|
||||||
This should place you in the arena with the dummy (if not, check for errors in the output! Use `objects` and `delete` commands to list and delete objects if you need to start over. )
|
This should place you in the arena with the dummy (if not, check for errors in the output! Use `objects` and `delete` commands to list and delete objects if you need to start over. )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -364,7 +364,7 @@ code {
|
||||||
/* padding: 1px 2px; */
|
/* padding: 1px 2px; */
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
font-family: "Courier Prime", Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
|
font-family: "Courier Prime", Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
|
||||||
font-weight: bold;
|
font-weight: normal;
|
||||||
background-color: #f7f7f7;
|
background-color: #f7f7f7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# BASE_BATCH_PROCESS_PATHS += ["evadventure.batchscripts"]
|
# BASE_BATCH_PROCESS_PATHS += ["evadventure.batchscripts"]
|
||||||
#
|
#
|
||||||
# Run from in-game as `batchcode combat_demo`
|
# Run from in-game as `batchcode turnbased_combat_demo`
|
||||||
#
|
#
|
||||||
|
|
||||||
# HEADER
|
# HEADER
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
# BASE_BATCH_PROCESS_PATHS += ["evadventure.batchscripts"]
|
# BASE_BATCH_PROCESS_PATHS += ["evadventure.batchscripts"]
|
||||||
#
|
#
|
||||||
# Run from in-game as batchcmd combat_demo
|
# Run from in-game as `batchcmd twitch_combat_demo`
|
||||||
#
|
#
|
||||||
|
|
||||||
# start from limbo
|
# start from limbo
|
||||||
|
|
@ -300,7 +300,7 @@ class EvAdventureCombatBaseHandler(DefaultScript):
|
||||||
combathandler = obj.ndb.combathandler
|
combathandler = obj.ndb.combathandler
|
||||||
if not combathandler:
|
if not combathandler:
|
||||||
combathandler = obj.scripts.get(combathandler_key).first()
|
combathandler = obj.scripts.get(combathandler_key).first()
|
||||||
if not combathandler:
|
if not combathandler or not combathandler.id:
|
||||||
# have to create from scratch
|
# have to create from scratch
|
||||||
persistent = kwargs.pop("persistent", True)
|
persistent = kwargs.pop("persistent", True)
|
||||||
combathandler = create_script(
|
combathandler = create_script(
|
||||||
|
|
|
||||||
|
|
@ -144,8 +144,8 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
||||||
target (Character or NPC): The target to check advantage against.
|
target (Character or NPC): The target to check advantage against.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return bool(self.advantage_matrix[combatant].pop(target, False)) or (
|
return target in self.fleeing_combatants or bool(
|
||||||
target in self.fleeing_combatants
|
self.advantage_matrix[combatant].pop(target, False)
|
||||||
)
|
)
|
||||||
|
|
||||||
def has_disadvantage(self, combatant, target):
|
def has_disadvantage(self, combatant, target):
|
||||||
|
|
@ -157,16 +157,14 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
||||||
target (Character or NPC): The target to check disadvantage against.
|
target (Character or NPC): The target to check disadvantage against.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return bool(self.disadvantage_matrix[combatant].pop(target, False)) or (
|
return bool(self.disadvantage_matrix[combatant].pop(target, False))
|
||||||
combatant in self.fleeing_combatants
|
|
||||||
)
|
|
||||||
|
|
||||||
def add_combatant(self, combatant):
|
def add_combatant(self, combatant):
|
||||||
"""
|
"""
|
||||||
Add a new combatant to the battle. Can be called multiple times safely.
|
Add a new combatant to the battle. Can be called multiple times safely.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*combatants (EvAdventureCharacter, EvAdventureNPC): Any number of combatants to add to
|
combatant (EvAdventureCharacter, EvAdventureNPC): Any number of combatants to add to
|
||||||
the combat.
|
the combat.
|
||||||
Returns:
|
Returns:
|
||||||
bool: If this combatant was newly added or not (it was already in combat).
|
bool: If this combatant was newly added or not (it was already in combat).
|
||||||
|
|
@ -260,19 +258,12 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
||||||
|
|
||||||
def queue_action(self, combatant, action_dict):
|
def queue_action(self, combatant, action_dict):
|
||||||
"""
|
"""
|
||||||
Queue an action by adding the new actiondict to the back of the queue. If the
|
Queue an action by adding the new actiondict.
|
||||||
queue was alrady at max-size, the front of the queue will be discarded.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
combatant (EvAdventureCharacter, EvAdventureNPC): A combatant queueing the action.
|
combatant (EvAdventureCharacter, EvAdventureNPC): A combatant queueing the action.
|
||||||
action_dict (dict): A dict describing the action class by name along with properties.
|
action_dict (dict): A dict describing the action class by name along with properties.
|
||||||
|
|
||||||
Example:
|
|
||||||
If the queue max-size is 3 and was `[a, b, c]` (where each element is an action-dict),
|
|
||||||
then using this method to add the new action-dict `d` will lead to a queue `[b, c, d]` -
|
|
||||||
that is, adding the new action will discard the one currently at the front of the queue
|
|
||||||
to make room.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.combatants[combatant] = action_dict
|
self.combatants[combatant] = action_dict
|
||||||
|
|
||||||
|
|
@ -299,17 +290,11 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
||||||
def execute_next_action(self, combatant):
|
def execute_next_action(self, combatant):
|
||||||
"""
|
"""
|
||||||
Perform a combatant's next queued action. Note that there is _always_ an action queued,
|
Perform a combatant's next queued action. Note that there is _always_ an action queued,
|
||||||
even if this action is 'hold'. We don't pop anything from the queue, instead we keep
|
even if this action is 'hold', which means the combatant will do nothing.
|
||||||
rotating the queue. When the queue has a length of one, this means just repeating the
|
|
||||||
same action over and over.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
combatant (EvAdventureCharacter, EvAdventureNPC): The combatant performing and action.
|
combatant (EvAdventureCharacter, EvAdventureNPC): The combatant performing and action.
|
||||||
|
|
||||||
Example:
|
|
||||||
If the combatant's action queue is `[a, b, c]` (where each element is an action-dict),
|
|
||||||
then calling this method will lead to action `a` being performed. After this method, the
|
|
||||||
queue will be rotated to the left and be `[b, c, a]` (so next time, `b` will be used).
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# this gets the next dict and rotates the queue
|
# this gets the next dict and rotates the queue
|
||||||
|
|
@ -324,6 +309,28 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
||||||
self.check_stop_combat()
|
self.check_stop_combat()
|
||||||
|
|
||||||
def check_stop_combat(self):
|
def check_stop_combat(self):
|
||||||
|
"""Check if it's time to stop combat"""
|
||||||
|
|
||||||
|
# check if anyone is defeated
|
||||||
|
for combatant in list(self.combatants.keys()):
|
||||||
|
if combatant.hp <= 0:
|
||||||
|
# PCs roll on the death table here, NPCs die. Even if PCs survive, they
|
||||||
|
# are still out of the fight.
|
||||||
|
combatant.at_defeat()
|
||||||
|
self.combatants.pop(combatant)
|
||||||
|
self.defeated_combatants.append(combatant)
|
||||||
|
self.msg("|r$You() $conj(fall) to the ground, defeated.|n", combatant=combatant)
|
||||||
|
else:
|
||||||
|
self.combatants[combatant] = self.fallback_action_dict
|
||||||
|
|
||||||
|
# check if anyone managed to flee
|
||||||
|
flee_timeout = self.flee_timeout
|
||||||
|
for combatant, started_fleeing in self.fleeing_combatants.items():
|
||||||
|
if self.turn - started_fleeing >= flee_timeout:
|
||||||
|
# if they are still alive/fleeing and have been fleeing long enough, escape
|
||||||
|
self.msg("|y$You() successfully $conj(flee) from combat.|n", combatant=combatant)
|
||||||
|
self.remove_combatant(combatant)
|
||||||
|
|
||||||
# check if one side won the battle
|
# check if one side won the battle
|
||||||
if not self.combatants:
|
if not self.combatants:
|
||||||
# noone left in combat - maybe they killed each other or all fled
|
# noone left in combat - maybe they killed each other or all fled
|
||||||
|
|
@ -368,26 +375,6 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
||||||
|
|
||||||
self.ndb.did_action = set()
|
self.ndb.did_action = set()
|
||||||
|
|
||||||
# check if anyone is defeated
|
|
||||||
for combatant in list(self.combatants.keys()):
|
|
||||||
if combatant.hp <= 0:
|
|
||||||
# PCs roll on the death table here, NPCs die. Even if PCs survive, they
|
|
||||||
# are still out of the fight.
|
|
||||||
combatant.at_defeat()
|
|
||||||
self.combatants.pop(combatant)
|
|
||||||
self.defeated_combatants.append(combatant)
|
|
||||||
self.msg("|r$You() $conj(fall) to the ground, defeated.|n", combatant=combatant)
|
|
||||||
else:
|
|
||||||
self.combatants[combatant] = self.fallback_action_dict
|
|
||||||
|
|
||||||
# check if anyone managed to flee
|
|
||||||
flee_timeout = self.flee_timeout
|
|
||||||
for combatant, started_fleeing in self.fleeing_combatants.items():
|
|
||||||
if self.turn - started_fleeing >= flee_timeout:
|
|
||||||
# if they are still alive/fleeing and have been fleeing long enough, escape
|
|
||||||
self.msg("|y$You() successfully $conj(flee) from combat.|n", combatant=combatant)
|
|
||||||
self.remove_combatant(combatant)
|
|
||||||
|
|
||||||
# check if one side won the battle
|
# check if one side won the battle
|
||||||
self.check_stop_combat()
|
self.check_stop_combat()
|
||||||
|
|
||||||
|
|
@ -421,10 +408,6 @@ def _get_combathandler(caller, turn_timeout=30, flee_time=3, combathandler_key="
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _rerun_current_node(caller, raw_string, **kwargs):
|
|
||||||
return None, kwargs
|
|
||||||
|
|
||||||
|
|
||||||
def _queue_action(caller, raw_string, **kwargs):
|
def _queue_action(caller, raw_string, **kwargs):
|
||||||
"""
|
"""
|
||||||
Goto-function that queue the action with the CombatHandler. This always returns
|
Goto-function that queue the action with the CombatHandler. This always returns
|
||||||
|
|
@ -435,40 +418,8 @@ def _queue_action(caller, raw_string, **kwargs):
|
||||||
return "node_combat"
|
return "node_combat"
|
||||||
|
|
||||||
|
|
||||||
def _step_wizard(caller, raw_string, **kwargs):
|
def _rerun_current_node(caller, raw_string, **kwargs):
|
||||||
"""
|
return None, kwargs
|
||||||
Many options requires stepping through several steps, wizard style. This
|
|
||||||
will redirect back/forth in the sequence.
|
|
||||||
|
|
||||||
E.g. Stunt boost -> Choose ability to boost -> Choose recipient -> Choose target -> queue
|
|
||||||
|
|
||||||
"""
|
|
||||||
caller.msg(f"_step_wizard kwargs: {kwargs}")
|
|
||||||
steps = kwargs.get("steps", [])
|
|
||||||
nsteps = len(steps)
|
|
||||||
istep = kwargs.get("istep", -1)
|
|
||||||
# one of abort, back, forward
|
|
||||||
step_direction = kwargs.get("step", "forward")
|
|
||||||
|
|
||||||
match step_direction:
|
|
||||||
case "abort":
|
|
||||||
# abort this wizard, back to top-level combat menu, dropping changes
|
|
||||||
return "node_combat"
|
|
||||||
case "back":
|
|
||||||
# step back in wizard
|
|
||||||
if istep <= 0:
|
|
||||||
return "node_combat"
|
|
||||||
istep = kwargs["istep"] = istep - 1
|
|
||||||
return steps[istep], kwargs
|
|
||||||
case _:
|
|
||||||
# forward (default)
|
|
||||||
if istep >= nsteps - 1:
|
|
||||||
# we are already at end of wizard - queue action!
|
|
||||||
return _queue_action(caller, raw_string, **kwargs)
|
|
||||||
else:
|
|
||||||
# step forward
|
|
||||||
istep = kwargs["istep"] = istep + 1
|
|
||||||
return steps[istep], kwargs
|
|
||||||
|
|
||||||
|
|
||||||
def _get_default_wizard_options(caller, **kwargs):
|
def _get_default_wizard_options(caller, **kwargs):
|
||||||
|
|
@ -480,7 +431,7 @@ def _get_default_wizard_options(caller, **kwargs):
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{"key": ("back", "b"), "goto": (_step_wizard, {**kwargs, **{"step": "back"}})},
|
{"key": ("back", "b"), "goto": (_step_wizard, {**kwargs, **{"step": "back"}})},
|
||||||
{"key": ("abort", "a"), "goto": (_step_wizard, {**kwargs, **{"step": "abort"}})},
|
{"key": ("abort", "a"), "goto": "node_combat"},
|
||||||
{
|
{
|
||||||
"key": "_default",
|
"key": "_default",
|
||||||
"goto": (_rerun_current_node, kwargs),
|
"goto": (_rerun_current_node, kwargs),
|
||||||
|
|
@ -488,6 +439,37 @@ def _get_default_wizard_options(caller, **kwargs):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _step_wizard(caller, raw_string, **kwargs):
|
||||||
|
"""
|
||||||
|
Many options requires stepping through several steps, wizard style. This
|
||||||
|
will redirect back/forth in the sequence.
|
||||||
|
|
||||||
|
E.g. Stunt boost -> Choose ability to boost -> Choose recipient -> Choose target -> queue
|
||||||
|
|
||||||
|
"""
|
||||||
|
steps = kwargs.get("steps", [])
|
||||||
|
nsteps = len(steps)
|
||||||
|
istep = kwargs.get("istep", -1)
|
||||||
|
# one of abort, back, forward
|
||||||
|
step_direction = kwargs.get("step", "forward")
|
||||||
|
|
||||||
|
if step_direction == "back":
|
||||||
|
# step back in wizard
|
||||||
|
if istep <= 0:
|
||||||
|
return "node_combat"
|
||||||
|
istep = kwargs["istep"] = istep - 1
|
||||||
|
return steps[istep], kwargs
|
||||||
|
else:
|
||||||
|
# step to the next step in wizard
|
||||||
|
if istep >= nsteps - 1:
|
||||||
|
# we are already at end of wizard - queue action!
|
||||||
|
return _queue_action(caller, raw_string, **kwargs)
|
||||||
|
else:
|
||||||
|
# step forward
|
||||||
|
istep = kwargs["istep"] = istep + 1
|
||||||
|
return steps[istep], kwargs
|
||||||
|
|
||||||
|
|
||||||
def node_choose_enemy_target(caller, raw_string, **kwargs):
|
def node_choose_enemy_target(caller, raw_string, **kwargs):
|
||||||
"""
|
"""
|
||||||
Choose an enemy as a target for an action
|
Choose an enemy as a target for an action
|
||||||
|
|
@ -715,8 +697,6 @@ def node_combat(caller, raw_string, **kwargs):
|
||||||
|
|
||||||
combathandler = _get_combathandler(caller)
|
combathandler = _get_combathandler(caller)
|
||||||
|
|
||||||
caller.msg(f"combathandler.combatants: {combathandler.combatants}")
|
|
||||||
|
|
||||||
text = combathandler.get_combat_summary(caller)
|
text = combathandler.get_combat_summary(caller)
|
||||||
options = [
|
options = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,9 @@ import copy
|
||||||
|
|
||||||
from anything import Anything
|
from anything import Anything
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from mock import MagicMock
|
|
||||||
|
|
||||||
from evennia.utils import ansi, evmenu
|
from evennia.utils import ansi, evmenu
|
||||||
from evennia.utils.test_resources import BaseEvenniaTest
|
from evennia.utils.test_resources import BaseEvenniaTest
|
||||||
|
from mock import MagicMock
|
||||||
|
|
||||||
|
|
||||||
class TestEvMenu(TestCase):
|
class TestEvMenu(TestCase):
|
||||||
|
|
@ -70,7 +69,6 @@ class TestEvMenu(TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _depth_first(menu, tree, visited, indent):
|
def _depth_first(menu, tree, visited, indent):
|
||||||
|
|
||||||
# we are in a given node here
|
# we are in a given node here
|
||||||
nodename = menu.nodename
|
nodename = menu.nodename
|
||||||
options = menu.test_options
|
options = menu.test_options
|
||||||
|
|
@ -120,7 +118,6 @@ class TestEvMenu(TestCase):
|
||||||
subtree = nodename
|
subtree = nodename
|
||||||
else:
|
else:
|
||||||
for inum, optdict in enumerate(options):
|
for inum, optdict in enumerate(options):
|
||||||
|
|
||||||
key, desc, execute, goto = (
|
key, desc, execute, goto = (
|
||||||
optdict.get("key", ""),
|
optdict.get("key", ""),
|
||||||
optdict.get("desc", None),
|
optdict.get("desc", None),
|
||||||
|
|
@ -231,7 +228,6 @@ class TestEvMenu(TestCase):
|
||||||
|
|
||||||
|
|
||||||
class TestEvMenuExample(TestEvMenu):
|
class TestEvMenuExample(TestEvMenu):
|
||||||
|
|
||||||
menutree = "evennia.utils.tests.data.evmenu_example"
|
menutree = "evennia.utils.tests.data.evmenu_example"
|
||||||
startnode = "test_start_node"
|
startnode = "test_start_node"
|
||||||
kwargs = {"testval": "val", "testval2": "val2"}
|
kwargs = {"testval": "val", "testval2": "val2"}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue