Made turnbattle tests pass after refactor

This commit is contained in:
Griatch 2022-02-01 21:17:32 +01:00
parent 80f5f8f3a9
commit 8fa89c7f01
4 changed files with 167 additions and 96 deletions

View file

@ -343,7 +343,7 @@ class ItemCombatRules(tb_basic.BasicCombatRules):
condition_turnchar = character.db.conditions[key][1]
# If the duration is 'True', then the condition doesn't tick down - it lasts
# indefinitely.
if not condition_duration:
if condition_duration is not True:
# Count down if the given turn character matches the condition's turn character.
if condition_turnchar == turnchar:
character.db.conditions[key][0] -= 1
@ -456,7 +456,7 @@ class ItemCombatRules(tb_basic.BasicCombatRules):
for condition in conditions:
self.add_condition(target, user, condition[0], condition[1])
def itemfunc_cure_condition(item, user, target, **kwargs):
def itemfunc_cure_condition(self, item, user, target, **kwargs):
"""
Item function that'll remove given conditions from a target.
@ -873,7 +873,7 @@ class CmdFight(tb_basic.CmdFight):
combat_handler_class = TBItemsTurnHandler
class CmdAttack(tb_basic.CmdFight):
class CmdAttack(tb_basic.CmdAttack):
"""
Attacks another character.
@ -906,7 +906,7 @@ class CmdPass(tb_basic.CmdPass):
rules = COMBAT_RULES
class CmdDisengage(Command):
class CmdDisengage(tb_basic.CmdDisengage):
"""
Passes your turn and attempts to end combat.
@ -925,7 +925,7 @@ class CmdDisengage(Command):
rules = COMBAT_RULES
class CmdRest(Command):
class CmdRest(tb_basic.CmdRest):
"""
Recovers damage.

View file

@ -403,7 +403,7 @@ SCRIPTS START HERE
"""
class TBMagicTurnHandler(DefaultScript):
class TBMagicTurnHandler(tb_basic.TBBasicTurnHandler):
"""
This is the script that handles the progression of combat through turns.
On creation (when a fight is started) it adds all combat-ready characters
@ -777,6 +777,8 @@ class CmdRest(Command):
key = "rest"
help_category = "combat"
rules = COMBAT_RULES
def func(self):
"This performs the actual command."

View file

