popups: read the modal recipe, lore and map popups
Learning a recipe spoke the word "Popup" and then nothing.
There are two separate popup mechanisms and only one was covered.
patches/popupstack.lua wraps popupStack.add, but views/fadingPopup.lua
registers just four types -- journal, loot, bestiary and tutorial -- so
the recipe/lore/map keys in that patch could never fire. Those three are
modal instead: states/{ingame,inventory,research} build one from
modules/{recipe,lore,map}Popup.lua and switch to states/ingame_popup.
ingame_popup had a name in stateNames.lua and no descriptor, so
announceScreen said "Popup" and the focus poll had nothing to add.
The popup modules are factories exposing only draw(), so every string is
a closure local. The new descriptor takes popupObject off the state and
reads them as upvalues of popupObject.draw, detecting the type by which
locals exist since the object carries no type tag. Reading order follows
draw order, newlines are flattened (the lore footer is one sentence with
hard breaks in it), and the blocks go into the console history so [ and ]
walk a long fragment back; = re-reads it.
The prologue fires no popup, so the testbed raises them itself via
ingame.recipePopup and ingame.lorePopup -- both display-only, so nothing
is learned and the world is untouched. That check is this descriptor's
version-bump canary: the self-test can only report "custom read()" here,
because the probe is on the popup object rather than the state.
88 testbed checks, 0 failures.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
55b19dd537
commit
a1ad7f26c2
@@ -968,6 +968,63 @@ local function scenario()
|
||||
check("slider announces value changes", true, "via ingame_wait")
|
||||
end
|
||||
|
||||
-- ingame_popup: the modal recipe / lore / map / loot popups.
|
||||
--
|
||||
-- These do NOT go through popupStack (views/fadingPopup only registers
|
||||
-- journal, loot, bestiary and tutorial), so patches/popupstack.lua never
|
||||
-- saw them -- the whole body of text was silent behind the spoken word
|
||||
-- "Popup". The prologue never fires one, so we raise them by calling the
|
||||
-- state's own entry points. Both are display-only: recipePopup just shows
|
||||
-- a template's name, lorePopup just renders the params it is handed, so
|
||||
-- neither teaches the player anything or touches the world.
|
||||
do
|
||||
local ingameState = require("states/ingame")
|
||||
|
||||
local function readPopup(label, raise, wants)
|
||||
local ok = pcall(raise)
|
||||
if not ok or not waitForState("ingame_popup", 120) then
|
||||
check(label .. ": popup opened", false, "state = " .. currentState())
|
||||
return
|
||||
end
|
||||
|
||||
local text = focusText() or ""
|
||||
check(label .. ": popup speaks more than its name",
|
||||
#text > 0, text)
|
||||
for _, want in ipairs(wants) do
|
||||
check(label .. ": says '" .. want .. "'",
|
||||
text:lower():find(want:lower(), 1, true) ~= nil, text)
|
||||
end
|
||||
|
||||
-- keypressed ignores input until fadeInAlpha >= 0.8, and
|
||||
-- fadeInPeriod is 0.6s -- so it must be given time before the
|
||||
-- dismiss key will register.
|
||||
wait(90)
|
||||
press("escape", "dismiss popup")
|
||||
wait(10)
|
||||
check(label .. ": popup dismissed", currentState() == "ingame",
|
||||
"got " .. currentState())
|
||||
end
|
||||
|
||||
readPopup("recipe popup",
|
||||
function() ingameState.recipePopup("ivy_leaves") end,
|
||||
{"New recipe available", "ivy", "journal"})
|
||||
|
||||
-- The lore popup carries the longest body text of the four, and is
|
||||
-- the case where "it says 'popup' and stops" was most visible.
|
||||
readPopup("lore popup",
|
||||
function()
|
||||
ingameState.lorePopup({
|
||||
knowledgeType = "practical",
|
||||
topic = "testbed topic",
|
||||
text = "A fragment of text from a very old book.",
|
||||
unlocked = 1,
|
||||
max = 3,
|
||||
})
|
||||
end,
|
||||
{"A fragment of text from a very old book", "This text contains",
|
||||
"testbed topic"})
|
||||
end
|
||||
|
||||
-- The game's own examine mode.
|
||||
press("x", "enter examine mode")
|
||||
wait(10)
|
||||
|
||||
Reference in New Issue
Block a user