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. 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. 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: 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_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 or not combathandler.id: if not combathandler:
# 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(

View file

@ -307,6 +307,15 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
action.execute() action.execute()
action.post_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): def check_stop_combat(self):
"""Check if it's time to stop combat""" """Check if it's time to stop combat"""
@ -319,8 +328,6 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
self.combatants.pop(combatant) self.combatants.pop(combatant)
self.defeated_combatants.append(combatant) self.defeated_combatants.append(combatant)
self.msg("|r$You() $conj(fall) to the ground, defeated.|n", combatant=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 # check if anyone managed to flee
flee_timeout = self.flee_timeout flee_timeout = self.flee_timeout
@ -704,7 +711,7 @@ def node_combat(caller, raw_string, **kwargs):
_step_wizard, _step_wizard,
{ {
"steps": ["node_choose_enemy_target"], "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!", "desc": "flee!",
"goto": (_queue_action, {"action_dict": {"key": "flee"}}), "goto": (_queue_action, {"action_dict": {"key": "flee", "repeat": True}}),
}, },
{ {
"desc": "hold, doing nothing", "desc": "hold, doing nothing",

View file

@ -502,7 +502,7 @@ class EvAdventureTurnbasedCombatHandlerTest(_CombatTestBase):
""" """
self.assertEqual(self.combathandler.turn, 0) self.assertEqual(self.combathandler.turn, 0)
action_dict = {"key": "flee"} action_dict = {"key": "flee", "repeat": True}
# first flee records the fleeing state # first flee records the fleeing state
self.combathandler.flee_timeout = 2 # to make sure 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.turn, 1)
self.assertEqual(self.combathandler.fleeing_combatants[self.combatant], 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( self.combatant.msg.assert_called_with(
text=( text=(
"You retreat, being exposed to attack while doing so (will escape in 1 turn).", "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 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 the menu. Deactivate for production use! When the debug flag is active, the
`persistent` flag is deactivated. `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. to be available at run.
Raises: Raises:
@ -650,7 +650,7 @@ class EvMenu:
# store ourself on the object # store ourself on the object
self.caller.ndb._evmenu = self 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 self.caller.ndb._menutree = self
if persistent: if persistent:
@ -974,6 +974,7 @@ class EvMenu:
self._quitting = True self._quitting = True
self.caller.cmdset.remove(EvMenuCmdSet) self.caller.cmdset.remove(EvMenuCmdSet)
del self.caller.ndb._evmenu del self.caller.ndb._evmenu
del self.caller.ndb._menutree # TODO Deprecated
if self._persistent: if self._persistent:
self.caller.attributes.remove("_menutree_saved") self.caller.attributes.remove("_menutree_saved")
self.caller.attributes.remove("_menutree_saved_startnode") self.caller.attributes.remove("_menutree_saved_startnode")