@ -154,6 +154,30 @@ class RangedCombatRules(tb_basic.BasicCombatRules):
attack_value -= 15
return attack_value
def get_defense(self, attacker, defender, attack_type='melee'):
"""
Returns a value for defense, which an attack roll must equal or exceed in order
for an attack to hit.
Args:
attacker (obj): Character doing the attacking
defender (obj): Character being attacked
attack_type (str): Type of attack ('melee' or 'ranged')
Returns:
defense_value (int): Defense value, compared against an attack roll
to determine whether an attack hits or misses.
Notes:
By default, returns 50, not taking any properties of the defender or
attacker into account.
As above, this can be expanded upon based on character stats and equipment.
"""
# For this example, just return 50, for about a 50/50 chance of hit.
defense_value = 50
return defense_value
def get_range(self, obj1, obj2):
"""
Gets the combat range between two objects.
@ -192,7 +216,7 @@ class RangedCombatRules(tb_basic.BasicCombatRules):
target.db.combat_range[mover] = 2
mover.db.combat_range[target] = 2
def _distance_dec(self, mover, target):
def distance_dec(self, mover, target):
"""
Helper function that decreases distance in range field between mover and target.
@ -233,12 +257,12 @@ class RangedCombatRules(tb_basic.BasicCombatRules):
if thing != mover and thing != target:
# Move closer to each object closer to the target than you.
if self.get_range(mover, thing) > self.get_range(target, thing):
self._distance_dec(mover, thing)
self.distance_dec(mover, thing)
# Move further from each object that's further from you than from the target.
if self.get_range(mover, thing) < self.get_range(target, thing):
self._distance_inc(mover, thing)
self.distance_inc(mover, thing)
# Lastly, move closer to your target.
self._distance_dec(mover, target)
self.distance_dec(mover, target)
def withdraw(self, mover, target):
"""
@ -262,15 +286,54 @@ class RangedCombatRules(tb_basic.BasicCombatRules):
# you than you are to the target.
if (self.get_range(mover, thing) >= self.get_range(target, thing)
and self.get_range(mover, thing) < self.get_range(mover, target)):
self._distance_inc(mover, thing)
self.distance_inc(mover, thing)
# Move away from anything your target is engaged with
if self.get_range(target, thing) == 0:
self._distance_inc(mover, thing)
self.distance_inc(mover, thing)
# Move away from anything you're engaged with.
if self.get_range(mover, thing) == 0:
self._distance_inc(mover, thing)
self.distance_inc(mover, thing)
# Then, move away from your target.
self._distance_inc(mover, target)
self.distance_inc(mover, target)
def resolve_attack(self, attacker, defender, attack_value=None, defense_value=None,
attack_type='melee'):
"""
Resolves an attack and outputs the result.
Args:
attacker (obj): Character doing the attacking
defender (obj): Character being attacked
attack_type (str): Type of attack (melee or ranged)
Notes:
Even though the attack and defense values are calculated
extremely simply, they are separated out into their own functions
so that they are easier to expand upon.
"""
# Get an attack roll from the attacker.
if not attack_value:
attack_value = self.get_attack(attacker, defender, attack_type)
# Get a defense value from the defender.
if not defense_value:
defense_value = self.get_defense(attacker, defender, attack_type)
# If the attack value is lower than the defense value, miss. Otherwise, hit.
if attack_value < defense_value:
attacker.location.msg_contents(
"%s's %s attack misses %s!" % (attacker, attack_type, defender)
)
else:
damage_value = self.get_damage(attacker, defender) # Calculate damage value.
# Announce damage dealt and apply damage.
attacker.location.msg_contents(
"%s hits %s with a %s attack for %i damage!"
% (attacker, defender, attack_type, damage_value)
)
self.apply_damage(defender, damage_value)
# If defender HP is reduced to 0 or less, call at_defeat.
if defender.db.hp <= 0:
self.at_defeat(defender)
def combat_status_message(self, fighter):
"""
@ -320,7 +383,7 @@ SCRIPTS START HERE
"""
class TBRangeTurnHandler(DefaultScript):
class TBRangeTurnHandler(tb_basic.TBBasicTurnHandler):
"""
This is the script that handles the progression of combat through turns.
On creation (when a fight is started) it adds all combat-ready characters
@ -400,7 +463,8 @@ class TBRangeTurnHandler(DefaultScript):
characters to both move and attack in the same turn (or, alternately,
move twice or attack twice).
"""
super().start_turn()
super().start_turn(character)
character.db.combat_actionsleft = ACTIONS_PER_TURN
def join_fight(self, character):
"""

View file

