test: cover tests.gameUseItemDrinkingACurePotionLiftsTheInfectionAndI...
This commit is contained in:
1 parent
89e97d7b3a
commit
fce4742c18
1 file changed
+173
+173
@@ -12066,6 +12066,179 @@ function tests.gameEndPlayerTurnTicksThePlayersDiseaseAndLogsItsEruption()
|
||||
Disease.infect(game.player, Disease.PARASITES)
|
||||
local incubation = Disease.defs[Disease.PARASITES].incubation
|
||||
for _ = 1, incubation - 1 do
|
||||
game:endPlayerTurn()
|
||||
eq(game.player.disease.stage, 0, "the infection keeps quietly incubating turn by turn")
|
||||
end
|
||||
game:endPlayerTurn()
|
||||
eq(game.player.disease.stage, 1, "the infection erupts on schedule as the player's own turns tick past")
|
||||
eq(game.log:last(), "you break out in gut parasites",
|
||||
"the eruption is reported in the message log with correct you-are-the-subject grammar, not the third-person 'breaks out' a named monster would get")
|
||||
end
|
||||
|
||||
function tests.gameUseItemDrinkingACurePotionLiftsTheInfectionAndIdentifiesThePotion()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
Disease.infect(game.player, Disease.ROT)
|
||||
game.player.inventory = { Items.potionOf("cure") }
|
||||
local used = game:useItem(1)
|
||||
eq(used, true, "drinking the potion succeeds")
|
||||
ok(not Disease.isInfected(game.player), "the cure potion lifts the infection entirely")
|
||||
ok(contains(game.log:last(), "cleansed"), "the log confirms the cure took effect")
|
||||
eq(#game.player.inventory, 0, "the spent potion leaves the inventory like any other")
|
||||
end
|
||||
|
||||
function tests.gameUseItemDrinkingACurePotionAlsoLiftsHostileStatusesNotJustDisease()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
Status.apply(game.player, Status.POISON, 5, 2)
|
||||
Status.apply(game.player, Status.CONFUSE, 6, 1)
|
||||
Status.apply(game.player, Status.STRENGTH, 30, 3)
|
||||
game.player.inventory = { Items.potionOf("cure") }
|
||||
local used = game:useItem(1)
|
||||
eq(used, true, "drinking the potion succeeds")
|
||||
ok(not Status.has(game.player, Status.POISON), "the cure potion lifts poison even with no disease present")
|
||||
ok(not Status.has(game.player, Status.CONFUSE), "the cure potion lifts confusion too")
|
||||
ok(Status.has(game.player, Status.STRENGTH), "the cure potion never touches a buff like strength")
|
||||
ok(contains(game.log:last(), "fades"), "the log reports the lifted statuses when there was no disease to mention")
|
||||
end
|
||||
|
||||
function tests.gameUseItemDrinkingACurePotionReportsBothDiseaseAndStatusesWhenBothArePresent()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
Disease.infect(game.player, Disease.ROT)
|
||||
Status.apply(game.player, Status.POISON, 5, 2)
|
||||
game.player.inventory = { Items.potionOf("cure") }
|
||||
game:useItem(1)
|
||||
ok(not Disease.isInfected(game.player), "the infection is lifted alongside the status effect")
|
||||
ok(not Status.has(game.player, Status.POISON), "the status effect is lifted alongside the infection")
|
||||
ok(contains(game.log:last(), "cleansed away") and contains(game.log:last(), "fades"),
|
||||
"the single log line credits both the disease cure and the status cure")
|
||||
end
|
||||
|
||||
function tests.gameUseItemDrinkingACurePotionWithNothingToCureIsHonestInTheLog()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.player.inventory = { Items.potionOf("cure") }
|
||||
local used = game:useItem(1)
|
||||
eq(used, true, "the potion is still consumed even when there is nothing to cleanse")
|
||||
ok(contains(game.log:last(), "nothing to cleanse"), "the log admits nothing was actually cured")
|
||||
end
|
||||
|
||||
function tests.diseaseAndBiteDiseaseFieldsSurviveALevelSerializationRoundTrip()
|
||||
local game = stagedGame(1, arena(21, 11), 5, 5)
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 6, 5, 1)
|
||||
Disease.infect(rat, Disease.PLAGUE)
|
||||
rat.disease.stage = 2
|
||||
game.level.entities = { rat }
|
||||
|
||||
local restored = Level.fromData(game.level:toData())
|
||||
eq(restored.entities[1].biteDisease, Disease.PARASITES, "the species' own carried affliction survives a level round trip")
|
||||
eq(restored.entities[1].disease.key, Disease.PLAGUE, "the active infection's key survives a level round trip")
|
||||
eq(restored.entities[1].disease.stage, 2, "the active infection's progressed stage survives a level round trip")
|
||||
end
|
||||
|
||||
-- captives.lua: netting a battered monster alive instead of finishing it
|
||||
-- off, and cashing the resulting captive in for goodwill, gold or intel.
|
||||
|
||||
function tests.captivesEligibleAcceptsABatteredWildHostileAndRejectsATooHealthyOne()
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 6, 6, 1)
|
||||
rat.hp = 1
|
||||
ok(Captives.eligible(rat), "a wild hostile battered down to a sliver of hp is eligible for a net")
|
||||
rat.hp = rat.maxHp
|
||||
ok(not Captives.eligible(rat), "a target still at full health is too fierce to net")
|
||||
end
|
||||
|
||||
function tests.captivesEligibleExcludesBossesMimicsGravesNemesesAndTheVendingShopkeeper()
|
||||
local orc = Monsters.create(Monsters.byKey.orc, 1, 6, 6, 3)
|
||||
orc.hp = 1
|
||||
orc.isBoss = true
|
||||
ok(not Captives.eligible(orc), "a boss is excluded from netting even when battered")
|
||||
orc.isBoss = false
|
||||
orc.mimic = true
|
||||
ok(not Captives.eligible(orc), "a mimic is excluded from netting even when battered")
|
||||
orc.mimic = false
|
||||
orc.grave = true
|
||||
ok(not Captives.eligible(orc), "a grave shade is excluded from netting even when battered")
|
||||
orc.grave = false
|
||||
orc.nemesis = true
|
||||
ok(not Captives.eligible(orc), "a nemesis is excluded from netting even when battered")
|
||||
orc.nemesis = false
|
||||
ok(Captives.eligible(orc), "the same battered orc becomes eligible again once none of the exclusions apply")
|
||||
local shopkeeper = Monsters.create(Monsters.byKey.shopkeeper, 2, 6, 6, 4)
|
||||
shopkeeper.hp = 1
|
||||
ok(not Captives.eligible(shopkeeper), "the vending shopkeeper is never eligible for a net even when battered")
|
||||
end
|
||||
|
||||
function tests.captivesCanReachRespectsRangeAndLineOfSight()
|
||||
local level = arena(21, 11)
|
||||
ok(Captives.canReach(level.map, 3, 6, 3 + Captives.RANGE, 6), "a target at exactly max range with a clear line is reachable")
|
||||
ok(not Captives.canReach(level.map, 3, 6, 3 + Captives.RANGE + 1, 6), "a target one cell beyond max range is unreachable")
|
||||
level.map:set(5, 6, Tiles.WALL)
|
||||
ok(not Captives.canReach(level.map, 3, 6, 7, 6), "a wall blocking the line of sight makes an in-range target unreachable")
|
||||
end
|
||||
|
||||
function tests.captivesValueOfMatchesKillXpAndAddsAnEliteBonus()
|
||||
local orc = Monsters.create(Monsters.byKey.orc, 1, 6, 6, 3)
|
||||
eq(Captives.valueOf(orc), Monsters.xpFor(orc), "a plain monster's capture value equals its kill xp")
|
||||
orc.elite = true
|
||||
orc.eliteTier = "champion"
|
||||
local baseXp = Monsters.xpFor(orc)
|
||||
eq(Captives.valueOf(orc), baseXp + Elites.xpBonus(orc, baseXp),
|
||||
"an elite's capture value adds the same bonus a kill's xp would")
|
||||
ok(Captives.valueOf(orc) > baseXp, "the elite bonus actually raises the capture value above the plain kill xp")
|
||||
end
|
||||
|
||||
function tests.captivesResolveRefusesWithNoClearThrowWithoutSpendingTheNet()
|
||||
local game = stagedGame(4, arena(21, 11), 2, 2)
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 19, 9, 1)
|
||||
rat.hp = 1
|
||||
game.level.entities = { rat }
|
||||
local net = Items.net()
|
||||
local success, lines = Captives.resolve(game, game.player, net, rat)
|
||||
eq(success, false, "a net thrown beyond range never leaves the hand")
|
||||
ok(contains(lines[1], "clear throw"), "the reason given is the lack of a clear throw")
|
||||
end
|
||||
|
||||
function tests.captivesResolveWastesTheNetOnATargetStillTooHealthyToSubdue()
|
||||
local game = stagedGame(4, arena(21, 11), 3, 6)
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 6, 6, 1)
|
||||
game.level.entities = { rat }
|
||||
local net = Items.net()
|
||||
local success, lines = Captives.resolve(game, game.player, net, rat)
|
||||
eq(success, true, "a net thrown at a still-healthy target still leaves the hand")
|
||||
eq(#game.level.captives, 0, "no captive is created from a target too healthy to subdue")
|
||||
eq(rat.hp, rat.maxHp, "the target takes no damage from a wasted net")
|
||||
ok(contains(lines[1], "fierce"), "the log explains the target was too fierce to net")
|
||||
end
|
||||
|
||||
function tests.captivesResolveCanThrashFreeAndStillSpendTheNet()
|
||||
local game = stagedGame(4, arena(21, 11), 3, 6)
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 6, 6, 1)
|
||||
rat.hp = 1
|
||||
game.level.entities = { rat }
|
||||
game.rng = Rng.new(1)
|
||||
local net = Items.net()
|
||||
local success, lines = Captives.resolve(game, game.player, net, rat)
|
||||
eq(success, true, "a lost catch roll still leaves the net thrown")
|
||||
eq(#game.level.captives, 0, "no captive is created when the target thrashes free")
|
||||
eq(rat.hp, 1, "a thrashing target takes no further damage")
|
||||
ok(rat:isAlive(), "a target that thrashes free is still alive")
|
||||
ok(contains(lines[1], "thrashes free"), "the log reports the target thrashing free")
|
||||
end
|
||||
|
||||
function tests.captivesResolveCatchesABatteredTargetIntoACaptiveAndZeroesItsHp()
|
||||
local game = stagedGame(4, arena(21, 11), 3, 6)
|
||||
local rat = Monsters.create(Monsters.byKey.rat, 1, 6, 6, 1)
|
||||
rat.hp = 1
|
||||
game.level.entities = { rat }
|
||||
game.rng = Rng.new(2)
|
||||
local net = Items.net()
|
||||
local success, lines = Captives.resolve(game, game.player, net, rat)
|
||||
eq(success, true, "a successful catch leaves the net thrown")
|
||||
eq(#game.level.captives, 1, "a successful catch adds exactly one captive")
|
||||
local captive = game.level.captives[1]
|
||||
eq(captive.name, rat.name, "the captive keeps the caught monster's name")
|
||||
eq(captive.species, rat.species, "the captive keeps the caught monster's species")
|
||||
eq(captive.faction, rat.faction, "the captive keeps the caught monster's faction")
|
||||
eq(captive.value, Monsters.xpFor(rat), "the captive's value matches Captives.valueOf")
|
||||
eq(rat.hp, 0, "the caught monster's hp is zeroed")
|
||||
ok(not rat:isAlive(), "the caught monster is no longer alive")
|
||||
end
|
||||
|
||||
local order = {
|
||||
|
||||
Reference in new issue
Block a user