Characters: 16:9 "Spielen" screen, autosave interval option
- Shared screen kit (mods/screen, docs/screens.md): a 1365x768 canvas centred in the render width on our own dark background, the game's frames and buttons; the main menu renders full width while it is shown. - The load window (cUI_Savegame) is replaced by the Spielen screen: character list, hero panel, campaign x difficulty grid, save/autosave choice, rename/delete/reset/new character dialogs. - Migrated characters without a shared hero load their hero's world first, then start the new world. - Options, Allgemein: autosave interval (Aus/5/10/15/30 minutes). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
732d9c2abb
commit
34a119433a
16 files changed
+1391
-468
No files matched your search
+52
-45
@@ -177,26 +177,55 @@ of both vectors, deleted) and UI_LABEL_LOADGAME ("Spielstände", shows
|
||||
UI_WND_SAVEGAME) moves to the top with the text "Spielen"; the others move up,
|
||||
keeping the gap before "Beenden".
|
||||
|
||||
### Load window (cUI_Savegame)
|
||||
### Spielen screen (cUI_Savegame)
|
||||
|
||||
Request 2026-10-20: redesign the load window, 16:9, using the space (layout
|
||||
agreed: characters left, the character in the middle, worlds right, buttons
|
||||
below; our own background). Built on the shared screen kit
|
||||
(docs/screens.md); the window's own drawing and mouse handling are not used.
|
||||
|
||||
- The window still scans: before each scan (0x71e330) one preview
|
||||
`GAMEnn.PAK` per character is written into `_work`; row nn = character nn.
|
||||
Its entries are only needed for the load.
|
||||
- Left: the characters, newest save first (name, class, level; "im Spiel" for
|
||||
the one being played). Click selects, double click plays.
|
||||
- Middle: name, class and level, the world played last with its date. (A
|
||||
render of the hero is planned.)
|
||||
- Right: a grid campaigns x difficulties. A cell shows the save's date,
|
||||
"+ Autosave" when the autosave is newer, "Story abgeschlossen", "Neu" for a
|
||||
difficulty that is open but has no world, "–" when closed. Open: Bronze and
|
||||
Silber, every difficulty up to the highest with a world in either campaign,
|
||||
and the one after each difficulty whose story the shared hero completed
|
||||
(hero header +0xed..); new worlds need the shared hero, not in multiplayer
|
||||
(byte 0x182cb6c). Click selects, double click plays. With a newer autosave
|
||||
"Laden von:" picks the save or the autosave (default: the autosave).
|
||||
"Welt zurücksetzen" for a saved world (not the character being played).
|
||||
- Buttons: Neuer Charakter (main menu only), Umbenennen, Löschen (not for the
|
||||
character being played), Zurück (action 0xc), Spielen.
|
||||
- Spielen: a saved world loads through the window's load action (4, with its
|
||||
"really load?" confirmation in a game): the window's selection is set to
|
||||
its first entry and `g_loadRow` names the row, which `Engine_Load` takes
|
||||
instead of the entry's. A new world starts a game (below; in a game after
|
||||
stopping the running one). The window's own load / default actions (Enter)
|
||||
run Spielen too; its delete actions (7, 8) are ignored.
|
||||
- Dialogs over the screen: rename (keys go to the field through the input
|
||||
key capture; the name is only in the hero header chunk 0xc3 (+8, UTF-16,
|
||||
0x40 chars): rewritten in the hero, every world and the autosave, plus
|
||||
`meta.name`), campaign of a new character, confirmations of reset and
|
||||
delete. Buttons are cUI_Button2 copies of the load button
|
||||
(`game::NewButtonLike`) with our own text ids and overrides.
|
||||
- Delete moves the character file and its autosave to `charactersdeleted`.
|
||||
- Neuer Charakter: sets `g_campaign`, hides the window and shows UI_CHARACTER
|
||||
(the game's character creation, as the main menu's campaign entries did).
|
||||
The first save makes the character file.
|
||||
- Reset (decided 2026-10-20) removes the world section (a copy goes to
|
||||
`charactersdeletedCharacterNN.sacredK.<section>.PAK`) and an autosave of
|
||||
that world, and clears the shared hero's story completion of that
|
||||
difficulty (hero header +0xed + d); the game counts it per difficulty, so
|
||||
the next difficulty closes in both campaigns unless a world keeps it open.
|
||||
|
||||
### Character window (cUI_Character)
|
||||
|
||||
- Before each scan (0x71e330) one preview `GAMEnn.PAK` per character is
|
||||
written into `_work` (header, thumbnail, world time, description
|
||||
"Name - Klasse"); row nn = character nn. The preview's campaign field is
|
||||
the running campaign, so the window lists every character. The row's
|
||||
second line (call 0x71db2a to SetText 0x736f00) shows
|
||||
"Stufe N - Campaign - difficulty".
|
||||
- Laden (action 4 / 0xb) opens the world dialog when there is more than one
|
||||
choice: per campaign worlds, newer autosaves "(Autosave)", and "(neu)" for
|
||||
every difficulty without a world up to the highest open one (needs the
|
||||
shared hero; not in multiplayer, byte 0x182cb6c). Open: Bronze and Silber,
|
||||
every difficulty up to the highest with a world in either campaign, and the
|
||||
one after each difficulty whose story the shared hero completed (hero
|
||||
header +0xed..). `g_campaign` is set to the chosen world's before loading
|
||||
or starting.
|
||||
- "Neuer Charakter" (two places below Löschen; main menu only) asks for the
|
||||
campaign, sets `g_campaign`, hides the window and shows UI_CHARACTER (the
|
||||
game's character creation, as the main menu's campaign entries did). The
|
||||
first save makes the character file.
|
||||
- Vanilla made no new heroes for the Underworld: `cUI_Character::Show`
|
||||
(vf24 0x70e2a0) switches to mode 7 in single player with `g_campaign` 1
|
||||
(0x70e3e8), the import of an exported hero of level 25+ (0x70eedc); with no
|
||||
@@ -209,30 +238,6 @@ keeping the gap before "Beenden".
|
||||
- Class selection without "Importieren" (request 2026-10-20): button +0x3a0
|
||||
(caption UI_IMPORT in modes 0/1); its modes-0/1 draw (0x70f67e) is removed,
|
||||
its click (0x70eab4 / 0x70eac7, SetMode(7)) jumps to the handler's end.
|
||||
- Load window without "Speichern" (request 2026-10-20; saving is direct):
|
||||
button +0x820 (action 1, disabled in load mode, so its click falls through)
|
||||
is not drawn (jump over 0x71ddbc); Löschen (+0x8dc) takes its rect, our
|
||||
buttons follow below it.
|
||||
- "Umbenennen" (below Löschen; not for the character being played) asks for
|
||||
a name; keys go to the field through the input key capture. The name is
|
||||
only in the hero header chunk 0xc3 (+8, UTF-16, 0x40 chars): rewritten in
|
||||
the hero, every world and the autosave, plus `meta.name`. Confirmed: the
|
||||
game loads renamed characters without complaint.
|
||||
- Dialog buttons are cUI_Button2 copies of the load button
|
||||
(`game::NewButtonLike`); their captions are our own text ids with
|
||||
overrides (texts.cpp checks overrides for our ids too).
|
||||
|
||||
- "Zurücksetzen" (below Umbenennen; a selected character with the shared
|
||||
hero and a world, not the one being played) lists the character's worlds,
|
||||
then asks "<Welt> zurücksetzen?". A reset (decided 2026-10-20) removes the
|
||||
world section (a copy goes to `charactersdeletedCharacterNN.sacredK.<section>.PAK`)
|
||||
and an autosave of that world, and clears the shared hero's story
|
||||
completion of that difficulty (hero header +0xed + d); the game counts it
|
||||
per difficulty, so the next difficulty closes in both campaigns unless a
|
||||
world keeps it open. The hero keeps everything else.
|
||||
- The dialog is one generic list: each kind fills a title and entries
|
||||
(FillDialog), "Abbrechen" last.
|
||||
|
||||
### Load
|
||||
|
||||
`cEngine::Load` (0x61b790) of a listed row: the chosen world and the hero are
|
||||
@@ -265,7 +270,8 @@ Silent autosave: 10 minutes after the last save of any kind (or the game's
|
||||
start), `SaveOnTick` does the direct save marked as an autosave, so it goes
|
||||
into the autosave file. While a window is open or a save runs it waits for
|
||||
the next tick. A character never saved yet gets its character file from it.
|
||||
Interval: `sacredK.ini` `[characters] AutosaveMinutes` (default 10, 0 off).
|
||||
Interval: options window, *Allgemein*, *Autosave (Min.)* (docs/options.md); kept in
|
||||
`sacredK.ini` `[characters] AutosaveMinutes` (default 10, 0 off).
|
||||
|
||||
Direct save (K key, Esc menu "Speichern"): on the next engine tick, as the
|
||||
quicksave does (0x618ebb): `cUI_Manager::CanOpenWindow` (0x75a690),
|
||||
@@ -299,5 +305,6 @@ kept, the newest file overall is the shared hero.
|
||||
|
||||
## Open
|
||||
|
||||
- Quickload (row 0) does not know characters.
|
||||
- Quickload (row 0) does not know characters (not needed, user 2026-10-20).
|
||||
- Spielen screen: a render of the hero; scrolling the list beyond 9 characters.
|
||||
- Multiplayer (see `todo.md`).
|
||||
Reference in new issue
Block a user