@ -108,53 +108,54 @@ class TestTurnBattleBasicFunc(BaseEvenniaTest):
def tearDown(self):
super().tearDown()
self.turnhandler.stop()
self.testroom.delete()
self.attacker.delete()
self.defender.delete()
self.joiner.delete()
self.testroom.delete()
# Test combat functions
def test_tbbasicfunc(self):
# Initiative roll
initiative = tb_basic.roll_init(self.attacker)
initiative = tb_basic.COMBAT_RULES.roll_init(self.attacker)
self.assertTrue(initiative >= 0 and initiative <= 1000)
# Attack roll
attack_roll = tb_basic.get_attack(self.attacker, self.defender)
attack_roll = tb_basic.COMBAT_RULES.get_attack(self.attacker, self.defender)
self.assertTrue(attack_roll >= 0 and attack_roll <= 100)
# Defense roll
defense_roll = tb_basic.get_defense(self.attacker, self.defender)
defense_roll = tb_basic.COMBAT_RULES.get_defense(self.attacker, self.defender)
self.assertTrue(defense_roll == 50)
# Damage roll
damage_roll = tb_basic.get_damage(self.attacker, self.defender)
damage_roll = tb_basic.COMBAT_RULES.get_damage(self.attacker, self.defender)
self.assertTrue(damage_roll >= 15 and damage_roll <= 25)
# Apply damage
self.defender.db.hp = 10
tb_basic.apply_damage(self.defender, 3)
tb_basic.COMBAT_RULES.apply_damage(self.defender, 3)
self.assertTrue(self.defender.db.hp == 7)
# Resolve attack
self.defender.db.hp = 40
tb_basic.resolve_attack(self.attacker, self.defender, attack_value=20, defense_value=10)
tb_basic.COMBAT_RULES.resolve_attack(self.attacker, self.defender,
attack_value=20, defense_value=10)
self.assertTrue(self.defender.db.hp < 40)
# Combat cleanup
self.attacker.db.Combat_attribute = True
tb_basic.combat_cleanup(self.attacker)
tb_basic.COMBAT_RULES.combat_cleanup(self.attacker)
self.assertFalse(self.attacker.db.combat_attribute)
# Is in combat
self.assertFalse(tb_basic.is_in_combat(self.attacker))
self.assertFalse(tb_basic.COMBAT_RULES.is_in_combat(self.attacker))
# Set up turn handler script for further tests
self.attacker.location.scripts.add(tb_basic.TBBasicTurnHandler)
self.turnhandler = self.attacker.db.combat_TurnHandler
self.assertTrue(self.attacker.db.combat_TurnHandler)
self.turnhandler = self.attacker.db.combat_turnHandler
self.assertTrue(self.attacker.db.combat_turnHandler)
# Set the turn handler's interval very high to keep it from repeating during tests.
self.turnhandler.interval = 10000
# Force turn order
self.turnhandler.db.fighters = [self.attacker, self.defender]
self.turnhandler.db.turn = 0
# Test is turn
self.assertTrue(tb_basic.is_turn(self.attacker))
self.assertTrue(tb_basic.COMBAT_RULES.is_turn(self.attacker))
# Spend actions
self.attacker.db.Combat_ActionsLeft = 1
tb_basic.spend_action(self.attacker, 1, action_name="Test")
tb_basic.COMBAT_RULES.spend_action(self.attacker, 1, action_name="Test")
self.assertTrue(self.attacker.db.Combat_ActionsLeft == 0)
self.assertTrue(self.attacker.db.Combat_LastAction == "Test")
# Initialize for combat
@ -201,53 +202,53 @@ class TestTurnBattleEquipFunc(BaseEvenniaTest):
def tearDown(self):
super().tearDown()
self.turnhandler.stop()
self.testroom.delete()
self.attacker.delete()
self.defender.delete()
self.joiner.delete()
self.testroom.delete()
# Test the combat functions in tb_equip too. They work mostly the same.
def test_tbequipfunc(self):
# Initiative roll
initiative = tb_equip.roll_init(self.attacker)
initiative = tb_equip.COMBAT_RULES.roll_init(self.attacker)
self.assertTrue(initiative >= 0 and initiative <= 1000)
# Attack roll
attack_roll = tb_equip.get_attack(self.attacker, self.defender)
attack_roll = tb_equip.COMBAT_RULES.get_attack(self.attacker, self.defender)
self.assertTrue(attack_roll >= -50 and attack_roll <= 150)
# Defense roll
defense_roll = tb_equip.get_defense(self.attacker, self.defender)
defense_roll = tb_equip.COMBAT_RULES.get_defense(self.attacker, self.defender)
self.assertTrue(defense_roll == 50)
# Damage roll
damage_roll = tb_equip.get_damage(self.attacker, self.defender)
damage_roll = tb_equip.COMBAT_RULES.get_damage(self.attacker, self.defender)
self.assertTrue(damage_roll >= 0 and damage_roll <= 50)
# Apply damage
self.defender.db.hp = 10
tb_equip.apply_damage(self.defender, 3)
tb_equip.COMBAT_RULES.apply_damage(self.defender, 3)
self.assertTrue(self.defender.db.hp == 7)
# Resolve attack
self.defender.db.hp = 40
tb_equip.resolve_attack(self.attacker, self.defender, attack_value=20, defense_value=10)
tb_equip.COMBAT_RULES.resolve_attack(self.attacker, self.defender, attack_value=20, defense_value=10)
self.assertTrue(self.defender.db.hp < 40)
# Combat cleanup
self.attacker.db.Combat_attribute = True
tb_equip.combat_cleanup(self.attacker)
tb_equip.COMBAT_RULES.combat_cleanup(self.attacker)
self.assertFalse(self.attacker.db.combat_attribute)
# Is in combat
self.assertFalse(tb_equip.is_in_combat(self.attacker))
self.assertFalse(tb_equip.COMBAT_RULES.is_in_combat(self.attacker))
# Set up turn handler script for further tests
self.attacker.location.scripts.add(tb_equip.TBEquipTurnHandler)
self.turnhandler = self.attacker.db.combat_TurnHandler
self.assertTrue(self.attacker.db.combat_TurnHandler)
self.turnhandler = self.attacker.db.combat_turnHandler
self.assertTrue(self.attacker.db.combat_turnHandler)
# Set the turn handler's interval very high to keep it from repeating during tests.
self.turnhandler.interval = 10000
# Force turn order
self.turnhandler.db.fighters = [self.attacker, self.defender]
self.turnhandler.db.turn = 0
# Test is turn
self.assertTrue(tb_equip.is_turn(self.attacker))
self.assertTrue(tb_equip.COMBAT_RULES.is_turn(self.attacker))
# Spend actions
self.attacker.db.Combat_ActionsLeft = 1
tb_equip.spend_action(self.attacker, 1, action_name="Test")
tb_equip.COMBAT_RULES.spend_action(self.attacker, 1, action_name="Test")
self.assertTrue(self.attacker.db.Combat_ActionsLeft == 0)
self.assertTrue(self.attacker.db.Combat_LastAction == "Test")
# Initialize for combat
@ -293,55 +294,57 @@ class TestTurnBattleRangeFunc(BaseEvenniaTest):
def tearDown(self):
super().tearDown()
self.turnhandler.stop()
self.testroom.delete()
self.attacker.delete()
self.defender.delete()
self.joiner.delete()
self.testroom.delete()
# Test combat functions in tb_range too.
def test_tbrangefunc(self):
# Initiative roll
initiative = tb_range.roll_init(self.attacker)
initiative = tb_range.COMBAT_RULES.roll_init(self.attacker)
self.assertTrue(initiative >= 0 and initiative <= 1000)
# Attack roll
attack_roll = tb_range.get_attack(self.attacker, self.defender, "test")
attack_roll = tb_range.COMBAT_RULES.get_attack(self.attacker, self.defender,
attack_type="test")
self.assertTrue(attack_roll >= 0 and attack_roll <= 100)
# Defense roll
defense_roll = tb_range.get_defense(self.attacker, self.defender, "test")
defense_roll = tb_range.COMBAT_RULES.get_defense(self.attacker, self.defender,
attack_type="test")
self.assertTrue(defense_roll == 50)
# Damage roll
damage_roll = tb_range.get_damage(self.attacker, self.defender)
damage_roll = tb_range.COMBAT_RULES.get_damage(self.attacker, self.defender)
self.assertTrue(damage_roll >= 15 and damage_roll <= 25)
# Apply damage
self.defender.db.hp = 10
tb_range.apply_damage(self.defender, 3)
tb_range.COMBAT_RULES.apply_damage(self.defender, 3)
self.assertTrue(self.defender.db.hp == 7)
# Resolve attack
self.defender.db.hp = 40
tb_range.resolve_attack(
self.attacker, self.defender, "test", attack_value=20, defense_value=10
tb_range.COMBAT_RULES.resolve_attack(
self.attacker, self.defender, attack_type="test", attack_value=20, defense_value=10
)
self.assertTrue(self.defender.db.hp < 40)
# Combat cleanup
self.attacker.db.Combat_attribute = True
tb_range.combat_cleanup(self.attacker)
tb_range.COMBAT_RULES.combat_cleanup(self.attacker)
self.assertFalse(self.attacker.db.combat_attribute)
# Is in combat
self.assertFalse(tb_range.is_in_combat(self.attacker))
self.assertFalse(tb_range.COMBAT_RULES.is_in_combat(self.attacker))
# Set up turn handler script for further tests
self.attacker.location.scripts.add(tb_range.TBRangeTurnHandler)
self.turnhandler = self.attacker.db.combat_TurnHandler
self.assertTrue(self.attacker.db.combat_TurnHandler)
self.turnhandler = self.attacker.db.combat_turnHandler
self.assertTrue(self.attacker.db.combat_turnHandler)
# Set the turn handler's interval very high to keep it from repeating during tests.
self.turnhandler.interval = 10000
# Force turn order
self.turnhandler.db.fighters = [self.attacker, self.defender]
self.turnhandler.db.turn = 0
# Test is turn
self.assertTrue(tb_range.is_turn(self.attacker))
self.assertTrue(tb_range.COMBAT_RULES.is_turn(self.attacker))
# Spend actions
self.attacker.db.Combat_ActionsLeft = 1
tb_range.spend_action(self.attacker, 1, action_name="Test")
tb_range.COMBAT_RULES.spend_action(self.attacker, 1, action_name="Test")
self.assertTrue(self.attacker.db.Combat_ActionsLeft == 0)
self.assertTrue(self.attacker.db.Combat_LastAction == "Test")
# Initialize for combat
@ -359,7 +362,7 @@ class TestTurnBattleRangeFunc(BaseEvenniaTest):
# Start turn
self.defender.db.Combat_ActionsLeft = 0
self.turnhandler.start_turn(self.defender)
self.assertTrue(self.defender.db.Combat_ActionsLeft == 2)
self.assertEqual(self.defender.db.Combat_ActionsLeft, 2)
# Next turn
self.turnhandler.db.fighters = [self.attacker, self.defender]
self.turnhandler.db.turn = 0
@ -378,13 +381,13 @@ class TestTurnBattleRangeFunc(BaseEvenniaTest):
self.assertTrue(self.turnhandler.db.turn == 1)
self.assertTrue(self.turnhandler.db.fighters == [self.joiner, self.attacker, self.defender])
# Now, test for approach/withdraw functions
self.assertTrue(tb_range.get_range(self.attacker, self.defender) == 1)
self.assertTrue(tb_range.COMBAT_RULES.get_range(self.attacker, self.defender) == 1)
# Approach
tb_range.approach(self.attacker, self.defender)
self.assertTrue(tb_range.get_range(self.attacker, self.defender) == 0)
tb_range.COMBAT_RULES.approach(self.attacker, self.defender)
self.assertTrue(tb_range.COMBAT_RULES.get_range(self.attacker, self.defender) == 0)
# Withdraw
tb_range.withdraw(self.attacker, self.defender)
self.assertTrue(tb_range.get_range(self.attacker, self.defender) == 1)
tb_range.COMBAT_RULES.withdraw(self.attacker, self.defender)
self.assertTrue(tb_range.COMBAT_RULES.get_range(self.attacker, self.defender) == 1)
class TestTurnBattleItemsFunc(BaseEvenniaTest):
@ -407,54 +410,55 @@ class TestTurnBattleItemsFunc(BaseEvenniaTest):
def tearDown(self):
super().tearDown()
self.turnhandler.stop()
self.testroom.delete()
self.attacker.delete()
self.defender.delete()
self.joiner.delete()
self.user.delete()
self.testroom.delete()
# Test functions in tb_items.
def test_tbitemsfunc(self):
# Initiative roll
initiative = tb_items.roll_init(self.attacker)
initiative = tb_items.COMBAT_RULES.roll_init(self.attacker)
self.assertTrue(initiative >= 0 and initiative <= 1000)
# Attack roll
attack_roll = tb_items.get_attack(self.attacker, self.defender)
attack_roll = tb_items.COMBAT_RULES.get_attack(self.attacker, self.defender)
self.assertTrue(attack_roll >= 0 and attack_roll <= 100)
# Defense roll
defense_roll = tb_items.get_defense(self.attacker, self.defender)
defense_roll = tb_items.COMBAT_RULES.get_defense(self.attacker, self.defender)
self.assertTrue(defense_roll == 50)
# Damage roll
damage_roll = tb_items.get_damage(self.attacker, self.defender)
damage_roll = tb_items.COMBAT_RULES.get_damage(self.attacker, self.defender)
self.assertTrue(damage_roll >= 15 and damage_roll <= 25)
# Apply damage
self.defender.db.hp = 10
tb_items.apply_damage(self.defender, 3)
tb_items.COMBAT_RULES.apply_damage(self.defender, 3)
self.assertTrue(self.defender.db.hp == 7)
# Resolve attack
self.defender.db.hp = 40
tb_items.resolve_attack(self.attacker, self.defender, attack_value=20, defense_value=10)
tb_items.COMBAT_RULES.resolve_attack(self.attacker, self.defender, attack_value=20,
defense_value=10)
self.assertTrue(self.defender.db.hp < 40)
# Combat cleanup
self.attacker.db.Combat_attribute = True
tb_items.combat_cleanup(self.attacker)
tb_items.COMBAT_RULES.combat_cleanup(self.attacker)
self.assertFalse(self.attacker.db.combat_attribute)
# Is in combat
self.assertFalse(tb_items.is_in_combat(self.attacker))
self.assertFalse(tb_items.COMBAT_RULES.is_in_combat(self.attacker))
# Set up turn handler script for further tests
self.attacker.location.scripts.add(tb_items.TBItemsTurnHandler)
self.turnhandler = self.attacker.db.combat_TurnHandler
self.assertTrue(self.attacker.db.combat_TurnHandler)
self.turnhandler = self.attacker.db.combat_turnHandler
self.assertTrue(self.attacker.db.combat_turnHandler)
# Set the turn handler's interval very high to keep it from repeating during tests.
self.turnhandler.interval = 10000
# Force turn order
self.turnhandler.db.fighters = [self.attacker, self.defender]
self.turnhandler.db.turn = 0
# Test is turn
self.assertTrue(tb_items.is_turn(self.attacker))
self.assertTrue(tb_items.COMBAT_RULES.is_turn(self.attacker))
# Spend actions
self.attacker.db.Combat_ActionsLeft = 1
tb_items.spend_action(self.attacker, 1, action_name="Test")
tb_items.COMBAT_RULES.spend_action(self.attacker, 1, action_name="Test")
self.assertTrue(self.attacker.db.Combat_ActionsLeft == 0)
self.assertTrue(self.attacker.db.Combat_LastAction == "Test")
# Initialize for combat
@ -485,29 +489,29 @@ class TestTurnBattleItemsFunc(BaseEvenniaTest):
self.assertTrue(self.turnhandler.db.fighters == [self.joiner, self.attacker, self.defender])
# Now time to test item stuff.
# Spend item use
tb_items.spend_item_use(self.test_healpotion, self.user)
tb_items.COMBAT_RULES.spend_item_use(self.test_healpotion, self.user)
self.assertTrue(self.test_healpotion.db.item_uses == 2)
# Use item
self.user.db.hp = 2
tb_items.use_item(self.user, self.test_healpotion, self.user)
tb_items.COMBAT_RULES.use_item(self.user, self.test_healpotion, self.user)
self.assertTrue(self.user.db.hp > 2)
# Add contition
tb_items.add_condition(self.user, self.user, "Test", 5)
tb_items.COMBAT_RULES.add_condition(self.user, self.user, "Test", 5)
self.assertTrue(self.user.db.conditions == {"Test": [5, self.user]})
# Condition tickdown
tb_items.condition_tickdown(self.user, self.user)
self.assertTrue(self.user.db.conditions == {"Test": [4, self.user]})
tb_items.COMBAT_RULES.condition_tickdown(self.user, self.user)
self.assertEqual(self.user.db.conditions, {"Test": [4, self.user]})
# Test item functions now!
# Item heal
self.user.db.hp = 2
tb_items.itemfunc_heal(self.test_healpotion, self.user, self.user)
tb_items.COMBAT_RULES.itemfunc_heal(self.test_healpotion, self.user, self.user)
# Item add condition
self.user.db.conditions = {}
tb_items.itemfunc_add_condition(self.test_healpotion, self.user, self.user)
tb_items.COMBAT_RULES.itemfunc_add_condition(self.test_healpotion, self.user, self.user)
self.assertTrue(self.user.db.conditions == {"Regeneration": [5, self.user]})
# Item cure condition
self.user.db.conditions = {"Poisoned": [5, self.user]}
tb_items.itemfunc_cure_condition(self.test_healpotion, self.user, self.user)
tb_items.COMBAT_RULES.itemfunc_cure_condition(self.test_healpotion, self.user, self.user)
self.assertTrue(self.user.db.conditions == {})
@ -526,53 +530,54 @@ class TestTurnBattleMagicFunc(BaseEvenniaTest):
def tearDown(self):
super().tearDown()
self.turnhandler.stop()
self.testroom.delete()
self.attacker.delete()
self.defender.delete()
self.joiner.delete()
self.testroom.delete()
# Test combat functions in tb_magic.
def test_tbbasicfunc(self):
# Initiative roll
initiative = tb_magic.roll_init(self.attacker)
initiative = tb_magic.COMBAT_RULES.roll_init(self.attacker)
self.assertTrue(initiative >= 0 and initiative <= 1000)
# Attack roll
attack_roll = tb_magic.get_attack(self.attacker, self.defender)
attack_roll = tb_magic.COMBAT_RULES.get_attack(self.attacker, self.defender)
self.assertTrue(attack_roll >= 0 and attack_roll <= 100)
# Defense roll
defense_roll = tb_magic.get_defense(self.attacker, self.defender)
defense_roll = tb_magic.COMBAT_RULES.get_defense(self.attacker, self.defender)
self.assertTrue(defense_roll == 50)
# Damage roll
damage_roll = tb_magic.get_damage(self.attacker, self.defender)
damage_roll = tb_magic.COMBAT_RULES.get_damage(self.attacker, self.defender)
self.assertTrue(damage_roll >= 15 and damage_roll <= 25)
# Apply damage
self.defender.db.hp = 10
tb_magic.apply_damage(self.defender, 3)
tb_magic.COMBAT_RULES.apply_damage(self.defender, 3)
self.assertTrue(self.defender.db.hp == 7)
# Resolve attack
self.defender.db.hp = 40
tb_magic.resolve_attack(self.attacker, self.defender, attack_value=20, defense_value=10)
tb_magic.COMBAT_RULES.resolve_attack(self.attacker, self.defender, attack_value=20,
defense_value=10)
self.assertTrue(self.defender.db.hp < 40)
# Combat cleanup
self.attacker.db.Combat_attribute = True
tb_magic.combat_cleanup(self.attacker)
tb_magic.COMBAT_RULES.combat_cleanup(self.attacker)
self.assertFalse(self.attacker.db.combat_attribute)
# Is in combat
self.assertFalse(tb_magic.is_in_combat(self.attacker))
self.assertFalse(tb_magic.COMBAT_RULES.is_in_combat(self.attacker))
# Set up turn handler script for further tests
self.attacker.location.scripts.add(tb_magic.TBMagicTurnHandler)
self.turnhandler = self.attacker.db.combat_TurnHandler
self.assertTrue(self.attacker.db.combat_TurnHandler)
self.turnhandler = self.attacker.db.combat_turnHandler
self.assertTrue(self.attacker.db.combat_turnHandler)
# Set the turn handler's interval very high to keep it from repeating during tests.
self.turnhandler.interval = 10000
# Force turn order
self.turnhandler.db.fighters = [self.attacker, self.defender]
self.turnhandler.db.turn = 0
# Test is turn
self.assertTrue(tb_magic.is_turn(self.attacker))
self.assertTrue(tb_magic.COMBAT_RULES.is_turn(self.attacker))
# Spend actions
self.attacker.db.Combat_ActionsLeft = 1
tb_magic.spend_action(self.attacker, 1, action_name="Test")
tb_magic.COMBAT_RULES.spend_action(self.attacker, 1, action_name="Test")
self.assertTrue(self.attacker.db.Combat_ActionsLeft == 0)
self.assertTrue(self.attacker.db.Combat_LastAction == "Test")
# Initialize for combat