diff --git a/CHANGELOG.md b/CHANGELOG.md index df7007a..331bf61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,22 @@ ### Changed +- **TILT and GBC FX are off the OPTIONS menu entirely while this mod is + installed.** Both fight the diorama and both were already half-taken: the + mode's own key forces them off on every press, and the registry switches + TILT off whenever a world pipeline takes the pass. What was left was two + rows a player could set and watch get reverted -- TILT being the flat fake + of what this mode does for real, and GBC FX a full-screen present pass over + the top of the whole thing. + + Dropped AND held at zero, which is the part that matters: hiding a live + setting is a trap, because a save written before the mod was installed can + carry TILT 3 and a row that is not there cannot turn it back off. Pinned + wherever the value could arrive from -- the menu opening, a save being + loaded or begun -- so there is no route by which either is on and + unreachable. Uninstalling the mod puts both rows back, at whatever they were + last set to. + - **The battle's text box and menus are frosted glass, like the HUDs.** The HUD blocks got panels because black glyphs on grass are not readable. The box at the bottom had the opposite problem and the same cause: it is drawn as an diff --git a/README.md b/README.md index f9c39ad..b40d6cf 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,13 @@ menu. **3D-BTL** is on by default and is independent of **VOXEL**: battles draw on the world whether or not the free-roam camera is pitched over. +Two of the engine's own rows are taken away while this mod is installed: +**TILT**, which is the flat fake of what this mode does for real, and **GBC +FX**, a full-screen present pass over the top of the diorama. Both are held at +off rather than merely hidden — a row that is not there cannot switch off a +value an older save arrived with. Uninstall and both come back, at whatever +they were last set to. + Everything the battle screen draws as a box — the two HUD blocks, the text box and the menus over it — sits on frosted glass rather than on the white field it used to have behind it: the world underneath, blurred and laid back diff --git a/main.lua b/main.lua index 88cea2b..26c78e6 100644 --- a/main.lua +++ b/main.lua @@ -367,9 +367,12 @@ mod.options:define(schema) -- AND the engine's TILT on the same press. -- -- Consequences worth being explicit about: while this mod is enabled, TILT --- (3) and GBC FX (5) are unreachable by key. Both are still reachable on --- the OPTIONS menu, and TILT is the one this mode supersedes anyway -- the --- registry already forces it off whenever a world pipeline takes the pass. +-- (3) and GBC FX (5) are unreachable by key -- and unreachable on the OPTIONS +-- menu too, where both rows are taken away and both values held at zero (see +-- pinEngineFx). Nothing is being hidden that still does something: TILT is the +-- flat fake of what this mode does for real, the registry already forces it +-- off whenever a world pipeline takes the pass, and GBC FX is a full-screen +-- present pass over the top of the diorama. Uninstalling puts both back. -- -- Everything the engine does around a pipeline hotkey has to happen here -- too, so the work is DELEGATED rather than reimplemented: Pipelines.hotkey @@ -488,12 +491,50 @@ local function dropRow(out, id) return out end +-- ------- TILT and GBC FX are gone while this mod is installed +-- +-- Both fight the diorama, and both were already half-taken: the mode's own key +-- (3) forces them off on every press, and the registry switches TILT off +-- whenever a world pipeline takes the pass. What was left was two rows the +-- player could set and watch get reverted -- TILT is the flat fake of what +-- this mode does for real, and GBC FX is a full-screen present pass over the +-- top of the whole thing. +-- +-- So they come OFF the menu, and are HELD at zero rather than merely dropped. +-- Hiding a live setting is a trap: a save written before the mod was installed +-- can carry TILT 3, and a row that is not there is a row that cannot turn it +-- back off. Pinned wherever the value could have arrived from -- the menu +-- opening, a save being loaded or begun -- so there is no route by which one +-- of them is on and unreachable. +-- +-- Everything they did is still reachable: uninstall the mod and both rows are +-- back, at whatever they were last set to. +local function pinEngineFx(game) + game = game or require("src.core.Game") + local opts = game and game.save and game.save.options + local Tilt = require("src.render.Tilt") + local GBCFX = require("src.render.GBCFX") + local changed = false + if opts then + changed = (opts.tilt or 0) ~= 0 or (opts.gbcfx or 0) ~= 0 + opts.tilt, opts.gbcfx = 0, 0 + end + pcall(Tilt.setLevel, 0) + pcall(GBCFX.setLevel, 0) + if changed and game.writeOptions then pcall(game.writeOptions, game) end +end + -- call next() first and decorate what comes back, so every other mod's -- rows survive this one mod.hooks:wrap("ui.options.rows", function(next, game, rows) local out = next(game, rows) if type(out) ~= "table" then return out end local Pipelines = require("src.render.Pipelines") + -- ahead of every branch below, including FULL's early return: these two are + -- off the menu whatever else this mod is or is not doing + pinEngineFx(game) + dropRow(out, "tilt") + dropRow(out, "gbcfx") -- BATTLE LAYOUT is the ENGINE's row, and this is the one place the mod takes -- one away. While a fight can be staged on the map, OG is the only layout it -- can be composed in (OverworldBattle.forceOG), so the value is pinned there @@ -514,8 +555,8 @@ mod.hooks:wrap("ui.options.rows", function(next, game, rows) local extra = {} for _, entry in ipairs(SETTINGS) do -- a row whose own switch is off the table this frame (BACK SPRITES, which - -- staged fight to be about) is left off with it; the mod manager's page - -- still carries every one of them + -- needs a staged fight to be about) is left off with it; the mod manager's + -- page still carries every one of them if not entry.when or entry.when() then extra[#extra + 1] = entry[1]:row() end end return insertGrouped(out, extra) @@ -746,10 +787,16 @@ end) mod.events:on("save.loaded", function() DayNight.restore() + -- a save written before this mod was installed can carry TILT or GBC FX + -- switched on, and their rows are not there to switch them back off (see + -- pinEngineFx). Answered here rather than only when the menu opens, so a + -- player who never opens it is not left playing under one. + pinEngineFx() end) mod.events:on("save.created", function() DayNight.restore() + pinEngineFx() end) -- The engine's own time-of-day seam. OverworldState:timeOfDay() is an diff --git a/mod.card b/mod.card index 79a2eb3..9f72264 100644 --- a/mod.card +++ b/mod.card @@ -14,9 +14,8 @@ return { "the battle's text box and menu are frosted glass over that ground rather than an opaque white slab, on the same panels the HUDs sit on", "the map's NPCs are culled for the length of a battle, so the wipe plays over an empty map", "a battle's letterbox voids go black rather than white, because the battle canvas is no longer white", - "VOXEL and the engine's TILT are mutually exclusive -- turning one on switches the other off", - "hotkeys 3 and 5 are taken over from the engine's TILT and GBC FX; both remain on the OPTIONS menu", - "the VOXEL key (3) turns TILT and GBC FX off on every press -- both fight the diorama, and 3 is now the only key that reaches either", + "the engine's TILT and GBC FX rows are taken OFF the OPTIONS menu and held at off for as long as this mod is installed -- TILT is the flat fake of what this mode does for real, GBC FX is a full-screen pass over the top of it; uninstalling puts both rows back", + "hotkeys 3 and 5 are taken over from those two, which have no key and no row while this is loaded", }, added = { "VOXEL options row and hotkey 3 (OFF / 15 / 35 / 50 / 75 degrees)", diff --git a/tests/dramatic_shape_test.lua b/tests/dramatic_shape_test.lua index 5432cd0..a637c31 100644 --- a/tests/dramatic_shape_test.lua +++ b/tests/dramatic_shape_test.lua @@ -210,6 +210,53 @@ T.eq(layoutGame.save.options.battleLayout, "og", Battles.setting:setIndex(1, layoutGame) end +-- ------- TILT and GBC FX are off the menu entirely +-- +-- Two ENGINE rows, taken away for as long as this mod is installed. Both fight +-- the diorama and both were already half-taken -- the mode's own key forces +-- them off on every press, and the registry switches TILT off whenever a world +-- pipeline takes the pass -- so what was left was two rows a player could set +-- and watch get reverted. +-- +-- Dropped AND held at zero, which is the part that matters: a save written +-- before the mod was installed can carry TILT 3, and a row that is not there +-- is a row that cannot turn it back off. +do +local fxGame = { + data = Data, + save = { options = { tilt = 3, gbcfx = 2, pipelines = {}, modOptions = {} } }, + mods = { modOptions = {} }, + writeOptions = function() end, +} +local Tilt = require("src.render.Tilt") +local GBCFX = require("src.render.GBCFX") +Tilt.setLevel(3) +GBCFX.setLevel(2) + +local fxRows = Runtime.call("ui.options.rows", function(_, r) return r end, + fxGame, + { { id = "tilt" }, { id = "gbcfx" }, + { id = "colors" }, { id = "pipeline:voxel" } }) +local fxIds = {} +for _, row in ipairs(fxRows) do fxIds[row.id] = true end +T.check(not fxIds["tilt"], "TILT is off the OPTIONS menu") +T.check(not fxIds["gbcfx"], "and so is GBC FX") +T.check(fxIds["colors"] and fxIds["pipeline:voxel"], + "with every other row the engine offered still on it") + +T.eq(fxGame.save.options.tilt, 0, + "a save that had TILT on is pinned back to off, not left on with no row") +T.eq(fxGame.save.options.gbcfx, 0, "and GBC FX with it") +T.eq(Tilt.level, 0, "the live level follows, so the frame is not still tilted") + +-- and FULL, which returns early from the rows hook, must not be a way back in +Pipelines.setLevel("voxel", VoxelState.FULL_LEVEL) +local fullFx = Runtime.call("ui.options.rows", function(_, r) return r end, + fxGame, { { id = "tilt" }, { id = "gbcfx" } }) +T.eq(#fullFx, 0, "under FULL they are gone too -- its early return is below them") +Pipelines.setLevel("voxel", 2) +end + -- ------- and off FULL, the rows come back, grouped with the mode -- -- The engine splices a pipeline row in beside TILT and lands a mod's own