Finish tests for combathandler
This commit is contained in:
parent
4a08a6ae94
commit
f42f4bf23e
3 changed files with 66 additions and 400 deletions
|
|
@ -28,8 +28,7 @@ nothing. Available actions:
|
||||||
3. Make [S]tunt <target/yourself> (gain/give advantage/disadvantage for future attacks)
|
3. Make [S]tunt <target/yourself> (gain/give advantage/disadvantage for future attacks)
|
||||||
4. S[W]ap weapon / spell rune
|
4. S[W]ap weapon / spell rune
|
||||||
5. [U]se <item>
|
5. [U]se <item>
|
||||||
6. [F]lee/disengage (takes two turns)
|
6. [F]lee/disengage (takes one turn, during which attacks have advantage against you)
|
||||||
7. [B]lock <target> from fleeing
|
|
||||||
8. [H]esitate/Do nothing
|
8. [H]esitate/Do nothing
|
||||||
|
|
||||||
You can also use say/emote between rounds.
|
You can also use say/emote between rounds.
|
||||||
|
|
@ -118,8 +117,6 @@ from .objects import EvAdventureObject
|
||||||
COMBAT_HANDLER_KEY = "evadventure_turnbased_combathandler"
|
COMBAT_HANDLER_KEY = "evadventure_turnbased_combathandler"
|
||||||
COMBAT_HANDLER_INTERVAL = 30
|
COMBAT_HANDLER_INTERVAL = 30
|
||||||
|
|
||||||
COMBAT_ACTION_DICT_DONOTHING = {"key": "nothing", "desc": "Do nothing"}
|
|
||||||
|
|
||||||
|
|
||||||
class CombatFailure(RuntimeError):
|
class CombatFailure(RuntimeError):
|
||||||
"""
|
"""
|
||||||
|
|
@ -168,10 +165,14 @@ class CombatAction:
|
||||||
self.combathandler.disadvantage_matrix[recipient][target] = True
|
self.combathandler.disadvantage_matrix[recipient][target] = True
|
||||||
|
|
||||||
def has_advantage(self, recipient, target):
|
def has_advantage(self, recipient, target):
|
||||||
return bool(self.combathandler.advantage_matrix[recipient].pop(target, False))
|
return bool(self.combathandler.advantage_matrix[recipient].pop(target, False)) or (
|
||||||
|
target in self.combathandler.fleeing_combatants
|
||||||
|
)
|
||||||
|
|
||||||
def has_disadvantage(self, recipient, target):
|
def has_disadvantage(self, recipient, target):
|
||||||
return bool(self.combathandler.disadvantage_matrix[recipient].pop(target, False))
|
return bool(self.combathandler.disadvantage_matrix[recipient].pop(target, False)) or (
|
||||||
|
recipient in self.combathandler.fleeing_combatants
|
||||||
|
)
|
||||||
|
|
||||||
def lose_advantage(self, recipient, target):
|
def lose_advantage(self, recipient, target):
|
||||||
self.combathandler.advantage_matrix[recipient][target] = False
|
self.combathandler.advantage_matrix[recipient][target] = False
|
||||||
|
|
@ -179,14 +180,6 @@ class CombatAction:
|
||||||
def lose_disadvantage(self, recipient, target):
|
def lose_disadvantage(self, recipient, target):
|
||||||
self.combathandler.disadvantage_matrix[recipient][target] = False
|
self.combathandler.disadvantage_matrix[recipient][target] = False
|
||||||
|
|
||||||
def flee(self, fleer):
|
|
||||||
if fleer not in self.combathandler.fleeing_combatants:
|
|
||||||
# we record the turn on which we started fleeing
|
|
||||||
self.combathandler.fleeing_combatants[fleer] = self.combathandler.turn
|
|
||||||
|
|
||||||
def unflee(self, fleer):
|
|
||||||
self.combathandler.fleeing_combatants.pop(fleer, None)
|
|
||||||
|
|
||||||
def msg(self, message, broadcast=True):
|
def msg(self, message, broadcast=True):
|
||||||
"""
|
"""
|
||||||
Convenience route to the combathandler msg-sender mechanism.
|
Convenience route to the combathandler msg-sender mechanism.
|
||||||
|
|
@ -217,6 +210,13 @@ class CombatAction:
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def post_execute(self):
|
||||||
|
"""
|
||||||
|
Called after execution.
|
||||||
|
"""
|
||||||
|
# most actions abort ongoing fleeing actions.
|
||||||
|
self.combathandler.fleeing_combatants.pop(self.combatant, None)
|
||||||
|
|
||||||
|
|
||||||
class CombatActionDoNothing(CombatAction):
|
class CombatActionDoNothing(CombatAction):
|
||||||
"""
|
"""
|
||||||
|
|
@ -392,52 +392,22 @@ class CombatActionFlee(CombatAction):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
|
|
||||||
|
if self.combatant not in self.combathandler.fleeing_combatants:
|
||||||
|
# we record the turn on which we started fleeing
|
||||||
|
self.combathandler.fleeing_combatants[self.combatant] = self.combathandler.turn
|
||||||
|
|
||||||
|
flee_timeout = self.combathandler.flee_timeout
|
||||||
self.msg(
|
self.msg(
|
||||||
"$You() $conj(retreat), and will leave combat next round unless someone successfully "
|
"$You() $conj(retreat), leaving yourself exposed while doing so (will escape in "
|
||||||
"blocks the escape."
|
f"{flee_timeout} $pluralize(turn, {flee_timeout}))."
|
||||||
)
|
|
||||||
self.flee(self.combatant)
|
|
||||||
|
|
||||||
|
|
||||||
class CombatActionHinder(CombatAction):
|
|
||||||
"""
|
|
||||||
Hinder a fleeing opponent from fleeing/disengaging from combat.
|
|
||||||
|
|
||||||
action_dict = {
|
|
||||||
"key": "hinder",
|
|
||||||
"target": Character/NPC
|
|
||||||
}
|
|
||||||
|
|
||||||
Note:
|
|
||||||
Refer to as 'hinder'
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def execute(self):
|
|
||||||
|
|
||||||
hinderer = self.combatant
|
|
||||||
target = self.target
|
|
||||||
|
|
||||||
is_success, _, txt = rules.dice.opposed_saving_throw(
|
|
||||||
hinderer,
|
|
||||||
target,
|
|
||||||
attack_type=Ability.DEX,
|
|
||||||
defense_type=Ability.DEX,
|
|
||||||
advantage=self.has_advantage(hinderer, target),
|
|
||||||
disadvantage=self.has_disadvantage(hinderer, target),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# handle result
|
def post_execute(self):
|
||||||
self.msg(
|
"""
|
||||||
f"$You() $conj(try) to block the retreat of $You({target.key}). {txt}",
|
We override the default since we don't want to cancel fleeing here.
|
||||||
)
|
"""
|
||||||
if is_success:
|
pass
|
||||||
# managed to stop the target from fleeing/disengaging
|
|
||||||
self.unflee(target)
|
|
||||||
self.msg(f"$You() $conj(block) the retreat of $You({target.key})")
|
|
||||||
else:
|
|
||||||
# failed to hinder the target
|
|
||||||
self.msg(f"$You({target.key}) $conj(dodge) away from you $You()!")
|
|
||||||
|
|
||||||
|
|
||||||
class EvAdventureCombatHandler(DefaultScript):
|
class EvAdventureCombatHandler(DefaultScript):
|
||||||
|
|
@ -447,9 +417,6 @@ class EvAdventureCombatHandler(DefaultScript):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# how many actions can be queued at a time (per combatant)
|
|
||||||
max_action_queue_size = 1
|
|
||||||
|
|
||||||
# available actions in combat
|
# available actions in combat
|
||||||
action_classes = {
|
action_classes = {
|
||||||
"nothing": CombatActionDoNothing,
|
"nothing": CombatActionDoNothing,
|
||||||
|
|
@ -458,18 +425,20 @@ class EvAdventureCombatHandler(DefaultScript):
|
||||||
"use": CombatActionUseItem,
|
"use": CombatActionUseItem,
|
||||||
"wield": CombatActionWield,
|
"wield": CombatActionWield,
|
||||||
"flee": CombatActionFlee,
|
"flee": CombatActionFlee,
|
||||||
"hinder": CombatActionHinder,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# how many actions can be queued at a time (per combatant)
|
||||||
|
max_action_queue_size = 1
|
||||||
|
|
||||||
# fallback action if not selecting anything
|
# fallback action if not selecting anything
|
||||||
fallback_action = "attack"
|
fallback_action_dict = {"key": "nothing"}
|
||||||
|
|
||||||
|
# how many turns you must be fleeing before escaping
|
||||||
|
flee_timeout = 1
|
||||||
|
|
||||||
# persistent storage
|
# persistent storage
|
||||||
turn = AttributeProperty(0)
|
turn = AttributeProperty(0)
|
||||||
|
|
||||||
# how many turns you must be fleeing before escaping
|
|
||||||
flee_timeout = AttributeProperty(1)
|
|
||||||
|
|
||||||
# who is involved in combat, and their action queue,
|
# who is involved in combat, and their action queue,
|
||||||
# as {combatant: [actiondict, actiondict,...]}
|
# as {combatant: [actiondict, actiondict,...]}
|
||||||
combatants = AttributeProperty(dict)
|
combatants = AttributeProperty(dict)
|
||||||
|
|
@ -617,7 +586,7 @@ class EvAdventureCombatHandler(DefaultScript):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
action_queue = self.combatants[combatant]
|
action_queue = self.combatants[combatant]
|
||||||
action_dict = action_queue[0] if action_queue else COMBAT_ACTION_DICT_DONOTHING
|
action_dict = action_queue[0] if action_queue else self.fallback_action_dict
|
||||||
# rotate the queue to the left so that the first element is now the last one
|
# rotate the queue to the left so that the first element is now the last one
|
||||||
action_queue.rotate(-1)
|
action_queue.rotate(-1)
|
||||||
|
|
||||||
|
|
@ -626,6 +595,7 @@ class EvAdventureCombatHandler(DefaultScript):
|
||||||
action = action_class(self, combatant, action_dict)
|
action = action_class(self, combatant, action_dict)
|
||||||
|
|
||||||
action.execute()
|
action.execute()
|
||||||
|
action.post_execute()
|
||||||
|
|
||||||
def execute_full_turn(self):
|
def execute_full_turn(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -653,9 +623,9 @@ class EvAdventureCombatHandler(DefaultScript):
|
||||||
|
|
||||||
# check if anyone managed to flee
|
# check if anyone managed to flee
|
||||||
flee_timeout = self.flee_timeout
|
flee_timeout = self.flee_timeout
|
||||||
for combatant, started_fleeing in dict(self.fleeing_combatants):
|
for combatant, started_fleeing in self.fleeing_combatants.items():
|
||||||
if self.turn - started_fleeing > flee_timeout:
|
if self.turn - started_fleeing >= flee_timeout:
|
||||||
# if they are still alive/fleeing and started fleeing >1 round ago, they succeed
|
# 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.msg("|y$You() successfully $conj(flee) from combat.|n", combatant=combatant)
|
||||||
self.remove_combatant(combatant)
|
self.remove_combatant(combatant)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,6 @@ class EvAdventureCombatHandlerTest(BaseEvenniaTest):
|
||||||
"use": combat.CombatActionUseItem,
|
"use": combat.CombatActionUseItem,
|
||||||
"wield": combat.CombatActionWield,
|
"wield": combat.CombatActionWield,
|
||||||
"flee": combat.CombatActionFlee,
|
"flee": combat.CombatActionFlee,
|
||||||
"hinder": combat.CombatActionHinder,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.assertEqual(chandler.flee_timeout, 1)
|
self.assertEqual(chandler.flee_timeout, 1)
|
||||||
|
|
@ -213,12 +212,6 @@ class EvAdventureCombatHandlerTest(BaseEvenniaTest):
|
||||||
self.assertFalse(action.has_advantage(combatant, target))
|
self.assertFalse(action.has_advantage(combatant, target))
|
||||||
self.assertFalse(action.has_disadvantage(combatant, target))
|
self.assertFalse(action.has_disadvantage(combatant, target))
|
||||||
|
|
||||||
action.flee(combatant)
|
|
||||||
self.assertIn(combatant, self.combathandler.fleeing_combatants)
|
|
||||||
|
|
||||||
action.unflee(combatant)
|
|
||||||
self.assertNotIn(combatant, self.combathandler.fleeing_combatants)
|
|
||||||
|
|
||||||
action.msg(f"$You() attack $You({target.key}).")
|
action.msg(f"$You() attack $You({target.key}).")
|
||||||
combatant.msg.assert_called_with(text=("You attack testmonster.", {}), from_obj=combatant)
|
combatant.msg.assert_called_with(text=("You attack testmonster.", {}), from_obj=combatant)
|
||||||
|
|
||||||
|
|
@ -382,330 +375,32 @@ class EvAdventureCombatHandlerTest(BaseEvenniaTest):
|
||||||
self.assertEqual(self.combatant.equipment.slots[WieldLocation.WEAPON_HAND], sword)
|
self.assertEqual(self.combatant.equipment.slots[WieldLocation.WEAPON_HAND], sword)
|
||||||
self.assertEqual(self.combatant.equipment.slots[WieldLocation.TWO_HANDS], None)
|
self.assertEqual(self.combatant.equipment.slots[WieldLocation.TWO_HANDS], None)
|
||||||
|
|
||||||
|
def test_flee__success(self):
|
||||||
|
"""
|
||||||
|
Test fleeing twice, leading to leaving combat.
|
||||||
|
|
||||||
# def test_flee__success(self):
|
"""
|
||||||
# """
|
|
||||||
# Test fleeing twice, leading to leaving combat.
|
|
||||||
#
|
|
||||||
# """
|
|
||||||
# # first flee records the fleeing state
|
|
||||||
# self._run_action(combat_turnbased.CombatActionFlee, None)
|
|
||||||
# self.assertTrue(self.combatant in self.combathandler.fleeing_combatants)
|
|
||||||
#
|
|
||||||
# # second flee should remove combatant
|
|
||||||
# self._run_action(combat_turnbased.CombatActionFlee, None)
|
|
||||||
# self.assertIsNone(self.combathandler.pk)
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_flee__blocked(self, mock_randint):
|
|
||||||
# """ """
|
|
||||||
# mock_randint.return_value = 11 # means block will succeed
|
|
||||||
#
|
|
||||||
# self._run_action(combat_turnbased.CombatActionFlee, None)
|
|
||||||
# self.assertTrue(self.combatant in self.combathandler.fleeing_combatants)
|
|
||||||
#
|
|
||||||
# # other combatant blocks in the same turn
|
|
||||||
# self.combathandler.register_action(
|
|
||||||
# self.combatant, combat_turnbased.CombatActionFlee.key, None
|
|
||||||
# )
|
|
||||||
# self.combathandler.register_action(
|
|
||||||
# self.target, combat_turnbased.CombatActionBlock.key, self.combatant
|
|
||||||
# )
|
|
||||||
# self.combathandler._end_turn()
|
|
||||||
# # the fleeing combatant should remain now
|
|
||||||
# self.assertTrue(self.combatant not in self.combathandler.fleeing_combatants)
|
|
||||||
# self.assertTrue(self.combatant in self.combathandler.combatants)
|
|
||||||
|
|
||||||
|
self.assertEqual(self.combathandler.turn, 0)
|
||||||
|
action_dict = {"key": "flee"}
|
||||||
|
|
||||||
# class EvAdventureTurnbasedCombatHandlerTest(EvAdventureMixin, BaseEvenniaTest):
|
# first flee records the fleeing state
|
||||||
# """
|
self._run_actions(action_dict)
|
||||||
# Test methods on the turn-based combat handler.
|
self.assertEqual(self.combathandler.turn, 1)
|
||||||
#
|
self.assertEqual(self.combathandler.fleeing_combatants[self.combatant], 1)
|
||||||
# """
|
|
||||||
#
|
self.combatant.msg.assert_called_with(
|
||||||
# maxDiff = None
|
text=(
|
||||||
#
|
"You retreat, leaving yourself exposed while doing so (will escape in 1 turn).",
|
||||||
# # make sure to mock away all time-keeping elements
|
{},
|
||||||
# @patch(
|
),
|
||||||
# "evennia.contrib.tutorials.evadventure.combat_turnbased"
|
from_obj=self.combatant,
|
||||||
# ".EvAdventureCombatHandler.interval",
|
)
|
||||||
# new=-1,
|
# Check that enemies have advantage against you now
|
||||||
# )
|
action = combat.CombatAction(self.combathandler, self.target, {"key": "nothing"})
|
||||||
# @patch(
|
self.assertTrue(action.has_advantage(self.target, self.combatant))
|
||||||
# "evennia.contrib.tutorials.evadventure.combat_turnbased.delay",
|
|
||||||
# new=MagicMock(return_value=None),
|
# second flee should remove combatant
|
||||||
# )
|
self._run_actions(action_dict)
|
||||||
# def setUp(self):
|
# this ends combat, so combathandler should be gone
|
||||||
# super().setUp()
|
self.assertIsNone(self.combathandler.pk)
|
||||||
# self.location.allow_combat = True
|
|
||||||
# self.location.allow_death = True
|
|
||||||
# self.combatant = self.character
|
|
||||||
# self.target = create.create_object(
|
|
||||||
# EvAdventureMob,
|
|
||||||
# key="testmonster",
|
|
||||||
# location=self.location,
|
|
||||||
# attributes=(("is_idle", True),),
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# # this already starts turn 1
|
|
||||||
# self.combathandler = combat_turnbased.join_combat(self.combatant, self.target)
|
|
||||||
#
|
|
||||||
# def tearDown(self):
|
|
||||||
# self.combathandler.delete()
|
|
||||||
# self.target.delete()
|
|
||||||
#
|
|
||||||
# def test_remove_combatant(self):
|
|
||||||
# self.assertTrue(bool(self.combatant.db.combathandler))
|
|
||||||
# self.combathandler.remove_combatant(self.combatant)
|
|
||||||
# self.assertFalse(self.combatant in self.combathandler.combatants)
|
|
||||||
# self.assertFalse(bool(self.combatant.db.combathandler))
|
|
||||||
#
|
|
||||||
# def test_start_turn(self):
|
|
||||||
# self.combathandler._start_turn()
|
|
||||||
# self.assertEqual(self.combathandler.turn, 2)
|
|
||||||
# self.combathandler._start_turn()
|
|
||||||
# self.assertEqual(self.combathandler.turn, 3)
|
|
||||||
#
|
|
||||||
# def test_end_of_turn__empty(self):
|
|
||||||
# self.combathandler._end_turn()
|
|
||||||
#
|
|
||||||
# def test_add_combatant(self):
|
|
||||||
# self.combathandler._init_menu = MagicMock()
|
|
||||||
# combatant3 = create.create_object(EvAdventureCharacter, key="testcharacter3")
|
|
||||||
# self.combathandler.add_combatant(combatant3)
|
|
||||||
#
|
|
||||||
# self.assertTrue(combatant3 in self.combathandler.combatants)
|
|
||||||
# self.combathandler._init_menu.assert_called_once()
|
|
||||||
#
|
|
||||||
# def test_start_combat(self):
|
|
||||||
# self.combathandler._start_turn = MagicMock()
|
|
||||||
# self.combathandler.start = MagicMock()
|
|
||||||
# self.combathandler.start_combat()
|
|
||||||
# self.combathandler._start_turn.assert_called_once()
|
|
||||||
# self.combathandler.start.assert_called_once()
|
|
||||||
#
|
|
||||||
# def test_combat_summary(self):
|
|
||||||
# result = self.combathandler.get_combat_summary(self.combatant)
|
|
||||||
# self.assertTrue("You (4 / 4 health)" in result)
|
|
||||||
# self.assertTrue("testmonster" in result)
|
|
||||||
#
|
|
||||||
# def test_msg(self):
|
|
||||||
# self.location.msg_contents = MagicMock()
|
|
||||||
# self.combathandler.msg("You hurt the target", combatant=self.combatant)
|
|
||||||
# self.location.msg_contents.assert_called_with(
|
|
||||||
# "You hurt the target",
|
|
||||||
# from_obj=self.combatant,
|
|
||||||
# exclude=[],
|
|
||||||
# mapping={"testchar": self.combatant, "testmonster": self.target},
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# def test_gain_advantage(self):
|
|
||||||
# self.combathandler.gain_advantage(self.combatant, self.target)
|
|
||||||
# self.assertTrue(bool(self.combathandler.advantage_matrix[self.combatant][self.target]))
|
|
||||||
#
|
|
||||||
# def test_gain_disadvantage(self):
|
|
||||||
# self.combathandler.gain_disadvantage(self.combatant, self.target)
|
|
||||||
# self.assertTrue(bool(self.combathandler.disadvantage_matrix[self.combatant][self.target]))
|
|
||||||
#
|
|
||||||
# def test_flee(self):
|
|
||||||
# self.combathandler.flee(self.combatant)
|
|
||||||
# self.assertTrue(self.combatant in self.combathandler.fleeing_combatants)
|
|
||||||
#
|
|
||||||
# def test_unflee(self):
|
|
||||||
# self.combathandler.unflee(self.combatant)
|
|
||||||
# self.assertFalse(self.combatant in self.combathandler.fleeing_combatants)
|
|
||||||
#
|
|
||||||
# def test_register_and_run_action(self):
|
|
||||||
# action_class = combat_turnbased.CombatActionAttack
|
|
||||||
# action = self.combathandler.combatant_actions[self.combatant][action_class.key]
|
|
||||||
#
|
|
||||||
# self.combathandler.register_action(self.combatant, action.key)
|
|
||||||
#
|
|
||||||
# self.assertEqual(self.combathandler.action_queue[self.combatant], (action, (), {}))
|
|
||||||
#
|
|
||||||
# action.use = MagicMock()
|
|
||||||
#
|
|
||||||
# self.combathandler._end_turn()
|
|
||||||
# action.use.assert_called_once()
|
|
||||||
#
|
|
||||||
# def test_get_available_actions(self):
|
|
||||||
# result = self.combathandler.get_available_actions(self.combatant)
|
|
||||||
# self.assertTrue(len(result), 7)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# class EvAdventureTurnbasedCombatActionTest(EvAdventureMixin, BaseEvenniaTest):
|
|
||||||
# """
|
|
||||||
# Test actions in turn_based combat.
|
|
||||||
# """
|
|
||||||
#
|
|
||||||
# @patch(
|
|
||||||
# "evennia.contrib.tutorials.evadventure.combat_turnbased"
|
|
||||||
# ".EvAdventureCombatHandler.interval",
|
|
||||||
# new=-1,
|
|
||||||
# )
|
|
||||||
# @patch(
|
|
||||||
# "evennia.contrib.tutorials.evadventure.combat_turnbased.delay",
|
|
||||||
# new=MagicMock(return_value=None),
|
|
||||||
# )
|
|
||||||
# def setUp(self):
|
|
||||||
# super().setUp()
|
|
||||||
# self.location.allow_combat = True
|
|
||||||
# self.location.allow_death = True
|
|
||||||
# self.combatant = self.character
|
|
||||||
# self.combatant2 = create.create_object(EvAdventureCharacter, key="testcharacter2")
|
|
||||||
# self.target = create.create_object(
|
|
||||||
# EvAdventureMob, key="testmonster", attributes=(("is_idle", True),)
|
|
||||||
# )
|
|
||||||
# self.target.hp = 4
|
|
||||||
#
|
|
||||||
# # this already starts turn 1
|
|
||||||
# self.combathandler = combat_turnbased.join_combat(self.combatant, self.target)
|
|
||||||
#
|
|
||||||
# def _run_action(self, action, *args, **kwargs):
|
|
||||||
# self.combathandler.register_action(self.combatant, action.key, *args, **kwargs)
|
|
||||||
# self.combathandler._end_turn()
|
|
||||||
#
|
|
||||||
# def test_do_nothing(self):
|
|
||||||
# self.combathandler.msg = MagicMock()
|
|
||||||
# self._run_action(combat_turnbased.CombatActionDoNothing, None)
|
|
||||||
# self.combathandler.msg.assert_called()
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_attack__miss(self, mock_randint):
|
|
||||||
# mock_randint.return_value = 8 # target has default armor 11, so 8+1 str will miss
|
|
||||||
# self._run_action(combat_turnbased.CombatActionAttack, self.target)
|
|
||||||
# self.assertEqual(self.target.hp, 4)
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_attack__success__still_alive(self, mock_randint):
|
|
||||||
# mock_randint.return_value = 11 # 11 + 1 str will hit beat armor 11
|
|
||||||
# # make sure target survives
|
|
||||||
# self.target.hp = 20
|
|
||||||
# self._run_action(combat_turnbased.CombatActionAttack, self.target)
|
|
||||||
# self.assertEqual(self.target.hp, 9)
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_attack__success__kill(self, mock_randint):
|
|
||||||
# mock_randint.return_value = 11 # 11 + 1 str will hit beat armor 11
|
|
||||||
# self._run_action(combat_turnbased.CombatActionAttack, self.target)
|
|
||||||
# self.assertEqual(self.target.hp, -7)
|
|
||||||
# # after this the combat is over
|
|
||||||
# self.assertIsNone(self.combathandler.pk)
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_stunt_fail(self, mock_randint):
|
|
||||||
# mock_randint.return_value = 8 # fails 8+1 dex vs DEX 11 defence
|
|
||||||
# self._run_action(combat_turnbased.CombatActionStunt, self.target)
|
|
||||||
# self.assertEqual(self.combathandler.advantage_matrix[self.combatant], {})
|
|
||||||
# self.assertEqual(self.combathandler.disadvantage_matrix[self.combatant], {})
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_stunt_advantage__success(self, mock_randint):
|
|
||||||
# mock_randint.return_value = 11 # 11+1 dex vs DEX 11 defence is success
|
|
||||||
# self._run_action(combat_turnbased.CombatActionStunt, self.target)
|
|
||||||
# self.assertEqual(
|
|
||||||
# bool(self.combathandler.advantage_matrix[self.combatant][self.target]), True
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_stunt_disadvantage__success(self, mock_randint):
|
|
||||||
# mock_randint.return_value = 11 # 11+1 dex vs DEX 11 defence is success
|
|
||||||
# action = combat_turnbased.CombatActionStunt
|
|
||||||
# action.give_advantage = False
|
|
||||||
# self._run_action(
|
|
||||||
# action,
|
|
||||||
# self.target,
|
|
||||||
# )
|
|
||||||
# self.assertEqual(
|
|
||||||
# bool(self.combathandler.disadvantage_matrix[self.target][self.combatant]), True
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# def test_use_item(self):
|
|
||||||
# """
|
|
||||||
# Use up a potion during combat.
|
|
||||||
#
|
|
||||||
# """
|
|
||||||
# item = create.create_object(
|
|
||||||
# EvAdventureConsumable, key="Healing potion", attributes=[("uses", 2)]
|
|
||||||
# )
|
|
||||||
# self.assertEqual(item.uses, 2)
|
|
||||||
# self._run_action(combat_turnbased.CombatActionUseItem, item, self.combatant)
|
|
||||||
# self.assertEqual(item.uses, 1)
|
|
||||||
# self._run_action(combat_turnbased.CombatActionUseItem, item, self.combatant)
|
|
||||||
# self.assertEqual(item.pk, None) # deleted, it was used up
|
|
||||||
#
|
|
||||||
# def test_swap_wielded_weapon_or_spell(self):
|
|
||||||
# """
|
|
||||||
# First draw a weapon (from empty fists), then swap that out to another weapon, then
|
|
||||||
# swap to a spell rune.
|
|
||||||
#
|
|
||||||
# """
|
|
||||||
# sword = create.create_object(EvAdventureWeapon, key="sword")
|
|
||||||
# zweihander = create.create_object(
|
|
||||||
# EvAdventureWeapon,
|
|
||||||
# key="zweihander",
|
|
||||||
# attributes=(("inventory_use_slot", WieldLocation.TWO_HANDS),),
|
|
||||||
# )
|
|
||||||
# runestone = create.create_object(EvAdventureRunestone, key="ice rune")
|
|
||||||
#
|
|
||||||
# # check hands are empty
|
|
||||||
# self.assertEqual(self.combatant.weapon.key, "Empty Fists")
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.WEAPON_HAND], None)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.TWO_HANDS], None)
|
|
||||||
#
|
|
||||||
# # swap to sword
|
|
||||||
# self._run_action(combat_turnbased.CombatActionSwapWieldedWeaponOrSpell, None, sword)
|
|
||||||
# self.assertEqual(self.combatant.weapon, sword)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.WEAPON_HAND], sword)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.TWO_HANDS], None)
|
|
||||||
#
|
|
||||||
# # swap to zweihander (two-handed sword)
|
|
||||||
# self._run_action(combat_turnbased.CombatActionSwapWieldedWeaponOrSpell, None, zweihander)
|
|
||||||
# self.assertEqual(self.combatant.weapon, zweihander)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.WEAPON_HAND], None)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.TWO_HANDS], zweihander)
|
|
||||||
#
|
|
||||||
# # swap to runestone (also using two hands)
|
|
||||||
# self._run_action(combat_turnbased.CombatActionSwapWieldedWeaponOrSpell, None, runestone)
|
|
||||||
# self.assertEqual(self.combatant.weapon, runestone)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.WEAPON_HAND], None)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.TWO_HANDS], runestone)
|
|
||||||
#
|
|
||||||
# # swap back to normal one-handed sword
|
|
||||||
# self._run_action(combat_turnbased.CombatActionSwapWieldedWeaponOrSpell, None, sword)
|
|
||||||
# self.assertEqual(self.combatant.weapon, sword)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.WEAPON_HAND], sword)
|
|
||||||
# self.assertEqual(self.combatant.equipment.slots[WieldLocation.TWO_HANDS], None)
|
|
||||||
#
|
|
||||||
# def test_flee__success(self):
|
|
||||||
# """
|
|
||||||
# Test fleeing twice, leading to leaving combat.
|
|
||||||
#
|
|
||||||
# """
|
|
||||||
# # first flee records the fleeing state
|
|
||||||
# self._run_action(combat_turnbased.CombatActionFlee, None)
|
|
||||||
# self.assertTrue(self.combatant in self.combathandler.fleeing_combatants)
|
|
||||||
#
|
|
||||||
# # second flee should remove combatant
|
|
||||||
# self._run_action(combat_turnbased.CombatActionFlee, None)
|
|
||||||
# self.assertIsNone(self.combathandler.pk)
|
|
||||||
#
|
|
||||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
|
||||||
# def test_flee__blocked(self, mock_randint):
|
|
||||||
# """ """
|
|
||||||
# mock_randint.return_value = 11 # means block will succeed
|
|
||||||
#
|
|
||||||
# self._run_action(combat_turnbased.CombatActionFlee, None)
|
|
||||||
# self.assertTrue(self.combatant in self.combathandler.fleeing_combatants)
|
|
||||||
#
|
|
||||||
# # other combatant blocks in the same turn
|
|
||||||
# self.combathandler.register_action(
|
|
||||||
# self.combatant, combat_turnbased.CombatActionFlee.key, None
|
|
||||||
# )
|
|
||||||
# self.combathandler.register_action(
|
|
||||||
# self.target, combat_turnbased.CombatActionBlock.key, self.combatant
|
|
||||||
# )
|
|
||||||
# self.combathandler._end_turn()
|
|
||||||
# # the fleeing combatant should remain now
|
|
||||||
# self.assertTrue(self.combatant not in self.combathandler.fleeing_combatants)
|
|
||||||
# self.assertTrue(self.combatant in self.combathandler.combatants)
|
|
||||||
|
|
|
||||||
|
|
@ -1489,4 +1489,5 @@ ACTOR_STANCE_CALLABLES = {
|
||||||
"conj": funcparser_callable_conjugate,
|
"conj": funcparser_callable_conjugate,
|
||||||
"pron": funcparser_callable_pronoun,
|
"pron": funcparser_callable_pronoun,
|
||||||
"Pron": funcparser_callable_pronoun_capitalize,
|
"Pron": funcparser_callable_pronoun_capitalize,
|
||||||
|
**FUNCPARSER_CALLABLES,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue