More combat tests
This commit is contained in:
parent
b0d6af9cc3
commit
6a7f59eaab
4 changed files with 343 additions and 115 deletions
|
|
@ -196,7 +196,7 @@ class CombatAction:
|
|||
the combatant doing the action and other combatants, respectively.
|
||||
|
||||
"""
|
||||
self.combathandler.msg(self, message, combatant=self.combatant, broadcast=broadcast)
|
||||
self.combathandler.msg(message, combatant=self.combatant, broadcast=broadcast)
|
||||
|
||||
def can_use(self):
|
||||
"""
|
||||
|
|
@ -250,44 +250,9 @@ class CombatActionAttack(CombatAction):
|
|||
weapon = attacker.weapon
|
||||
target = self.target
|
||||
|
||||
is_hit, quality, txt = rules.dice.opposed_saving_throw(
|
||||
attacker,
|
||||
target,
|
||||
attack_type=weapon.attack_type,
|
||||
defense_type=attacker.weapon.defense_type,
|
||||
advantage=self.has_advantage(attacker, target),
|
||||
disadvantage=self.has_disadvantage(attacker, target),
|
||||
)
|
||||
self.msg(f"$You() $conj(attack) $You({target.key}) with {weapon.key}: {txt}")
|
||||
if is_hit:
|
||||
# enemy hit, calculate damage
|
||||
weapon_dmg_roll = attacker.weapon.damage_roll
|
||||
|
||||
dmg = rules.dice.roll(weapon_dmg_roll)
|
||||
|
||||
if quality is Ability.CRITICAL_SUCCESS:
|
||||
dmg += rules.dice.roll(weapon_dmg_roll)
|
||||
message = (
|
||||
f" $You() |ycritically|n $conj(hit) $You({target.key}) for |r{dmg}|n damage!"
|
||||
)
|
||||
else:
|
||||
message = f" $You() $conj(hit) $You({target.key}) for |r{dmg}|n damage!"
|
||||
self.msg(message)
|
||||
|
||||
# call hook
|
||||
target.at_damage(dmg, attacker=attacker)
|
||||
|
||||
# note that we mustn't remove anyone from combat yet, because this is
|
||||
# happening simultaneously. So checking of the final hp
|
||||
# and rolling of death etc happens in the combathandler at the end of the turn.
|
||||
|
||||
else:
|
||||
# a miss
|
||||
message = f" $You() $conj(miss) $You({target.key})."
|
||||
if quality is Ability.CRITICAL_FAILURE:
|
||||
attacker.weapon.quality -= 1
|
||||
message += ".. it's a |rcritical miss!|n, damaging the weapon."
|
||||
self.msg(message)
|
||||
if weapon.at_pre_use(attacker, target):
|
||||
weapon.use(attacker, target, advantage=self.has_advantage(attacker, target))
|
||||
weapon.at_post_use(attacker, target)
|
||||
|
||||
|
||||
class CombatActionStunt(CombatAction):
|
||||
|
|
@ -317,6 +282,7 @@ class CombatActionStunt(CombatAction):
|
|||
recipient = self.recipient # the one to receive the effect of the stunt
|
||||
target = self.target # the affected by the stunt (can be the same as recipient/combatant)
|
||||
is_success = False
|
||||
txt = ""
|
||||
|
||||
if target == self.combatant:
|
||||
# can always grant dis/advantage against yourself
|
||||
|
|
@ -369,7 +335,7 @@ class CombatActionUseItem(CombatAction):
|
|||
action_dict = {
|
||||
"key": "use",
|
||||
"item": Object
|
||||
"target": Character/NPC/Object
|
||||
"target": Character/NPC/Object/None
|
||||
}
|
||||
|
||||
Note:
|
||||
|
|
@ -383,22 +349,14 @@ class CombatActionUseItem(CombatAction):
|
|||
user = self.combatant
|
||||
target = self.target
|
||||
|
||||
if user == target:
|
||||
# always manage to use the item on yourself
|
||||
is_success = True
|
||||
else:
|
||||
if item.has_obj_type(ObjType.WEAPON):
|
||||
# this is something that harms the target. We need to roll defense
|
||||
is_success, _, txt = rules.dice.opposed_saving_throw(
|
||||
user,
|
||||
target,
|
||||
attack_type=item.attack_type,
|
||||
defense_type=item.defense_type,
|
||||
advantage=self.has_advantage(user, target),
|
||||
disadvantage=self.has_disadvantage(user, target),
|
||||
)
|
||||
|
||||
item.at_use(self.combatant, self.target)
|
||||
if item.at_pre_use(user, target):
|
||||
item.use(
|
||||
user,
|
||||
target,
|
||||
advantage=self.has_advantage(user, target),
|
||||
disadvantage=self.has_disadvantage(user, target),
|
||||
)
|
||||
item.at_post_use(user, target)
|
||||
|
||||
|
||||
class CombatActionWield(CombatAction):
|
||||
|
|
@ -514,13 +472,13 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
|
||||
# who is involved in combat, and their action queue,
|
||||
# as {combatant: [actiondict, actiondict,...]}
|
||||
combatants = AttributeProperty(defaultdict(deque))
|
||||
combatants = AttributeProperty(dict)
|
||||
|
||||
advantage_matrix = AttributeProperty(defaultdict(dict))
|
||||
disadvantage_matrix = AttributeProperty(defaultdict(dict))
|
||||
|
||||
fleeing_combatants = AttributeProperty(dict)
|
||||
defeated_combatants = AttributeProperty(dict)
|
||||
defeated_combatants = AttributeProperty(list)
|
||||
|
||||
def msg(self, message, combatant=None, broadcast=True):
|
||||
"""
|
||||
|
|
@ -568,7 +526,7 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
"""
|
||||
for combatant in combatants:
|
||||
if combatant not in self.combatants:
|
||||
self.combatants[combatant] = deque((), self.max_action_queue_size)
|
||||
self.combatants[combatant] = deque((), maxlen=self.max_action_queue_size)
|
||||
return True
|
||||
|
||||
def remove_combatant(self, combatant):
|
||||
|
|
@ -693,7 +651,8 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
# PCs roll on the death table here, NPCs die. Even if PCs survive, they
|
||||
# are still out of the fight.
|
||||
combatant.at_defeat()
|
||||
self.defeated_combatants.append(self.combatant.pop(combatant))
|
||||
self.combatants.pop(combatant)
|
||||
self.defeated_combatants.append(combatant)
|
||||
self.msg("|r$You() $conj(fall) to the ground, defeated.|n", combatant=combatant)
|
||||
|
||||
# check if anyone managed to flee
|
||||
|
|
@ -717,12 +676,8 @@ class EvAdventureCombatHandler(DefaultScript):
|
|||
if not enemies:
|
||||
# if one way or another, there are no more enemies to fight
|
||||
still_standing = list_to_string(f"$You({comb.key})" for comb in allies)
|
||||
knocked_out = list_to_string(
|
||||
f"$You({comb.key})" for comb in self.defeated_combatants if comb.hp > 0
|
||||
)
|
||||
killed = list_to_string(
|
||||
comb for comb in self.defeated_combatants if comb not in knocked_out
|
||||
)
|
||||
knocked_out = list_to_string(comb for comb in self.defeated_combatants if comb.hp > 0)
|
||||
killed = list_to_string(comb for comb in self.defeated_combatants if comb.hp <= 0)
|
||||
|
||||
if still_standing:
|
||||
txt = [f"The combat is over. {still_standing} are still standing."]
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from evennia import AttributeProperty
|
|||
from evennia.objects.objects import DefaultObject
|
||||
from evennia.utils.utils import make_iter
|
||||
|
||||
from . import rules
|
||||
from .enums import Ability, ObjType, WieldLocation
|
||||
from .utils import get_obj_stats
|
||||
|
||||
|
|
@ -70,6 +71,25 @@ class EvAdventureObject(DefaultObject):
|
|||
"""
|
||||
return "No help for this item."
|
||||
|
||||
def at_pre_use(self, *args, **kwargs):
|
||||
"""
|
||||
Called before use. If returning False, usage should be aborted.
|
||||
"""
|
||||
return True
|
||||
|
||||
def use(self, *args, **kwargs):
|
||||
"""
|
||||
Use this object, whatever that may mean.
|
||||
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def at_post_use(self, *args, **kwargs):
|
||||
"""
|
||||
Called after use happened.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class EvAdventureObjectFiller(EvAdventureObject):
|
||||
"""
|
||||
|
|
@ -119,17 +139,12 @@ class EvAdventureConsumable(EvAdventureObject):
|
|||
size = AttributeProperty(0.25)
|
||||
uses = AttributeProperty(1)
|
||||
|
||||
def at_use(self, user, *args, **kwargs):
|
||||
def use(self, user, *args, **kwargs):
|
||||
"""
|
||||
Consume a 'use' of this item. Once it reaches 0 uses, it should normally
|
||||
not be usable anymore and probably be deleted.
|
||||
|
||||
Args:
|
||||
user (Object): The one using the item.
|
||||
*args, **kwargs: Extra arguments depending on the usage and item.
|
||||
Use the consumable.
|
||||
|
||||
"""
|
||||
pass
|
||||
raise NotImplementedError
|
||||
|
||||
def at_post_use(self, user, *args, **kwargs):
|
||||
"""
|
||||
|
|
@ -162,6 +177,43 @@ class EvAdventureWeapon(EvAdventureObject):
|
|||
defense_type = AttributeProperty(Ability.ARMOR)
|
||||
damage_roll = AttributeProperty("1d6")
|
||||
|
||||
def use(self, attacker, target, *args, advantage=False, disadvantage=False, **kwargs):
|
||||
"""When a weapon is used, it attacks an opponent"""
|
||||
|
||||
is_hit, quality, txt = rules.dice.opposed_saving_throw(
|
||||
attacker,
|
||||
target,
|
||||
attack_type=self.attack_type,
|
||||
defense_type=self.defense_type,
|
||||
advantage=advantage,
|
||||
disadvantage=disadvantage,
|
||||
)
|
||||
self.msg(f"$You() $conj(attack) $You({target.key}) with {self.key}: {txt}")
|
||||
if is_hit:
|
||||
# enemy hit, calculate damage
|
||||
dmg = rules.dice.roll(self.damage_roll)
|
||||
|
||||
if quality is Ability.CRITICAL_SUCCESS:
|
||||
# doble damage roll for critical success
|
||||
dmg += rules.dice.roll(self.damage_roll)
|
||||
message = (
|
||||
f" $You() |ycritically|n $conj(hit) $You({target.key}) for |r{dmg}|n damage!"
|
||||
)
|
||||
else:
|
||||
message = f" $You() $conj(hit) $You({target.key}) for |r{dmg}|n damage!"
|
||||
self.msg(message)
|
||||
|
||||
# call hook
|
||||
target.at_damage(dmg, attacker=attacker)
|
||||
|
||||
else:
|
||||
# a miss
|
||||
message = f" $You() $conj(miss) $You({target.key})."
|
||||
if quality is Ability.CRITICAL_FAILURE:
|
||||
self.quality -= 1
|
||||
message += ".. it's a |rcritical miss!|n, damaging the weapon."
|
||||
self.msg(message)
|
||||
|
||||
|
||||
class EvAdventureThrowable(EvAdventureWeapon, EvAdventureConsumable):
|
||||
"""
|
||||
|
|
@ -178,7 +230,7 @@ class EvAdventureThrowable(EvAdventureWeapon, EvAdventureConsumable):
|
|||
damage_roll = AttributeProperty("1d6")
|
||||
|
||||
|
||||
class WeaponEmptyHand:
|
||||
class WeaponEmptyHand(EvAdventureWeapon):
|
||||
"""
|
||||
This is a dummy-class loaded when you wield no weapons. We won't create any db-object for it.
|
||||
|
||||
|
|
@ -192,9 +244,6 @@ class WeaponEmptyHand:
|
|||
damage_roll = "1d4"
|
||||
quality = 100000 # let's assume fists are always available ...
|
||||
|
||||
def __repr__(self):
|
||||
return "<WeaponEmptyHand>"
|
||||
|
||||
|
||||
class EvAdventureRunestone(EvAdventureWeapon, EvAdventureConsumable):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ from evennia.utils.test_resources import BaseEvenniaTest
|
|||
|
||||
from .. import combat_turnbased as combat
|
||||
from ..characters import EvAdventureCharacter
|
||||
from ..enums import WieldLocation
|
||||
from ..enums import Ability, WieldLocation
|
||||
from ..npcs import EvAdventureMob
|
||||
from ..objects import EvAdventureConsumable, EvAdventureRunestone, EvAdventureWeapon
|
||||
from ..rooms import EvAdventureRoom
|
||||
|
|
@ -53,10 +53,34 @@ class EvAdventureCombatHandlerTest(BaseEvenniaTest):
|
|||
attributes=(("is_idle", True),),
|
||||
)
|
||||
|
||||
# mock the msg so we can check what they were sent later
|
||||
self.combatant.msg = Mock()
|
||||
self.target.msg = Mock()
|
||||
|
||||
self.combathandler = combat.get_or_create_combathandler(self.combatant)
|
||||
# add target to combat
|
||||
self.combathandler.add_combatants(self.target)
|
||||
|
||||
def _get_action(self, action_dict={"key": "nothing"}):
|
||||
action_class = self.combathandler.action_classes[action_dict["key"]]
|
||||
return action_class(self.combathandler, self.combatant, action_dict)
|
||||
|
||||
def _run_actions(
|
||||
self, action_dict, action_dict2={"key": "nothing"}, combatant_msg=None, target_msg=None
|
||||
):
|
||||
"""
|
||||
Helper method to run an action and check so combatant saw the expected message.
|
||||
"""
|
||||
self.combathandler.queue_action(self.combatant, action_dict)
|
||||
self.combathandler.queue_action(self.target, action_dict2)
|
||||
self.combathandler.execute_full_turn()
|
||||
if combatant_msg is not None:
|
||||
# this works because we mock combatant.msg in SetUp
|
||||
self.combatant.msg.assert_called_with(combatant_msg)
|
||||
if target_msg is not None:
|
||||
# this works because we mock target.msg in SetUp
|
||||
self.combatant.msg.assert_called_with(target_msg)
|
||||
|
||||
def test_combatanthandler_setup(self):
|
||||
"""Testing all is set up correctly in the combathandler"""
|
||||
|
||||
|
|
@ -166,30 +190,233 @@ class EvAdventureCombatHandlerTest(BaseEvenniaTest):
|
|||
[call(self.combatant), call(self.target)], any_order=True
|
||||
)
|
||||
|
||||
def _get_action(self, action_dict, action_dict2={"key": "nothing"}):
|
||||
def test_combat_action(self):
|
||||
"""General tests of action functionality"""
|
||||
|
||||
self.combathandler.queue_action(self.combatant, action_dict)
|
||||
self.combathandler.queue_action(self.target, action_dict2)
|
||||
combatant = self.combatant
|
||||
target = self.target
|
||||
|
||||
action_cls1 = self.combathandler.action_classes[action_dict["key"]]
|
||||
action_cls2 = self.combathandler.action_classes[action_dict2["key"]]
|
||||
action = self._get_action({"key": "nothing"})
|
||||
|
||||
return action_cls1, action_cls2
|
||||
self.assertTrue(action.can_use())
|
||||
|
||||
action.give_advantage(combatant, target)
|
||||
action.give_disadvantage(combatant, target)
|
||||
|
||||
self.assertTrue(action.has_advantage(combatant, target))
|
||||
self.assertTrue(action.has_disadvantage(combatant, target))
|
||||
|
||||
action.lose_advantage(combatant, target)
|
||||
action.lose_disadvantage(combatant, target)
|
||||
|
||||
self.assertFalse(action.has_advantage(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}).")
|
||||
combatant.msg.assert_called_with(text=("You attack testmonster.", {}), from_obj=combatant)
|
||||
|
||||
def test_action__do_nothing(self):
|
||||
"""Do nothing"""
|
||||
|
||||
actiondict = {"key": "nothing"}
|
||||
|
||||
actioncls1, actioncls2 = self._get_action(actiondict, actiondict)
|
||||
|
||||
self.assertEqual(actioncls1, actioncls2)
|
||||
|
||||
self.combathandler.execute_full_turn()
|
||||
|
||||
self._run_actions(actiondict, actiondict)
|
||||
self.assertEqual(self.combathandler.turn, 1)
|
||||
|
||||
# @patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
||||
self.combatant.msg.assert_not_called()
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
||||
def test_attack__miss(self, mock_randint):
|
||||
|
||||
actiondict = {"key": "attack", "target": self.target}
|
||||
|
||||
mock_randint.return_value = 8 # target has default armor 11, so 8+1 str will miss
|
||||
self._run_actions(actiondict)
|
||||
self.assertEqual(self.target.hp, 4)
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
||||
def test_attack__success__still_alive(self, mock_randint):
|
||||
actiondict = {"key": "attack", "target": self.target}
|
||||
|
||||
mock_randint.return_value = 11 # 11 + 1 str will hit beat armor 11
|
||||
# make sure target survives
|
||||
self.target.hp = 20
|
||||
self._run_actions(actiondict)
|
||||
self.assertEqual(self.target.hp, 9)
|
||||
|
||||
@patch("evennia.contrib.tutorials.evadventure.combat_turnbased.rules.randint")
|
||||
def test_attack__success__kill(self, mock_randint):
|
||||
actiondict = {"key": "attack", "target": self.target}
|
||||
|
||||
mock_randint.return_value = 11 # 11 + 1 str will hit beat armor 11
|
||||
self._run_actions(actiondict)
|
||||
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):
|
||||
action_dict = {
|
||||
"key": "stunt",
|
||||
"recipient": self.combatant,
|
||||
"target": self.target,
|
||||
"advantage": True,
|
||||
"stunt_type": Ability.STR,
|
||||
"defense_type": Ability.DEX,
|
||||
}
|
||||
mock_randint.return_value = 8 # fails 8+1 dex vs DEX 11 defence
|
||||
self._run_actions(action_dict)
|
||||
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):
|
||||
action_dict = {
|
||||
"key": "stunt",
|
||||
"recipient": self.combatant,
|
||||
"target": self.target,
|
||||
"advantage": True,
|
||||
"stunt_type": Ability.STR,
|
||||
"defense_type": Ability.DEX,
|
||||
}
|
||||
mock_randint.return_value = 11 # 11+1 dex vs DEX 11 defence is success
|
||||
self._run_actions(action_dict)
|
||||
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):
|
||||
action_dict = {
|
||||
"key": "stunt",
|
||||
"recipient": self.target,
|
||||
"target": self.combatant,
|
||||
"advantage": False,
|
||||
"stunt_type": Ability.STR,
|
||||
"defense_type": Ability.DEX,
|
||||
}
|
||||
mock_randint.return_value = 11 # 11+1 dex vs DEX 11 defence is success
|
||||
self._run_actions(action_dict)
|
||||
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)]
|
||||
)
|
||||
|
||||
item.use = Mock()
|
||||
|
||||
action_dict = {
|
||||
"key": "use",
|
||||
"item": item,
|
||||
"target": self.target,
|
||||
}
|
||||
|
||||
self.assertEqual(item.uses, 2)
|
||||
self._run_actions(action_dict)
|
||||
self.assertEqual(item.uses, 1)
|
||||
self._run_actions(action_dict)
|
||||
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
|
||||
|
||||
actiondict = {"key": "wield", "item": sword}
|
||||
|
||||
self._run_actions(actiondict)
|
||||
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)
|
||||
actiondict["item"] = zweihander
|
||||
|
||||
from evennia import set_trace
|
||||
|
||||
set_trace()
|
||||
self._run_actions(actiondict)
|
||||
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)
|
||||
actiondict["item"] = runestone
|
||||
|
||||
self._run_actions(actiondict)
|
||||
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
|
||||
actiondict["item"] = sword
|
||||
|
||||
self._run_actions(actiondict)
|
||||
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)
|
||||
|
||||
|
||||
# class EvAdventureTurnbasedCombatHandlerTest(EvAdventureMixin, BaseEvenniaTest):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue