test: cover tests.effectsMessagesAddressThePlayerInSecondPersonNotThi...

This commit is contained in:
dualfroz committed 2026-09-08 17:52:05 +02:00
1 parent 62e694d522
commit a1f6ad3feb
1 file changed
+173
+173
View File
@@ -999,6 +999,179 @@ function tests.effects()
Effects.apply("fireball", blastGame, blastGame.player, {}) Effects.apply("fireball", blastGame, blastGame.player, {})
eq(orc.hp, 12, "fireball burns nearby monsters") eq(orc.hp, 12, "fireball burns nearby monsters")
eq(Status.has(orc, Status.BURNING), true, "fireball sets monsters alight") eq(Status.has(orc, Status.BURNING), true, "fireball sets monsters alight")
ok(Hazards.at(blastGame.level, orc.x, orc.y, Hazards.FIRE) ~= nil,
"fireball leaves a lingering flame under a scorched monster")
ok(Hazards.at(blastGame.level, blastGame.player.x, blastGame.player.y, Hazards.FIRE) ~= nil,
"fireball also ignites the ground at its own point of origin")
end
-- Effects.apply's only real caller (Game:useItem) always hands it the
-- player, whose entity.name is the pronoun "you" - a subject that takes the
-- plain verb form English gives second person ("you heal"), not the
-- third-person-singular form ("heals") a named monster like "orc" would take
-- through the exact same handler. Before this fix every line below actually
-- read "you heals 5", "you is poisoned", etc. on every real potion/scroll
-- use in the game - these are the literal strings a real player sees.
function tests.effectsMessagesAddressThePlayerInSecondPersonNotThirdPersonSingular()
local game = Game.new(31)
game.player.hp = 10
eq(Effects.apply("heal", game, game.player, { power = 5 })[1], "you heal 5",
"heal addresses the player correctly, not 'you heals 5'")
eq(Effects.apply("poison", game, game.player, { power = 3 })[1], "you are poisoned",
"poison addresses the player correctly, not 'you is poisoned'")
eq(Effects.apply("strength", game, game.player, {})[1], "you feel mightier",
"strength addresses the player correctly, not 'you feels mightier'")
eq(Effects.apply("haste", game, game.player, {})[1], "you speed up",
"haste addresses the player correctly, not 'you speeds up'")
eq(Effects.apply("fortify", game, game.player, {})[1], "you feel fortified",
"fortify addresses the player correctly, not 'you feels fortified'")
eq(Effects.apply("levitate", game, game.player, {})[1], "you rise off the ground",
"levitate addresses the player correctly, not 'you rises off the ground'")
eq(Effects.apply("confuse", game, game.player, {})[1], "your mind reels with confusion",
"confuse addresses the player possessively, not \"you's mind reels with confusion\"")
eq(Effects.apply("blind", game, game.player, {})[1], "you are struck blind",
"blind addresses the player correctly, not 'you is struck blind'")
eq(Effects.apply("teleport", game, game.player, {})[1], "you blink away",
"teleport addresses the player correctly, not 'you blinks away'")
end
function tests.effectsClarityMessageAddressesThePlayerPossessively()
local game = Game.new(31)
Sanity.adjust(game.player, -20)
local line = Effects.apply("clarity", game, game.player, { power = 10 })[1]
ok(contains(line, "your mind steadies"), "clarity addresses the player possessively, not \"you's mind steadies\"")
end
function tests.effectsCureMessagesAddressThePlayerPossessivelyForAllFourOutcomes()
local game = Game.new(31)
Disease.infect(game.player, Disease.ROT)
Status.apply(game.player, Status.POISON, 5, 2)
eq(Effects.apply("cure", game, game.player, {})[1], "your affliction is cleansed away, and the poison fades",
"curing both addresses the player possessively, not \"you's affliction ... you's poison\"")
Disease.infect(game.player, Disease.ROT)
eq(Effects.apply("cure", game, game.player, {})[1], "your affliction is cleansed away",
"curing disease alone addresses the player possessively, not \"you's affliction\"")
Status.apply(game.player, Status.POISON, 5, 2)
eq(Effects.apply("cure", game, game.player, {})[1], "your poison fades",
"curing a status alone addresses the player possessively, not \"you's poison fades\"")
eq(Effects.apply("cure", game, game.player, {})[1], "you feel a faint tingle, but had nothing to cleanse",
"curing nothing addresses the player correctly, not 'you feels a faint tingle'")
end
-- The exact same pronoun problem effects.lua had also lived in status.lua's
-- own POISON/REGEN tick messages, disease.lua's tick messages, and
-- terrain.lua's lava message - every one of them templated a
-- third-person-singular verb onto entity.name with no branch at all for the
-- player, whose name is "you". These four tests cover each of those sites
-- directly against a real player entity.
function tests.statusPoisonShrugAndRegenKnitMessagesAddressThePlayerInSecondPerson()
local immunePlayer = Entity.new({
x = 1, y = 1, glyph = "@", name = "you", kind = "player", hp = 10, maxHp = 10, attack = 1, defense = 0,
})
immunePlayer.resist = { poison = Resistances.IMMUNE }
Status.apply(immunePlayer, Status.POISON, 3, 4)
eq(Status.tick(immunePlayer)[1], "you shrug off the poison",
"an immune player shrugs off poison in second person, not 'you shrugs off the poison'")
local hurtPlayer = Entity.new({
x = 1, y = 1, glyph = "@", name = "you", kind = "player", hp = 5, maxHp = 10, attack = 1, defense = 0,
})
Status.apply(hurtPlayer, Status.REGEN, 2, 3)
eq(Status.tick(hurtPlayer)[1], "you knit flesh for 3",
"a regenerating player knits flesh in second person, not 'you knits flesh for 3'")
end
function tests.diseaseTickMessagesAddressThePlayerInSecondPersonForEruptionDamageAndEscalation()
local player = Entity.new({
x = 1, y = 1, glyph = "@", name = "you", kind = "player", hp = 1000, maxHp = 1000, attack = 1, defense = 0,
})
Disease.infect(player, Disease.PARASITES)
local incubation = Disease.defs[Disease.PARASITES].incubation
for _ = 1, incubation - 1 do Disease.tick(player) end
eq(Disease.tick(player), "you break out in gut parasites",
"eruption addresses the player in second person, not 'you breaks out in gut parasites'")
eq(Disease.tick(player), "you are wracked by gut parasites for 1",
"a damaging tick addresses the player in second person, not 'you is wracked by gut parasites for 1'")
local stageTurns = Disease.defs[Disease.PARASITES].stageTurns
for _ = 2, stageTurns - 1 do Disease.tick(player) end
eq(Disease.tick(player), "your gut parasites worsens",
"escalation addresses the player possessively, not \"you's gut parasites worsens\"")
end
function tests.terrainAfflictLavaUnharmedMessageAddressesThePlayerInSecondPerson()
local level = arena(21, 11)
level.map:set(5, 5, Tiles.LAVA)
local game = stagedGame(1, level, 5, 5)
game.player.resist = { fire = Resistances.IMMUNE }
eq(Terrain.afflictLava(level, game.player), "you wade through the lava unharmed",
"an immune player wading through lava is addressed in second person, not 'you wades through the lava unharmed'")
end
function tests.hazards()
local level = arena(21, 11)
local fire = Hazards.ignite(level, 5, 5, 3, 4)
eq(fire.kind, Hazards.FIRE, "ignite drops a fire hazard")
eq(Hazards.at(level, 5, 5, Hazards.FIRE), fire, "the hazard is found by its cell and kind")
Hazards.ignite(level, 5, 5, 5, 1)
eq(#level.hazards, 1, "re-igniting the same cell refreshes it instead of stacking a duplicate")
eq(fire.duration, 5, "refreshing a hazard keeps the stronger of the two durations")
eq(fire.potency, 4, "refreshing a hazard keeps the stronger of the two potencies")
local victim = Monsters.create(Monsters.byKey.rat, 1, 5, 5, 1)
local hpBefore = victim.hp
local line = Hazards.afflict(level, victim)
ok(contains(line, "flames"), "afflict describes a fire hazard as flames")
eq(victim.hp, hpBefore - fire.potency, "standing in fire deals its potency in damage")
eq(Status.has(victim, Status.BURNING), true, "fire afflict also lays down a burning status")
local elsewhere = Monsters.create(Monsters.byKey.rat, 2, 9, 9, 1)
eq(Hazards.afflict(level, elsewhere), nil, "afflict does nothing to an entity off any hazard cell")
local gas = Hazards.spawnGas(level, 12, 8, 4, 2)
eq(gas.kind, Hazards.GAS, "spawnGas drops a gas hazard")
local choker = Monsters.create(Monsters.byKey.rat, 3, 12, 8, 1)
local gasLine = Hazards.afflict(level, choker)
ok(contains(gasLine, "fumes"), "afflict describes a gas hazard as fumes")
eq(Status.has(choker, Status.POISON), true, "gas afflict lays down a poison status")
local wet = arena(21, 11)
wet.map:set(6, 6, Tiles.WATER)
Hazards.ignite(wet, 6, 6, 3, 2)
Hazards.step(wet, Rng.new(1))
eq(Hazards.at(wet, 6, 6, Hazards.FIRE), nil,
"fire sitting on water is doused on the very next environmental step")
local fading = arena(21, 11)
Hazards.spawn(fading, 15, 5, Hazards.FIRE, 1, 2)
Hazards.step(fading, Rng.new(1))
eq(Hazards.at(fading, 15, 5, Hazards.FIRE), nil, "a hazard is removed once its duration runs out")
local spread = false
for seed = 1, 200 do
local field = arena(21, 11)
Hazards.ignite(field, 10, 5, 3, 2)
Hazards.step(field, Rng.new(seed))
if Hazards.at(field, 11, 5) or Hazards.at(field, 9, 5)
or Hazards.at(field, 10, 4) or Hazards.at(field, 10, 6) then
spread = true
break
end
end
ok(spread, "fire eventually spreads into open neighbouring floor on some seed")
local rendered = stagedGame(1, arena(21, 11), 3, 6)
Hazards.ignite(rendered.level, 5, 6, 3, 2)
rendered:computeVisible()
ok(contains(rendered:render(), "`"), "a fire hazard on a visible cell renders as its glyph")
end
local function shrinePlayer(gold)
end end
function tests.messageLog() function tests.messageLog()