test: cover tests.entityWetFieldSurvivesSerialization
This commit is contained in:
1 parent
607c19a95f
commit
7679ba954e
1 file changed
+173
+173
@@ -7741,6 +7741,179 @@ function tests.builderCanRollATomeOfTheShockBoltSpell()
|
||||
-- seed, and the nearest shock tome under the new list happens to sit at
|
||||
-- seed 174 - still well within "a reasonable seed range".
|
||||
local found
|
||||
for seed = 1, 200 do
|
||||
local level = Builder.build(6, Rng.new(seed), {})
|
||||
for _, ground in ipairs(level.floorItems) do
|
||||
if ground.item.kind == Items.TOME and ground.item.spell == "shock" then found = ground.item end
|
||||
end
|
||||
if found then break end
|
||||
end
|
||||
ok(found ~= nil, "the shock bolt tome is reachable dungeon loot within a reasonable seed range")
|
||||
eq(found.name, "tome of shock", "an unnamed tome defaults its label to the spell key")
|
||||
end
|
||||
|
||||
function tests.entityWetFieldSurvivesSerialization()
|
||||
local game = Game.new(3)
|
||||
game.player.wet = 2
|
||||
local path = os.tmpname()
|
||||
game:save(path)
|
||||
local restored = Game.load(path)
|
||||
os.remove(path)
|
||||
eq(restored.player.wet, 2, "the player's soak counter survives a save/load round trip")
|
||||
end
|
||||
|
||||
function tests.diggingCanDigAllowsOnlyWallsAndRubble()
|
||||
local level = arena(21, 11)
|
||||
ok(Digging.canDig(level.map, 1, 5), "the arena's own border wall is diggable")
|
||||
ok(not Digging.canDig(level.map, 5, 5), "open floor has nothing left to dig")
|
||||
level.map:set(5, 5, Tiles.RUBBLE)
|
||||
ok(Digging.canDig(level.map, 5, 5), "rubble left by a prior swing is still diggable")
|
||||
level.map:set(5, 5, Tiles.VAULT_DOOR)
|
||||
ok(not Digging.canDig(level.map, 5, 5), "a vault's own boundary never yields to a pick")
|
||||
ok(not Digging.canDig(level.map, 0, 5), "a cell outside the map is never diggable")
|
||||
end
|
||||
|
||||
function tests.diggingSwingClearsAWallToRubbleOnAnOrdinarySwing()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(5, 5, Tiles.WALL)
|
||||
game.rng = Rng.new(1)
|
||||
local line = Digging.swing(game, game.player, 5, 5)
|
||||
eq(game.level.map:get(5, 5), Tiles.RUBBLE, "an ordinary swing crumbles a wall to rubble, not clear")
|
||||
ok(contains(line, "carve"), "the log line describes carving through rock")
|
||||
end
|
||||
|
||||
function tests.diggingSwingClearsRubbleToFloorOnASecondSwing()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(5, 5, Tiles.RUBBLE)
|
||||
game.rng = Rng.new(1)
|
||||
local line = Digging.swing(game, game.player, 5, 5)
|
||||
eq(game.level.map:get(5, 5), Tiles.FLOOR, "a second swing clears rubble the rest of the way to open floor")
|
||||
ok(contains(line, "clear"), "the log line describes clearing rubble away")
|
||||
end
|
||||
|
||||
function tests.diggingSwingCaveInHurtsTheDiggerAndLeavesTheTileUntouched()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(5, 5, Tiles.WALL)
|
||||
game.rng = Rng.new(6)
|
||||
local hpBefore = game.player.hp
|
||||
local line = Digging.swing(game, game.player, 5, 5)
|
||||
eq(game.level.map:get(5, 5), Tiles.WALL, "a cave-in wastes the swing; the wall is untouched")
|
||||
ok(game.player.hp < hpBefore, "a cave-in deals real damage to the digger")
|
||||
ok(contains(line, "buries you"), "the log line names the player directly, not by their entity name")
|
||||
end
|
||||
|
||||
function tests.diggingSwingOreStrikeClearsTheWallOutrightAndPaysEssenceToATrackingDigger()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(5, 5, Tiles.WALL)
|
||||
game.rng = Rng.new(2)
|
||||
local essenceBefore = game.player.essence
|
||||
local line = Digging.swing(game, game.player, 5, 5)
|
||||
eq(game.level.map:get(5, 5), Tiles.FLOOR, "a lucky ore strike clears the wall in a single stroke")
|
||||
ok(game.player.essence > essenceBefore, "striking a vein pays essence to a digger that tracks it")
|
||||
ok(contains(line, "essence"), "the log line reports the essence payout")
|
||||
end
|
||||
|
||||
function tests.diggingSwingOreStrikeSkipsTheEssenceRewardForADiggerThatDoesNotTrackIt()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(5, 5, Tiles.WALL)
|
||||
local burrower = Entity.new({ id = 1, x = 4, y = 5, glyph = "b", name = "rock burrower", kind = "monster", hp = 12, attack = 4, defense = 2 })
|
||||
game.rng = Rng.new(2)
|
||||
local line = Digging.swing(game, burrower, 5, 5)
|
||||
eq(game.level.map:get(5, 5), Tiles.FLOOR, "the same lucky strike still clears the wall for a monster")
|
||||
eq(burrower.essence, nil, "a monster never gains an essence field it never had")
|
||||
ok(contains(line, "vein"), "the log line still names the vein even without a payout")
|
||||
end
|
||||
|
||||
function tests.diggingWearPickDepletesDurabilityAndBreaksAtZero()
|
||||
local entity = { pick = Items.pick("test pick", 2) }
|
||||
eq(Digging.wearPick(entity), nil, "the first swing just wears the edge down")
|
||||
eq(entity.pick.uses, 1, "one use is spent")
|
||||
local brokenLine = Digging.wearPick(entity)
|
||||
ok(contains(brokenLine, "crumbles"), "the swing that empties the pick reports it breaking")
|
||||
eq(entity.pick, nil, "a spent pick is discarded outright")
|
||||
end
|
||||
|
||||
function tests.diggingWearPickIsANoOpWithoutAPickEquipped()
|
||||
local entity = {}
|
||||
eq(Digging.wearPick(entity), nil, "wearing down a pick that was never equipped changes nothing")
|
||||
end
|
||||
|
||||
function tests.diggingDirectionsTowardPrefersTheLongerAxisFirst()
|
||||
local dirs = Digging.directionsToward(10, 10, 15, 12)
|
||||
eq(#dirs, 2, "a diagonal target yields both an x and a y candidate")
|
||||
eq(dirs[1][1], 1, "the longer x delta is offered first")
|
||||
eq(dirs[1][2], 0, "the first candidate is a pure x step")
|
||||
eq(dirs[2][1], 0, "the second candidate is a pure y step")
|
||||
eq(dirs[2][2], 1, "it steps toward the smaller but still positive y delta")
|
||||
|
||||
local vertical = Digging.directionsToward(10, 10, 11, 5)
|
||||
eq(vertical[1][1], 0, "when y dominates, the y step comes first")
|
||||
eq(vertical[1][2], -1, "stepping toward a smaller y is a negative step")
|
||||
end
|
||||
|
||||
function tests.diggingDirectionsTowardOmitsAZeroDelta()
|
||||
local dirs = Digging.directionsToward(10, 10, 15, 10)
|
||||
eq(#dirs, 1, "a purely horizontal target yields only one candidate")
|
||||
eq(dirs[1][1], 1, "the sole candidate steps toward positive x")
|
||||
eq(dirs[1][2], 0, "the sole candidate carries no y component")
|
||||
|
||||
local same = Digging.directionsToward(10, 10, 10, 10)
|
||||
eq(#same, 0, "already standing on the target yields no candidate at all")
|
||||
end
|
||||
|
||||
function tests.itemsEquipPickSwapsAnyPriorPickBackIntoInventory()
|
||||
local entity = { inventory = {}, pick = Items.pick("worn pick", 3) }
|
||||
local fresh = Items.pick("fresh pick", 20)
|
||||
Items.equipPick(fresh, entity)
|
||||
eq(entity.pick, fresh, "the freshly equipped pick becomes the active one")
|
||||
eq(#entity.inventory, 1, "the previously equipped pick drops back into the inventory")
|
||||
eq(entity.inventory[1].name, "worn pick", "the displaced pick is the one that was equipped before")
|
||||
end
|
||||
|
||||
function tests.shopPicksHaveAPositiveCatalogPrice()
|
||||
ok(Shop.priceOf(Items.pick()) > 0, "a miner's pick has a positive catalog price")
|
||||
end
|
||||
|
||||
function tests.gameDigFailsWithoutAPickEquipped()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(4, 6, Tiles.WALL)
|
||||
local moved = game:dig(1, 0)
|
||||
eq(moved, false, "digging without a pick equipped fails outright")
|
||||
eq(game.level.map:get(4, 6), Tiles.WALL, "the wall is untouched without a pick")
|
||||
ok(contains(game.log:last(), "nothing to dig with"), "the log explains why")
|
||||
end
|
||||
|
||||
function tests.gameDigFailsWhenNothingAheadIsDiggable()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.player.pick = Items.pick()
|
||||
local moved = game:dig(1, 0)
|
||||
eq(moved, false, "there is nothing to dig into open floor")
|
||||
ok(contains(game.log:last(), "nothing here to dig"), "the log explains why")
|
||||
end
|
||||
|
||||
function tests.gameDigClearsAWallAndWearsThePickDown()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(4, 6, Tiles.WALL)
|
||||
game.player.pick = Items.pick("miner's pick", 5)
|
||||
game.rng = Rng.new(1)
|
||||
local moved = game:dig(1, 0)
|
||||
eq(moved, true, "a swing against a wall with a pick readied succeeds")
|
||||
eq(game.level.map:get(4, 6), Tiles.RUBBLE, "the wall crumbles to rubble")
|
||||
eq(game.player.pick.uses, 4, "the swing spends one use of the pick's durability")
|
||||
end
|
||||
|
||||
function tests.gameDigBreaksThePickOnItsLastUse()
|
||||
local game = stagedGame(1, arena(21, 11), 3, 6)
|
||||
game.level.map:set(4, 6, Tiles.WALL)
|
||||
game.player.pick = Items.pick("worn pick", 1)
|
||||
game.rng = Rng.new(1)
|
||||
game:dig(1, 0)
|
||||
eq(game.player.pick, nil, "the pick's last use breaks it outright")
|
||||
ok(contains(game.log:last(), "crumbles"), "the log reports the pick breaking")
|
||||
end
|
||||
|
||||
function tests.gameMonsterTunnelsThroughAWallToReachAndAttackThePlayer()
|
||||
local level = arena(21, 11)
|
||||
end
|
||||
|
||||
local order = {
|
||||
|
||||
Reference in new issue
Block a user