Make turnbased combat work
This commit is contained in:
parent
ea7a3c83d7
commit
f70fd64478
7 changed files with 139 additions and 60 deletions
|
|
@ -200,10 +200,6 @@ class CombatActionStunt(CombatAction):
|
|||
f"to gain {'advantage' if self.advantage else 'disadvantage'} "
|
||||
f"against $You({target.key})!"
|
||||
)
|
||||
self.msg(
|
||||
"|yHaving succeeded, you hold back to plan your next move.|n [hold]",
|
||||
broadcast=False,
|
||||
)
|
||||
else:
|
||||
self.msg(f"$You({defender.key}) $conj(resist)! $You() $conj(fail) the stunt.")
|
||||
|
||||
|
|
@ -258,6 +254,7 @@ class CombatActionWield(CombatAction):
|
|||
|
||||
def execute(self):
|
||||
self.combatant.equipment.move(self.item)
|
||||
self.msg(f"$You() $conj(wield) $You({self.item.key}).")
|
||||
|
||||
|
||||
# main combathandler
|
||||
|
|
@ -311,6 +308,7 @@ class EvAdventureCombatBaseHandler(DefaultScript):
|
|||
key=combathandler_key,
|
||||
obj=obj,
|
||||
persistent=persistent,
|
||||
autostart=False,
|
||||
**kwargs,
|
||||
)
|
||||
obj.ndb.combathandler = combathandler
|
||||
|
|
|
|||
|
|
@ -210,6 +210,18 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
|||
self.stop()
|
||||
self.delete()
|
||||
|
||||
def get_combat_summary(self, combatant):
|
||||
"""Add your next queued action to summary"""
|
||||
summary = super().get_combat_summary(combatant)
|
||||
next_action = self.get_next_action_dict(combatant) or {"key": "hold"}
|
||||
next_repeat = self.time_until_next_repeat()
|
||||
|
||||
summary = (
|
||||
f"{summary}\n Your queued action: [|b{next_action['key']}|n] (|b{next_repeat}s|n until"
|
||||
" next round,\n or until all combatants have chosen their next action)."
|
||||
)
|
||||
return summary
|
||||
|
||||
def get_sides(self, combatant):
|
||||
"""
|
||||
Get a listing of the two 'sides' of this combat, from the perspective of the provided
|
||||
|
|
@ -265,19 +277,18 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
|||
self.combatants[combatant] = action_dict
|
||||
|
||||
# track who inserted actions this turn (non-persistent)
|
||||
did_action = set(self.ndb.did_action or ())
|
||||
did_action = set(self.ndb.did_action or set())
|
||||
did_action.add(combatant)
|
||||
if len(did_action) >= len(self.combatants):
|
||||
# everyone has inserted an action. Start next turn without waiting!
|
||||
self.force_repeat()
|
||||
|
||||
def get_next_action_dict(self, combatant, rotate_queue=True):
|
||||
def get_next_action_dict(self, combatant):
|
||||
"""
|
||||
Give the action_dict for the next action that will be executed.
|
||||
|
||||
Args:
|
||||
combatant (EvAdventureCharacter, EvAdventureNPC): The combatant to get the action for.
|
||||
rotate_queue (bool, optional): Rotate the queue after getting the action dict.
|
||||
|
||||
Returns:
|
||||
dict: The next action-dict in the queue.
|
||||
|
|
@ -355,6 +366,8 @@ class EvAdventureTurnbasedCombatHandler(EvAdventureCombatBaseHandler):
|
|||
for combatant in combatants:
|
||||
self.execute_next_action(combatant)
|
||||
|
||||
self.ndb.did_action = set()
|
||||
|
||||
# check if anyone is defeated
|
||||
for combatant in list(self.combatants.keys()):
|
||||
if combatant.hp <= 0:
|
||||
|
|
@ -364,6 +377,8 @@ 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
|
||||
|
|
@ -402,10 +417,14 @@ def _get_combathandler(caller, turn_timeout=30, flee_time=3, combathandler_key="
|
|||
caller.location,
|
||||
interval=turn_timeout,
|
||||
attributes=[("flee_time", flee_time)],
|
||||
combathandler_key=combathandler_key,
|
||||
key=combathandler_key,
|
||||
)
|
||||
|
||||
|
||||
def _rerun_current_node(caller, raw_string, **kwargs):
|
||||
return None, kwargs
|
||||
|
||||
|
||||
def _queue_action(caller, raw_string, **kwargs):
|
||||
"""
|
||||
Goto-function that queue the action with the CombatHandler. This always returns
|
||||
|
|
@ -462,6 +481,10 @@ def _get_default_wizard_options(caller, **kwargs):
|
|||
return [
|
||||
{"key": ("back", "b"), "goto": (_step_wizard, {**kwargs, **{"step": "back"}})},
|
||||
{"key": ("abort", "a"), "goto": (_step_wizard, {**kwargs, **{"step": "abort"}})},
|
||||
{
|
||||
"key": "_default",
|
||||
"goto": (_rerun_current_node, kwargs),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -473,6 +496,7 @@ def node_choose_enemy_target(caller, raw_string, **kwargs):
|
|||
action_dict = kwargs["action_dict"]
|
||||
|
||||
combathandler = _get_combathandler(caller)
|
||||
|
||||
_, enemies = combathandler.get_sides(caller)
|
||||
|
||||
options = [
|
||||
|
|
@ -489,6 +513,30 @@ def node_choose_enemy_target(caller, raw_string, **kwargs):
|
|||
return text, options
|
||||
|
||||
|
||||
def node_choose_enemy_recipient(caller, raw_string, **kwargs):
|
||||
"""
|
||||
Choose an enemy as a 'recipient' for an action.
|
||||
"""
|
||||
text = "Choose an enemy as a recipient."
|
||||
action_dict = kwargs["action_dict"]
|
||||
|
||||
combathandler = _get_combathandler(caller)
|
||||
_, enemies = combathandler.get_sides(caller)
|
||||
|
||||
options = [
|
||||
{
|
||||
"desc": target.get_display_name(caller),
|
||||
"goto": (
|
||||
_step_wizard,
|
||||
{**kwargs, **{"action_dict": {**action_dict, **{"recipient": target}}}},
|
||||
),
|
||||
}
|
||||
for target in enemies
|
||||
]
|
||||
options.extend(_get_default_wizard_options(caller, **kwargs))
|
||||
return text, options
|
||||
|
||||
|
||||
def node_choose_allied_target(caller, raw_string, **kwargs):
|
||||
"""
|
||||
Choose an enemy as a target for an action
|
||||
|
|
@ -507,11 +555,49 @@ def node_choose_allied_target(caller, raw_string, **kwargs):
|
|||
_step_wizard,
|
||||
{
|
||||
**kwargs,
|
||||
**{
|
||||
"action_dict": {
|
||||
**{**action_dict, **{"target": caller, "recipient": caller}}
|
||||
}
|
||||
**{"action_dict": {**action_dict, **{"target": caller}}},
|
||||
},
|
||||
),
|
||||
}
|
||||
]
|
||||
options.extend(
|
||||
[
|
||||
{
|
||||
"desc": target.get_display_name(caller),
|
||||
"goto": (
|
||||
_step_wizard,
|
||||
{
|
||||
**kwargs,
|
||||
**{"action_dict": {**action_dict, **{"target": target}}},
|
||||
},
|
||||
),
|
||||
}
|
||||
for target in allies
|
||||
]
|
||||
)
|
||||
options.extend(_get_default_wizard_options(caller, **kwargs))
|
||||
return text, options
|
||||
|
||||
|
||||
def node_choose_allied_recipient(caller, raw_string, **kwargs):
|
||||
"""
|
||||
Choose an allied recipient for an action
|
||||
"""
|
||||
text = "Choose an ally as a recipient."
|
||||
action_dict = kwargs["action_dict"]
|
||||
|
||||
combathandler = _get_combathandler(caller)
|
||||
allies, _ = combathandler.get_sides(caller)
|
||||
|
||||
# can choose yourself
|
||||
options = [
|
||||
{
|
||||
"desc": "Yourself",
|
||||
"goto": (
|
||||
_step_wizard,
|
||||
{
|
||||
**kwargs,
|
||||
**{"action_dict": {**action_dict, **{"recipient": caller}}},
|
||||
},
|
||||
),
|
||||
}
|
||||
|
|
@ -527,7 +613,7 @@ def node_choose_allied_target(caller, raw_string, **kwargs):
|
|||
**{
|
||||
"action_dict": {
|
||||
**action_dict,
|
||||
**{"target": target, "recipient": target},
|
||||
**{"recipient": target},
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -585,7 +671,10 @@ def node_choose_use_item(caller, raw_string, **kwargs):
|
|||
options = [
|
||||
{
|
||||
"desc": item.get_display_name(caller),
|
||||
"goto": (_step_wizard, {**kwargs, **{**action_dict, **{"item": item}}}),
|
||||
"goto": (
|
||||
_step_wizard,
|
||||
{**kwargs, **{"action_dict": {**action_dict, **{"item": item}}}},
|
||||
),
|
||||
}
|
||||
for item in caller.equipment.get_usable_objects_from_backpack()
|
||||
]
|
||||
|
|
@ -607,7 +696,10 @@ def node_choose_wield_item(caller, raw_string, **kwargs):
|
|||
options = [
|
||||
{
|
||||
"desc": item.get_display_name(caller),
|
||||
"goto": (_step_wizard, {**kwargs, **{**action_dict, **{"item": item}}}),
|
||||
"goto": (
|
||||
_step_wizard,
|
||||
{**kwargs, **{"action_dict": {**action_dict, **{"item": item}}}},
|
||||
),
|
||||
}
|
||||
for item in caller.equipment.get_wieldable_objects_from_backpack()
|
||||
]
|
||||
|
|
@ -623,6 +715,8 @@ def node_combat(caller, raw_string, **kwargs):
|
|||
|
||||
combathandler = _get_combathandler(caller)
|
||||
|
||||
caller.msg(f"combathandler.combatants: {combathandler.combatants}")
|
||||
|
||||
text = combathandler.get_combat_summary(caller)
|
||||
options = [
|
||||
{
|
||||
|
|
@ -642,8 +736,8 @@ def node_combat(caller, raw_string, **kwargs):
|
|||
{
|
||||
"steps": [
|
||||
"node_choose_ability",
|
||||
"node_choose_allied_target",
|
||||
"node_choose_enemy_target",
|
||||
"node_choose_allied_recipient",
|
||||
],
|
||||
"action_dict": {"key": "stunt", "advantage": True},
|
||||
},
|
||||
|
|
@ -656,7 +750,7 @@ def node_combat(caller, raw_string, **kwargs):
|
|||
{
|
||||
"steps": [
|
||||
"node_choose_ability",
|
||||
"node_choose_enemy_target",
|
||||
"node_choose_enemy_recipient",
|
||||
"node_choose_allied_target",
|
||||
],
|
||||
"action_dict": {"key": "stunt", "advantage": False},
|
||||
|
|
@ -701,6 +795,10 @@ def node_combat(caller, raw_string, **kwargs):
|
|||
"desc": "hold, doing nothing",
|
||||
"goto": (_queue_action, {"action_dict": {"key": "hold"}}),
|
||||
},
|
||||
{
|
||||
"key": "_default",
|
||||
"goto": "node_combat",
|
||||
},
|
||||
]
|
||||
|
||||
return text, options
|
||||
|
|
@ -763,6 +861,8 @@ class CmdTurnAttack(Command):
|
|||
{
|
||||
"node_choose_enemy_target": node_choose_enemy_target,
|
||||
"node_choose_allied_target": node_choose_allied_target,
|
||||
"node_choose_enemy_recipient": node_choose_enemy_recipient,
|
||||
"node_choose_allied_recipient": node_choose_allied_recipient,
|
||||
"node_choose_ability": node_choose_ability,
|
||||
"node_choose_use_item": node_choose_use_item,
|
||||
"node_choose_wield_item": node_choose_wield_item,
|
||||
|
|
@ -770,6 +870,7 @@ class CmdTurnAttack(Command):
|
|||
},
|
||||
startnode="node_combat",
|
||||
combathandler=combathandler,
|
||||
auto_look=False,
|
||||
# cmdset_mergetype="Union",
|
||||
persistent=True,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ class EquipmentHandler:
|
|||
WieldLocation.BACKPACK: [],
|
||||
},
|
||||
)
|
||||
self.slots[WieldLocation.BACKPACK] = [
|
||||
obj for obj in self.slots[WieldLocation.BACKPACK] if obj and obj.id
|
||||
]
|
||||
|
||||
def _save(self):
|
||||
"""
|
||||
|
|
@ -358,6 +361,7 @@ class EquipmentHandler:
|
|||
obj
|
||||
for obj in self.slots[WieldLocation.BACKPACK]
|
||||
if obj
|
||||
and obj.id
|
||||
and obj.inventory_use_slot
|
||||
in (WieldLocation.WEAPON_HAND, WieldLocation.TWO_HANDS, WieldLocation.SHIELD_HAND)
|
||||
]
|
||||
|
|
@ -376,7 +380,7 @@ class EquipmentHandler:
|
|||
return [
|
||||
obj
|
||||
for obj in self.slots[WieldLocation.BACKPACK]
|
||||
if obj and obj.inventory_use_slot in (WieldLocation.BODY, WieldLocation.HEAD)
|
||||
if obj and obj.id and obj.inventory_use_slot in (WieldLocation.BODY, WieldLocation.HEAD)
|
||||
]
|
||||
|
||||
def get_usable_objects_from_backpack(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue