test: cover tests.durabilityWearArmorBreaksAndSubtractsItsPowerFromDe...
This commit is contained in:
1 parent
a9d2900e79
commit
117119b11e
1 file changed
+173
+173
@@ -8952,6 +8952,179 @@ function tests.durabilityWearWeaponDecrementsAndBreaksAtZeroSubtractingItsPower(
|
|||||||
end
|
end
|
||||||
|
|
||||||
function tests.durabilityWearWeaponIsANoOpOnceAlreadyBroken()
|
function tests.durabilityWearWeaponIsANoOpOnceAlreadyBroken()
|
||||||
|
local item = Items.weapon("dagger", 2)
|
||||||
|
item.durability = 0
|
||||||
|
local hero = { weapon = item, attack = 10, kind = "player", name = "you" }
|
||||||
|
eq(Durability.wearWeapon(hero), nil, "wearing an already broken weapon reports no further break")
|
||||||
|
eq(item.durability, 0, "durability never drops below zero")
|
||||||
|
eq(hero.attack, 10, "wearing an already-broken weapon never touches attack again")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.durabilityWearArmorBreaksAndSubtractsItsPowerFromDefense()
|
||||||
|
local hero = { defense = 1, inventory = {}, kind = "player", name = "you" }
|
||||||
|
Items.equipArmor(Items.armor("plate", 3), hero)
|
||||||
|
eq(hero.defense, 4, "the plate's power is baked into defense on equip")
|
||||||
|
hero.armor.durability = 1
|
||||||
|
local broke = Durability.wearArmor(hero)
|
||||||
|
ok(contains(broke, "battered"), "the break line reports the armor giving out")
|
||||||
|
eq(hero.defense, 1, "the armor's power is pulled back out of defense the instant it breaks")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.durabilityWearBowBreaksWithoutTouchingAnyStatDirectly()
|
||||||
|
local hero = { bow = Items.bow("shortbow", 3, 6), attack = 5, kind = "player", name = "you" }
|
||||||
|
hero.bow.durability = 1
|
||||||
|
local broke = Durability.wearBow(hero)
|
||||||
|
ok(contains(broke, "snaps"), "the break line reports the bow giving out")
|
||||||
|
eq(hero.bow.durability, 0, "durability floors at zero")
|
||||||
|
eq(hero.attack, 5, "a bow's power was never baked into attack, so breaking it leaves attack untouched")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.durabilityEffectivePowerIsZeroForABrokenItemAndFullOtherwise()
|
||||||
|
local bow = Items.bow("shortbow", 3, 6)
|
||||||
|
eq(Durability.effectivePower(bow), 3, "a pristine bow contributes its full power")
|
||||||
|
bow.durability = 0
|
||||||
|
eq(Durability.effectivePower(bow), 0, "a broken bow contributes nothing")
|
||||||
|
eq(Durability.effectivePower(nil), 0, "no bow equipped contributes nothing")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.durabilityRepairFailsWithoutEnoughGoldOrOnAPristineItem()
|
||||||
|
local hero = { weapon = Items.weapon("sword", 4), gold = 0 }
|
||||||
|
local success, reason = Durability.repair(hero, "weapon")
|
||||||
|
eq(success, false, "a pristine weapon refuses repair")
|
||||||
|
eq(reason, "already in perfect condition", "the refusal explains why")
|
||||||
|
hero.weapon.durability = 10
|
||||||
|
success, reason = Durability.repair(hero, "weapon")
|
||||||
|
eq(success, false, "an empty purse refuses to cover the repair bill")
|
||||||
|
eq(reason, "not enough gold", "the refusal explains why")
|
||||||
|
success, reason = Durability.repair(hero, "bow")
|
||||||
|
eq(success, false, "repairing an empty slot fails")
|
||||||
|
eq(reason, "nothing equipped there", "the refusal explains why")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.durabilityRepairRestoresFullDurabilityAndFoldsPowerBackInAfterABreak()
|
||||||
|
local hero = { attack = 5, gold = 100, inventory = {}, kind = "player", name = "you" }
|
||||||
|
Items.equipWeapon(Items.weapon("sword", 4), hero)
|
||||||
|
hero.weapon.durability = 0
|
||||||
|
hero.attack = hero.attack - 4
|
||||||
|
local success, cost = Durability.repair(hero, "weapon")
|
||||||
|
ok(success, "a full purse and a broken weapon repair successfully")
|
||||||
|
eq(hero.weapon.durability, Durability.MAX, "repairing restores full durability")
|
||||||
|
eq(cost, Durability.MAX * Durability.REPAIR_COST_PER_POINT, "repairing a fully broken item costs its full bill")
|
||||||
|
eq(hero.gold, 100 - cost, "the repair bill is deducted from gold")
|
||||||
|
eq(hero.attack, 9, "the weapon's power is folded back into attack once repaired")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.durabilityRepairOnANotYetBrokenItemJustTopsUpDurabilityWithoutTouchingStats()
|
||||||
|
local hero = { attack = 9, gold = 100 }
|
||||||
|
hero.weapon = Items.weapon("sword", 4)
|
||||||
|
hero.weapon.durability = 20
|
||||||
|
local success, cost = Durability.repair(hero, "weapon")
|
||||||
|
ok(success, "a merely dinged weapon still repairs")
|
||||||
|
eq(hero.weapon.durability, Durability.MAX, "durability tops back up to max")
|
||||||
|
eq(cost, (Durability.MAX - 20) * Durability.REPAIR_COST_PER_POINT, "the bill only covers the missing points")
|
||||||
|
eq(hero.attack, 9, "attack is untouched since the weapon was never broken in the first place")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.equipWeaponAddsOnlyEffectivePowerForAnAlreadyBrokenWeapon()
|
||||||
|
local hero = { attack = 5, inventory = {} }
|
||||||
|
local sword = Items.weapon("sword", 4)
|
||||||
|
sword.durability = 0
|
||||||
|
Items.equipWeapon(sword, hero)
|
||||||
|
eq(hero.attack, 5, "equipping an already-broken weapon adds none of its power")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.rangedFireDealsNoBowBonusOnceTheBowIsBroken()
|
||||||
|
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||||
|
game.player.bow = Items.bow("shortbow", 5, 6)
|
||||||
|
game.player.inventory[#game.player.inventory + 1] = Items.ammo("arrow", 10)
|
||||||
|
local orc = Monsters.create(Monsters.byKey.orc, 1, 9, 6, 1)
|
||||||
|
orc.hp, orc.maxHp = 999, 999
|
||||||
|
|
||||||
|
game:fireAt(orc)
|
||||||
|
local pristineDamage = 999 - orc.hp
|
||||||
|
|
||||||
|
orc.hp = 999
|
||||||
|
game.player.bow.durability = 0
|
||||||
|
game:fireAt(orc)
|
||||||
|
local brokenDamage = 999 - orc.hp
|
||||||
|
|
||||||
|
ok(brokenDamage < pristineDamage, "a broken bow deals strictly less damage than a working one")
|
||||||
|
eq(brokenDamage, pristineDamage - 5, "the broken bow's missing power matches its catalog power exactly")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.gamePlayerAttackWearsTheEquippedWeaponAndLogsWhenItBreaks()
|
||||||
|
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||||
|
Items.equipWeapon(Items.weapon("dagger", 2), game.player)
|
||||||
|
game.player.weapon.durability = 1
|
||||||
|
local orc = Monsters.create(Monsters.byKey.orc, 1, 4, 6, 1)
|
||||||
|
orc.hp, orc.maxHp = 999, 999
|
||||||
|
game:playerAttack(orc)
|
||||||
|
eq(game.player.weapon.durability, 0, "the weapon's last durability point is spent on this hit")
|
||||||
|
local broke = false
|
||||||
|
for _, line in ipairs(game.log:recent(6)) do
|
||||||
|
if contains(line, "breaks apart") then broke = true end
|
||||||
|
end
|
||||||
|
ok(broke, "the weapon breaking is reported in the message log")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.gameMonsterMeleeWearsThePlayersArmorAndLogsWhenItBreaks()
|
||||||
|
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||||
|
Items.equipArmor(Items.armor("plate", 3), game.player)
|
||||||
|
game.player.armor.durability = 1
|
||||||
|
local orc = Monsters.create(Monsters.byKey.orc, 1, 4, 6, 1)
|
||||||
|
game:monsterMelee(orc)
|
||||||
|
eq(game.player.armor.durability, 0, "the armor's last durability point is spent on this hit")
|
||||||
|
local broke = false
|
||||||
|
for _, line in ipairs(game.log:recent(6)) do
|
||||||
|
if contains(line, "battered") then broke = true end
|
||||||
|
end
|
||||||
|
ok(broke, "the armor breaking is reported in the message log")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.gameFireAtWearsTheEquippedBowAndLogsWhenItBreaks()
|
||||||
|
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||||
|
game.player.bow = Items.bow("shortbow", 3, 6)
|
||||||
|
game.player.bow.durability = 1
|
||||||
|
game.player.inventory[#game.player.inventory + 1] = Items.ammo("arrow", 5)
|
||||||
|
local orc = Monsters.create(Monsters.byKey.orc, 1, 9, 6, 1)
|
||||||
|
orc.hp, orc.maxHp = 999, 999
|
||||||
|
game:fireAt(orc)
|
||||||
|
eq(game.player.bow.durability, 0, "the bow's last durability point is spent on this shot")
|
||||||
|
ok(contains(game.log:last(), "snaps"), "the bow snapping is the shot's own last log line")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.gameBrokenEquippedSlotFindsTheFirstBrokenPieceInPriorityOrder()
|
||||||
|
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||||
|
eq(game:brokenEquippedSlot(), nil, "a fresh player with no gear has nothing broken")
|
||||||
|
Items.equipArmor(Items.armor("plate", 3), game.player)
|
||||||
|
game.player.armor.durability = 0
|
||||||
|
eq(game:brokenEquippedSlot(), "armor", "the only broken piece is found")
|
||||||
|
Items.equipWeapon(Items.weapon("sword", 4), game.player)
|
||||||
|
game.player.weapon.durability = 0
|
||||||
|
eq(game:brokenEquippedSlot(), "weapon", "weapon takes priority over armor once both are broken")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.gameRepairEquippedSpendsGoldAndLogsSuccess()
|
||||||
|
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||||
|
Items.equipWeapon(Items.weapon("sword", 4), game.player)
|
||||||
|
game.player.weapon.durability = 0
|
||||||
|
game.player.gold = 1000
|
||||||
|
local before = game.player.gold
|
||||||
|
local success = game:repairEquipped("weapon")
|
||||||
|
ok(success, "a full purse repairs the broken weapon")
|
||||||
|
eq(game.player.weapon.durability, Durability.MAX, "the weapon comes back to full durability")
|
||||||
|
ok(game.player.gold < before, "gold is spent on the repair")
|
||||||
|
ok(contains(game.log:last(), "repair"), "the repair is logged")
|
||||||
|
end
|
||||||
|
|
||||||
|
function tests.gameRepairEquippedFailsAndLogsWhenGoldIsShort()
|
||||||
|
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||||
|
Items.equipWeapon(Items.weapon("sword", 4), game.player)
|
||||||
|
game.player.weapon.durability = 0
|
||||||
|
game.player.gold = 0
|
||||||
|
local success = game:repairEquipped("weapon")
|
||||||
|
eq(success, false, "an empty purse cannot repair")
|
||||||
|
eq(game.player.weapon.durability, 0, "the weapon stays broken")
|
||||||
end
|
end
|
||||||
|
|
||||||
local order = {
|
local order = {
|
||||||
|
|||||||
Reference in new issue
Block a user