Complete combat unit tests
This commit is contained in:
parent
1f3d4ed840
commit
998cbb870b
2 changed files with 143 additions and 32 deletions
|
|
@ -68,7 +68,7 @@ class EvAdventureCombatTwitchHandler(EvAdventureCombatHandlerBase):
|
||||||
a message that looks different depending on who sees it. Use
|
a message that looks different depending on who sees it. Use
|
||||||
`$You(combatant_key)` to refer to other combatants.
|
`$You(combatant_key)` to refer to other combatants.
|
||||||
"""
|
"""
|
||||||
super().msg(message, broadcast=broadcast, location=self.obj.location)
|
super().msg(message, combatant=self.obj, broadcast=broadcast, location=self.obj.location)
|
||||||
|
|
||||||
def get_sides(self, combatant):
|
def get_sides(self, combatant):
|
||||||
"""
|
"""
|
||||||
|
|
@ -222,10 +222,7 @@ class EvAdventureCombatTwitchHandler(EvAdventureCombatHandlerBase):
|
||||||
if not allies or not enemies:
|
if not allies or not enemies:
|
||||||
still_standing = list_to_string(f"$You({comb.key})" for comb in allies + enemies)
|
still_standing = list_to_string(f"$You({comb.key})" for comb in allies + enemies)
|
||||||
self.msg(
|
self.msg(
|
||||||
(
|
f"The combat is over. Still standing: {still_standing}.",
|
||||||
f"The combat is over. {still_standing} $pluralize(is, {len(allies + enemies)})"
|
|
||||||
" are) still standing."
|
|
||||||
),
|
|
||||||
broadcast=False,
|
broadcast=False,
|
||||||
)
|
)
|
||||||
self.stop_combat()
|
self.stop_combat()
|
||||||
|
|
@ -255,7 +252,7 @@ class _BaseTwitchCombatCommand(Command):
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
"""
|
"""
|
||||||
Handle parsing of all supported combat syntaxes.
|
Handle parsing of most supported combat syntaxes (except stunts).
|
||||||
|
|
||||||
<action> [<target>|<item>]
|
<action> [<target>|<item>]
|
||||||
or
|
or
|
||||||
|
|
@ -264,7 +261,11 @@ class _BaseTwitchCombatCommand(Command):
|
||||||
Use 'on' to differentiate if names/items have spaces in the name.
|
Use 'on' to differentiate if names/items have spaces in the name.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
args = self.args.strip()
|
self.args = args = self.args.strip()
|
||||||
|
self.lhs, self.rhs = "", ""
|
||||||
|
|
||||||
|
if not args:
|
||||||
|
return
|
||||||
|
|
||||||
if " on " in args:
|
if " on " in args:
|
||||||
lhs, rhs = args.split(" on ", 1)
|
lhs, rhs = args.split(" on ", 1)
|
||||||
|
|
@ -304,7 +305,7 @@ class CmdAttack(_BaseTwitchCombatCommand):
|
||||||
# we use a fixed dt of 3 here, to mimic Diku style; one could also picture
|
# we use a fixed dt of 3 here, to mimic Diku style; one could also picture
|
||||||
# attacking at a different rate, depending on skills/weapon etc.
|
# attacking at a different rate, depending on skills/weapon etc.
|
||||||
combathandler.queue_action({"key": "attack", "target": target, "dt": 3})
|
combathandler.queue_action({"key": "attack", "target": target, "dt": 3})
|
||||||
combathandler.msg("$You() attacks $You(target.key)!", self.caller)
|
combathandler.msg(f"$You() $conj(attack) $You({target.key})!", self.caller)
|
||||||
|
|
||||||
|
|
||||||
class CmdLook(default_cmds.CmdLook):
|
class CmdLook(default_cmds.CmdLook):
|
||||||
|
|
@ -363,7 +364,6 @@ class CmdStunt(_BaseTwitchCombatCommand):
|
||||||
help_category = "combat"
|
help_category = "combat"
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
super().parse()
|
|
||||||
args = self.args
|
args = self.args
|
||||||
|
|
||||||
if not args or " " not in args:
|
if not args or " " not in args:
|
||||||
|
|
@ -377,6 +377,9 @@ class CmdStunt(_BaseTwitchCombatCommand):
|
||||||
stunt_type, recipient, target = None, None, None
|
stunt_type, recipient, target = None, None, None
|
||||||
|
|
||||||
stunt_type, *args = args.split(None, 1)
|
stunt_type, *args = args.split(None, 1)
|
||||||
|
if stunt_type:
|
||||||
|
stunt_type = stunt_type.strip().lower()
|
||||||
|
|
||||||
args = args[0] if args else ""
|
args = args[0] if args else ""
|
||||||
|
|
||||||
recipient, *args = args.split(None, 1)
|
recipient, *args = args.split(None, 1)
|
||||||
|
|
@ -385,8 +388,11 @@ class CmdStunt(_BaseTwitchCombatCommand):
|
||||||
# validate input and try to guess if not given
|
# validate input and try to guess if not given
|
||||||
|
|
||||||
# ability is requried
|
# ability is requried
|
||||||
if stunt_type.strip() not in ABILITY_REVERSE_MAP:
|
if not stunt_type or stunt_type not in ABILITY_REVERSE_MAP:
|
||||||
self.msg("That's not a valid ability.")
|
self.msg(
|
||||||
|
f"'{stunt_type}' is not a valid ability. Pick one of"
|
||||||
|
f" {', '.join(ABILITY_REVERSE_MAP.keys())}."
|
||||||
|
)
|
||||||
raise InterruptCommand()
|
raise InterruptCommand()
|
||||||
|
|
||||||
if not recipient:
|
if not recipient:
|
||||||
|
|
@ -405,22 +411,21 @@ class CmdStunt(_BaseTwitchCombatCommand):
|
||||||
|
|
||||||
# save what we found so it can be accessed from func()
|
# save what we found so it can be accessed from func()
|
||||||
self.advantage = advantage
|
self.advantage = advantage
|
||||||
self.stunt_type = ABILITY_REVERSE_MAP[stunt_type.strip()]
|
self.stunt_type = ABILITY_REVERSE_MAP[stunt_type]
|
||||||
self.recipient = recipient.strip()
|
self.recipient = recipient.strip()
|
||||||
self.target = target.strip()
|
self.target = target.strip()
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
combathandler = self.get_or_create_combathandler()
|
combathandler = self.get_or_create_combathandler()
|
||||||
|
|
||||||
target = self.caller.search(self.target, candidates=combathandler.combatants.keys())
|
target = self.caller.search(self.target)
|
||||||
if not target:
|
if not target:
|
||||||
return
|
return
|
||||||
recipient = self.caller.search(self.recipient, candidates=combathandler.combatants.keys())
|
recipient = self.caller.search(self.recipient)
|
||||||
if not recipient:
|
if not recipient:
|
||||||
return
|
return
|
||||||
|
|
||||||
combathandler.queue_action(
|
combathandler.queue_action(
|
||||||
self.caller,
|
|
||||||
{
|
{
|
||||||
"key": "stunt",
|
"key": "stunt",
|
||||||
"recipient": recipient,
|
"recipient": recipient,
|
||||||
|
|
@ -453,16 +458,13 @@ class CmdUseItem(_BaseTwitchCombatCommand):
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
super().parse()
|
super().parse()
|
||||||
args = self.args
|
|
||||||
|
|
||||||
if not args:
|
if not self.args:
|
||||||
self.msg("What do you want to use?")
|
self.msg("What do you want to use?")
|
||||||
raise InterruptCommand()
|
raise InterruptCommand()
|
||||||
elif "on" in args:
|
|
||||||
self.item, self.target = (part.strip() for part in args.split("on", 1))
|
self.item = self.lhs
|
||||||
else:
|
self.target = self.rhs or "me"
|
||||||
self.item, *target = args.split(None, 1)
|
|
||||||
self.target = target[0] if target else "me"
|
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
item = self.caller.search(
|
item = self.caller.search(
|
||||||
|
|
@ -477,7 +479,7 @@ class CmdUseItem(_BaseTwitchCombatCommand):
|
||||||
return
|
return
|
||||||
|
|
||||||
combathandler = self.get_or_create_combathandler()
|
combathandler = self.get_or_create_combathandler()
|
||||||
combathandler.queue_action(self.caller, {"key": "use", "item": item, "target": self.target})
|
combathandler.queue_action({"key": "use", "item": item, "target": target})
|
||||||
combathandler.msg(
|
combathandler.msg(
|
||||||
f"$You() prepare to use {item.get_display_name(self.caller)}!", self.caller
|
f"$You() prepare to use {item.get_display_name(self.caller)}!", self.caller
|
||||||
)
|
)
|
||||||
|
|
@ -518,10 +520,8 @@ class CmdWield(_BaseTwitchCombatCommand):
|
||||||
self.msg("(You must carry the item to wield it.)")
|
self.msg("(You must carry the item to wield it.)")
|
||||||
return
|
return
|
||||||
combathandler = self.get_or_create_combathandler()
|
combathandler = self.get_or_create_combathandler()
|
||||||
combathandler.queue_action(self.caller, {"key": "wield", "item": item})
|
combathandler.queue_action({"key": "wield", "item": item})
|
||||||
combathandler.msg(
|
combathandler.msg(f"$You() reach for {item.get_display_name(self.caller)}!", self.caller)
|
||||||
f"$You() start wielding {item.get_display_name(self.caller)}!", self.caller
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TwitchAttackCmdSet(CmdSet):
|
class TwitchAttackCmdSet(CmdSet):
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,14 @@ class TestEvAdventureTwitchCombatHandler(EvenniaCommandTestMixin, _CombatTestBas
|
||||||
sides = self.combatant_combathandler.get_sides(self.combatant)
|
sides = self.combatant_combathandler.get_sides(self.combatant)
|
||||||
self.assertEqual(sides, ([], [self.target]))
|
self.assertEqual(sides, ([], [self.target]))
|
||||||
|
|
||||||
|
def test_give_advantage(self):
|
||||||
|
self.combatant_combathandler.give_advantage(self.combatant, self.target)
|
||||||
|
self.assertTrue(self.combatant_combathandler.advantages_against[self.target])
|
||||||
|
|
||||||
|
def test_give_disadvantage(self):
|
||||||
|
self.combatant_combathandler.give_disadvantage(self.combatant, self.target)
|
||||||
|
self.assertTrue(self.combatant_combathandler.disadvantages_against[self.target])
|
||||||
|
|
||||||
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
||||||
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock(return_value=999))
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock(return_value=999))
|
||||||
def test_queue_action(self):
|
def test_queue_action(self):
|
||||||
|
|
@ -584,7 +592,8 @@ class TestEvAdventureTwitchCombatHandler(EvenniaCommandTestMixin, _CombatTestBas
|
||||||
def test_check_stop_combat(self):
|
def test_check_stop_combat(self):
|
||||||
"""Test combat-stop functionality"""
|
"""Test combat-stop functionality"""
|
||||||
|
|
||||||
# noone remains
|
# noone remains (both combatant/target <0 hp
|
||||||
|
# get_sides does not include the caller
|
||||||
self.combatant_combathandler.get_sides = Mock(return_value=([], []))
|
self.combatant_combathandler.get_sides = Mock(return_value=([], []))
|
||||||
self.combatant_combathandler.stop_combat = Mock()
|
self.combatant_combathandler.stop_combat = Mock()
|
||||||
|
|
||||||
|
|
@ -592,21 +601,123 @@ class TestEvAdventureTwitchCombatHandler(EvenniaCommandTestMixin, _CombatTestBas
|
||||||
self.target.hp = -1
|
self.target.hp = -1
|
||||||
|
|
||||||
self.combatant_combathandler.check_stop_combat()
|
self.combatant_combathandler.check_stop_combat()
|
||||||
self.combatant.msg.assert_called_with()
|
self.combatant.msg.assert_called_with(
|
||||||
|
text=("Noone stands after the dust settles.", {}), from_obj=self.combatant
|
||||||
|
)
|
||||||
self.combatant_combathandler.stop_combat.assert_called()
|
self.combatant_combathandler.stop_combat.assert_called()
|
||||||
|
|
||||||
# only one side wiped out
|
# only one side wiped out
|
||||||
self.combatant = 10
|
self.combatant.hp = 10
|
||||||
|
self.target.hp = -1
|
||||||
self.combatant_combathandler.get_sides = Mock(return_value=([], []))
|
self.combatant_combathandler.get_sides = Mock(return_value=([], []))
|
||||||
self.combatant_combathandler.check_stop_combat()
|
self.combatant_combathandler.check_stop_combat()
|
||||||
self.combatant.msg.assert_called_with()
|
self.combatant.msg.assert_called_with(
|
||||||
|
text=("The combat is over. Still standing: You.", {}), from_obj=self.combatant
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock())
|
||||||
|
def test_hold(self):
|
||||||
|
self.call(combat_twitch.CmdHold(), "", "You hold back, doing nothing")
|
||||||
|
self.assertEqual(self.combatant_combathandler.action_dict, {"key": "hold"})
|
||||||
|
|
||||||
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
||||||
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock())
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock())
|
||||||
def test_attack(self):
|
def test_attack(self):
|
||||||
"""Test attack action in the twitch combathandler"""
|
"""Test attack action in the twitch combathandler"""
|
||||||
self.call(combat_twitch.CmdAttack(), f"{self.target.key}", "")
|
self.call(combat_twitch.CmdAttack(), self.target.key, "You attack testmonster!")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.combatant_combathandler.action_dict,
|
self.combatant_combathandler.action_dict,
|
||||||
{"key": "attack", "target": self.target, "dt": 3},
|
{"key": "attack", "target": self.target, "dt": 3},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock())
|
||||||
|
def test_stunt(self):
|
||||||
|
boost_result = {
|
||||||
|
"key": "stunt",
|
||||||
|
"recipient": self.combatant,
|
||||||
|
"target": self.target,
|
||||||
|
"advantage": True,
|
||||||
|
"stunt_type": Ability.STR,
|
||||||
|
"defense_type": Ability.STR,
|
||||||
|
}
|
||||||
|
foil_result = {
|
||||||
|
"key": "stunt",
|
||||||
|
"recipient": self.target,
|
||||||
|
"target": self.combatant,
|
||||||
|
"advantage": False,
|
||||||
|
"stunt_type": Ability.STR,
|
||||||
|
"defense_type": Ability.STR,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.call(
|
||||||
|
combat_twitch.CmdStunt(),
|
||||||
|
f"STR {self.target.key}",
|
||||||
|
"You prepare a stunt!",
|
||||||
|
cmdstring="boost",
|
||||||
|
)
|
||||||
|
self.assertEqual(self.combatant_combathandler.action_dict, boost_result)
|
||||||
|
|
||||||
|
self.call(
|
||||||
|
combat_twitch.CmdStunt(),
|
||||||
|
f"STR me {self.target.key}",
|
||||||
|
"You prepare a stunt!",
|
||||||
|
cmdstring="boost",
|
||||||
|
)
|
||||||
|
self.assertEqual(self.combatant_combathandler.action_dict, boost_result)
|
||||||
|
|
||||||
|
self.call(
|
||||||
|
combat_twitch.CmdStunt(),
|
||||||
|
f"STR {self.target.key}",
|
||||||
|
"You prepare a stunt!",
|
||||||
|
cmdstring="foil",
|
||||||
|
)
|
||||||
|
self.assertEqual(self.combatant_combathandler.action_dict, foil_result)
|
||||||
|
|
||||||
|
self.call(
|
||||||
|
combat_twitch.CmdStunt(),
|
||||||
|
f"STR {self.target.key} me",
|
||||||
|
"You prepare a stunt!",
|
||||||
|
cmdstring="foil",
|
||||||
|
)
|
||||||
|
self.assertEqual(self.combatant_combathandler.action_dict, foil_result)
|
||||||
|
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock())
|
||||||
|
def test_useitem(self):
|
||||||
|
item = create.create_object(
|
||||||
|
EvAdventureConsumable, key="potion", attributes=[("uses", 2)], location=self.combatant
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call(combat_twitch.CmdUseItem(), "potion", "You prepare to use potion!")
|
||||||
|
self.assertEqual(
|
||||||
|
self.combatant_combathandler.action_dict,
|
||||||
|
{"key": "use", "item": item, "target": self.combatant},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call(
|
||||||
|
combat_twitch.CmdUseItem(),
|
||||||
|
f"potion on {self.target.key}",
|
||||||
|
"You prepare to use potion!",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.combatant_combathandler.action_dict,
|
||||||
|
{"key": "use", "item": item, "target": self.target},
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.unrepeat", new=Mock())
|
||||||
|
@patch("evennia.contrib.tutorials.evadventure.combat_twitch.repeat", new=Mock())
|
||||||
|
def test_wield(self):
|
||||||
|
sword = create.create_object(EvAdventureWeapon, key="sword", location=self.combatant)
|
||||||
|
runestone = create.create_object(
|
||||||
|
EvAdventureWeapon, key="runestone", location=self.combatant
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call(combat_twitch.CmdWield(), "sword", "You reach for sword!")
|
||||||
|
self.assertEqual(self.combatant_combathandler.action_dict, {"key": "wield", "item": sword})
|
||||||
|
|
||||||
|
self.call(combat_twitch.CmdWield(), "runestone", "You reach for runestone!")
|
||||||
|
self.assertEqual(
|
||||||
|
self.combatant_combathandler.action_dict, {"key": "wield", "item": runestone}
|
||||||
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue