Fix some more issues with the turnbased combat

This commit is contained in:
Griatch 2023-05-19 08:20:10 +02:00
parent d13ac065c7
commit 1c5746d59c
5 changed files with 22 additions and 9 deletions

View file

@ -204,6 +204,8 @@ class EvAdventureCombatBaseHandler(DefaultScript):
This helper method uses `obj.scripts.get()` to find if the combat script already exists 'on' the provided `obj`. If not, it will create it using Evennia's [create_script](evennia.utils.create.create_script) function. For some extra speed we cache the handler as `obj.ndb.combathandler` The `.ndb.` (non-db) means that handler is cached only in memory.
To know if the cache is out of date, we make sure to also check if the combathandler we got has an `id` that is not `None` . If it's `None`, this means the database entity was deleted and we just got its cached python representation from memory - we need to recreate it.
This is a `classmethod`, meaning it should be used on the handler class directly (rather than on an _instance_ of said class). This makes sense because this method actually should return the new instance.
As a class method we'll need to call this directly on the class, like this:

View file

@ -298,9 +298,9 @@ class EvAdventureCombatBaseHandler(DefaultScript):
combathandler_key = kwargs.pop("key", "combathandler")
combathandler = obj.ndb.combathandler
if not combathandler:
if not combathandler or not combathandler.id:
combathandler = obj.scripts.get(combathandler_key).first()
if not combathandler or not combathandler.id:
if not combathandler:
# have to create from scratch
persistent = kwargs.pop("persistent", True)
combathandler = create_script(

View file

@ -307,6 +307,15 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
action.execute()
action.post_execute()
if action_dict.get("repeat", False):
# queue the action again *without updating the *.ndb.did_action list* (otherwise
# we'd always auto-end the turn if everyone used repeating actions and there'd be
# no time to change it before the next round)
self.combatants[combatant] = action_dict
else:
# if not a repeat, set the fallback action
self.combatants[combatant] = self.fallback_action_dict
def check_stop_combat(self):
"""Check if it's time to stop combat"""
@ -319,8 +328,6 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
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
@ -704,7 +711,7 @@ def node_combat(caller, raw_string, **kwargs):
_step_wizard,
{
"steps": ["node_choose_enemy_target"],
"action_dict": {"key": "attack", "target": None},
"action_dict": {"key": "attack", "target": None, "repeat": True},
},
),
},
@ -768,7 +775,7 @@ def node_combat(caller, raw_string, **kwargs):
},
{
"desc": "flee!",
"goto": (_queue_action, {"action_dict": {"key": "flee"}}),
"goto": (_queue_action, {"action_dict": {"key": "flee", "repeat": True}}),
},
{
"desc": "hold, doing nothing",

View file

@ -502,7 +502,7 @@ class EvAdventureTurnbasedCombatHandlerTest(_CombatTestBase):
"""
self.assertEqual(self.combathandler.turn, 0)
action_dict = {"key": "flee"}
action_dict = {"key": "flee", "repeat": True}
# first flee records the fleeing state
self.combathandler.flee_timeout = 2 # to make sure
@ -510,6 +510,9 @@ class EvAdventureTurnbasedCombatHandlerTest(_CombatTestBase):
self.assertEqual(self.combathandler.turn, 1)
self.assertEqual(self.combathandler.fleeing_combatants[self.combatant], 1)
# action_dict should still be in place due to repeat
self.assertEqual(self.combathandler.combatants[self.combatant], action_dict)
self.combatant.msg.assert_called_with(
text=(
"You retreat, being exposed to attack while doing so (will escape in 1 turn).",

View file

@ -556,7 +556,7 @@ class EvMenu:
by default in all nodes of the menu. This will print out the current state of
the menu. Deactivate for production use! When the debug flag is active, the
`persistent` flag is deactivated.
**kwargs: All kwargs will become initialization variables on `caller.ndb._menutree`,
**kwargs: All kwargs will become initialization variables on `caller.ndb._evmenu`,
to be available at run.
Raises:
@ -650,7 +650,7 @@ class EvMenu:
# store ourself on the object
self.caller.ndb._evmenu = self
# DEPRECATED - for backwards-compatibility. Use `.ndb._evmenu` instead
# TODO DEPRECATED - for backwards-compatibility. Use `.ndb._evmenu` instead
self.caller.ndb._menutree = self
if persistent:
@ -974,6 +974,7 @@ class EvMenu:
self._quitting = True
self.caller.cmdset.remove(EvMenuCmdSet)
del self.caller.ndb._evmenu
del self.caller.ndb._menutree # TODO Deprecated
if self._persistent:
self.caller.attributes.remove("_menutree_saved")
self.caller.attributes.remove("_menutree_saved_startnode")