Eingraben becomes ground-targeted; after its own case the dwarf moves to
the end of Phasenverschiebung's walk towards the point (stops before walls
and cliffs). The barrier's bonus lasts 3 s and its lock in place
(effect kind 0x3a) is dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AddMainQuestItem refused every new main quest item once the list held an
entry with script id 0 (scripts give such items); the Goldbeeren of quest
402 were picked up and lost. The script id test is patched out.
Quest variables are bit fields (op 0x44 sets a bit): the quest giver
restart now writes the values directly, 0 and 1 (available) for the
variable named after the quest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A follower that fell more than 40 cells behind was removed when its sector
was switched off, and the game ran its death label (the husband of "Die
Sklaven der Orks"). Every 500 ms followers of the local hero that far away
are teleported to him with cCreature::Teleport.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mörsergranate's explosion crashed twice reading the colour of a particle
with a huge life (sacred.exe+0x361b54). Particles with life >= 256 or the
unset fourth row are switched off before drawing; logged cases were all
row 3 with garbage sizes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The landing point is noted from the grenade's cEventFX 0x96 at launch; a
translucent red circle with the explosion radius (shared ImpactRadius) is
drawn after the world's ground, under the objects, and ends when that
grenade's impact gathers its targets. Ground -> screen projection in
game/engine/worldview.h.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The game drew 2x2 px red dots per visited-sector neighbour (0x6c8580), in
64-tile steps and unrelated to the explored mask. Replaced by lines traced
from the explored cells (2x2 tiles), simplified to 0.75 px, rebuilt while
the map is open when the masks change.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Escorts lost their place on the hero's follower list after a load, so
quest checks like the one in "Furchtbares Verbrechen" failed; they are
added back once after loading (town NPCs that tag along briefly are left
out). Restarted quests stay available (flag 1), which their giver's dialog
and accepting them need. Quest givers are read from the quest scripts:
when a running quest's giver dies, the quest restarts and the giver is
spawned again at her start; an accepted quest without its giver is repaired
on load. Notes on the script format and opcodes in docs/quests.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Kanonenschuss: the stun no longer plays the hit motion or pushes the
target; stunned creatures stand still for 1.5 s. The impact effect only
shows on targets that did not resist, and the ray reaches 1800 for the
wider view. Mörsergranate: the impact radius grows by a tenth of its size
every 5 skill levels. Art levels come from a shared helper.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Quest items are recognized by the type's quest number or the scripts'
QuestItem / MainQuestItem marks, checked before the other categories.
Their row in the Beute tab has no Löschen box; Void in the ini reads as
Default.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A dialog's quest comes from the game's script labels ("Dialog:<name>",
quest at +0x48). When that quest is done and not in progress, IsQuestNpc
answers false (blue on the minimap) and the idle action's type check
skips the turn towards the hero.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Internet-Optionen frame becomes Bildschirm with a Monitor dropdown
(Hauptmonitor or a connected monitor, kept by device path in
[display] Monitor=). The borderless window and the render size use that
monitor, falling back to the main monitor when it is not connected.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The zoom button never set the zoom point, so it zoomed on the last
magnifier point (or 0,0). While the button's zoom is on, the point is put on
the hero's map pixel every engine tick; the held mouse button still zooms on
the mouse. game::UiWindow / UiWindowShown shared from windows.h.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The game's list builder runs on a reordered copy of the book: the story, then
one section per region (id blocks of 100 grouped by the region their quests
lie in, named as the megamap names regions), unknown quests as "???", the
rest joined to the nearest area, undiscovered counts. Act tabs hidden, page
turning kept. "Erledigte anzeigen" row toggles completed quests
([questbook] ShowCompleted).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
All mirror checks are skipped by code patches (the game's own "not the local
hero" paths, or straight past the check), the level trap in Think and
VerifyHeroMirror are off, the cheater flag is never set (stream checks,
loadHero, character selection). The VirtualProtect mirror refresh is gone; it
never refreshed the second mirror, a separate heap block, which killed the
hero again.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Megamap / TAB map zoomed view: heroes' markers and the other symbols
(integer 200h centre immediates) follow the view's centre.
- Map reveal: the hero's reveal stamp scaled 10x (mods/mapreveal.cpp,
docs/map-reveal.md); creatures on the zoomed map shown within 10x the
sight range.
- Load / save progress screen drawn on the rock background across the full
width, the picture blended over it (mods/loadingscreen.cpp); the classic
1024x768 frame is gone.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A failed quest gets its flags cleared and its quest book entries removed
after its failure script ran, so the quest giver can offer it again; quests
failed before the mod are reset once after loading. Quest table and quest
book in game/engine/quests.h, measurements in docs/quests.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The game's cheater detection killed the hero ("Hase!") whenever its
protected stat mirror was stale; the mirror is now refreshed from the hero
whenever it is unlocked, stream checks never punish, loadHero no longer
sets the cheater flag (docs/anticheat.md).
- saveHero wrote the items of weapon sets 1-5 only: its loop runs over all 7
sets, so sets 6-7 survive a world loading the hero from the hero file.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
In the Underworld the potion opens the Underworld portals (busy dialog mode
6, as the teleporters there do); g_campaign moved to game/addresses.h.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Shared chest: emptied and not saved from the moment a save game is read
until it reloads; a hero saved inside a load wrote the new world's
objects (stale ids) as the chest's items.
- Main menu after a game: shown 16:9 screens are tracked on the menu thread
only and expire after 2 frames; a destroyed in-game window kept the menu
unframed (old pictures, frame at the left).
- Dialogs over a 16:9 screen in the main menu are centred, their dimming
covers the screen.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The hidden-texture list stayed active in a game; a game texture made at the
address of a freed menu picture was skipped (rendering glitches in-game).
Hiding now applies only while the main menu's frame or the in-game options
draw over the menu background.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Spielen hero panel shows the selected hero in 3D (cUI_NetGranny,
game/ui/granny.h).
- All menu screens draw on the options' rock wall; the main menu's 1024
frame is drawn centred over it, mouse and cursor shifted to match.
- The main menu's and options' own pictures and the main menu's 3D scene
are left out (textures hidden by surface, scene call redirected).
- Logo top left: FX_SACREDLOGO.TGA, drawn added.
- Game textures by name (game/ui/texture.h), textured and added quads.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- 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>
- Esc menu: "Exportieren" became "Laden"; it opens the load window, always
in load mode. In a game every world loads (the current one reloads); a
"(neu)" world stops the game (cCommand_armaStop) and starts the new one
without the main menu. The character being played cannot be deleted.
- Silent autosave every sacredK.ini [characters] AutosaveMinutes (default
10, 0 = off) into the character's autosave file.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
"Zuruecksetzen" in the load window lists the selected character's worlds
and asks for confirmation. The world goes (a copy in characters\deleted),
with an autosave of it, and the shared hero's story completion of that
difficulty is cleared. The dialog is one generic list (title + entries).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- cUI_EscMenu::BuildLines hook: the UI_ESC_EXPORT line is removed, the
lines below move up, the window shrinks by one line, centred.
- game/ui/control.h: control vector helpers (ControlsIn, RemoveControl,
SetControlAt, DeleteControl, ControlNamed), used by the main menu too.
- The export screen is unreachable now: charexport.cpp and
docs/char-export.md deleted. Spielen screen redesign noted in todo.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- One world per campaign and difficulty in a character file (sections
ancaria<d> / underworld<d>; old world<d> renamed when read). Difficulty
unlocks by the shared hero's story completions (hero header +0xed..),
shared by both campaigns.
- Main menu: "Kampagne Ancaria", "Kampagne Underworld" and "Spielstaende"
become "Spielen" (mods/mainmenu.cpp). The load window lists all
characters, the world dialog offers both campaigns, "Neuer Charakter"
asks for the campaign and opens character creation.
- Character window: no Underworld import mode (new Underworld heroes, all
classes, slots light up), no "Importieren"; load window without
"Speichern".
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- CharacterNN.sacredK holds the shared hero and one world per difficulty,
plus an autosave file; the game works in save\characters\_work
- Load window: one row per character, a difficulty dialog on Laden
(worlds, newer autosaves, "(neu)" starts a new game with the shared
hero), Umbenennen, delete moves the character to characters\deleted
- The world keeps its own portals and hero position when the shared hero
is put on
- K and the Esc menu's "Speichern" save directly (quicksave path)
- One-time migration of the old save rows and exported heroes, after a
backup
- Startup no longer hangs in the game's foreground loop (0x810af0)
- Text overrides apply to our own text ids too; shared cUI_Button2
helpers in game/ui/button.h
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The game's ANSI file API calls are hooked; paths under save\ and
Settings.cfg are redirected to Documents\Sacred\save and
Documents\Sacred\config, copied there once from the game folder.
The shared chest uses the same save folder.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Per category (Gold, Tränke, white/blue/yellow/brown/green items) one of
Löschen (loot deleted at once), Ignorieren (pickup key leaves it), Standard,
Immer anzeigen (label without the labels key). Replaces the game's
PICKUPAUTO choice; settings in [loot] of sacredK.ini. docs/loot-filter.md.
Also ignore MSYS *.stackdump files.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
sacred_re.dll/.exe/.ini/.log/_crash files are now sacredK.*; inventory saves
with the old "sacred_re.inventory" format id still load.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Options window in three tabs; the auto-pickup settings move to Beute;
sliders move with their page; black sides like the save game screen.
- Tastenbelegung: every binding settable (click, press key; Esc cancels,
Backspace unbinds), "Alle zurücksetzen" as a game button, saved on OK.
- Potions bindable (default unbound), named by the game's potion texts; the
game's own potion hotkeys are off; bar tooltips show the bound key.
- Map (M), overview map (Tab, held) and labels (Alt, held) bindable; the
game's own M / Tab / Alt handling is switched off.
- Save game key calls the game's save window code instead of a posted key.
- Teleportationstrank: fixed text replacement from startup (also the
Ausdauertrank items, potion kind 5 as well).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- cUI_Character (export) and cUI_Savegame draw inside the centred 1024x768
frame (viewport) with the render target beside it cleared black; the
export screen's 3D heroes were stretched across the wide viewport, away
from their labels and hit areas.
- Export screen shows the game's erase button for an occupied slot and
reloads the heroes after a delete. Overwriting was already the game's
own path once clicks hit the right slot.
- game/ui/control.h: shared show/hide for cUI_Control2.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Arts are objects (game::Art) built from the game's definitions: name,
launch type, damage source, regeneration group and the skills' art lists.
The tooltip gets one line per effect of a skill or attribute, sorted by
size; unlearned class skills are greyed out at 0%. Weapon arts list only
the damage types the held weapon deals and the held weapon's skill.
Tooltip line wrap ignores colour codes; art tooltips wrap wider.
Blitzschlag's tooltip rewrite becomes a tooltip filter.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The chains of a cast share the enemies they have claimed and prefer
unclaimed ones. Each chain keeps its heading and ranks candidates by
distance and turn; a chain's first jump turns away from the directions
the other chains set out in, so they keep fanning out. Jumps reach 75 %
of the cast range.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The keys rewrite the hero's path every cCreature::Update: one segment
along the held direction, the facing set to it, sliding along blocked
cells. Starting from idle runs the game's own Think steps at once
(StartPendingWalk, WalkAction) instead of waiting up to 110 ms, so
weapon switches no longer stop the walk. Stops wait 50 ms after the
keys are released, and a stop in progress is taken back when keys are
held again. Names for movement, stats and text-key functions.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Switching between weapon classes resets the hero's animation state inside
cUI_Taskbar2::SelectWeaponSet, which dropped the walk for a tick. The hook
sends the WASD walk again at once. Checkpoint before the movement rework.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The shot end's button check (0x4def52) answers "held" for the auto-attack
target, like the melee swing end.
- An art order counts as started when the art's cooldown rises, so bow arts
and arts ordered mid-swing hand over to auto-attack.
- re/crash.cpp: a watchdog writes sacred_re_hang.dmp when the engine tick
stops for 10 s while the game is in front.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Character creation and the save window were not detected (the UI manager's
dialog slot held a hidden busy dialog); bound keys were swallowed or posted
their hotkey into the field. A text field now counts while it is the focused
edit control and was drawn in the last 250 ms.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The zoomed map view resets the viewport to the full render size when done;
the HUD layer shifted that reset past the render target, SetViewport failed
and the map's 256x256 viewport stayed set, clipping the cursor. Full-width
viewports at x 0 are no longer shifted.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Every yellow potion (potion kind 5, all stages) is a Teleportationstrank:
drinking it posts the teleporter's event to the busy dialog with the
hero's known portals; the potion is used up only when the hero teleports
from that window (closing it keeps the potion)
- Names replaced in every game text (ReplaceInTexts), so item names and the
bottom bar's quick-select tooltip read Teleportationstrank; GameText reads
the game's own text
- HeroIndex / HeroInventory moved to skillslots for shared use
- docs/teleport-potion.md; walking animation after loading noted in todo
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Shared chest: tabs "Truhe"/"Gemeinsam" as a column left of the grid
(game tab sheet), grids placed every tick, persistent across heroes
- Inventory tab texts capitalized (RegisterText / CapitalizeText)
- Combat-art runes stack like potions (itemstack, renamed from potionstack)
- Rune master: any rune for any number of runes, price by rune count
(4 runes = 1,000, x10 per missing rune), bought rune goes into the
backpack, Buy disabled without runes, gold or room, last rune remembered
per hero (saved), the chosen rune's name below its icon, dropping a
stack gives up one rune
- Keys: the old key handling no longer takes over after the save screen
(text field focus only counts while its dialog is shown)
- Esc crash: tooltips forgotten when the game destroys them
- Pick up (Q) sends the pickup order directly; search reach doubled
- Kettenblitz: tooltip shows hits per chain, chains, cast and jump range;
cast range 900 (longer ray segments), jumps half of that
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The chest is inventory 0x11 and already saved as JSON; stacking now applies
to all inventories below 0x12. Traders keep selling single potions.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- potioncounts.cpp: each potion slot shows how many potions of its kind the
hero carries (stacks added up)
- potionstack.cpp: potions of one type stack up to 20 per cell; every
potion entering the hero's grid pours into stacks with room, the sort
button stacks first, drinking takes one off a stack, counts drawn on the
cells and saved in the JSON inventories
- game/engine/items.h: potion kinds and grid helpers; ObjectManager and
DestroyObject in objects.h
- auto-attack: the projectile-weapon target radius is a design value
- docs/potion-stacks.md: measured paths and the design
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- autoattack: when the target dies, the nearest enemy within close range
(contact distance + a step) takes over; after an art the hero auto-attacks
if the art was melee (walked up / cast close by), or ranged with a ranged
weapon, or ranged with an enemy already in melee range; measured action
codes and weapon classes in game/engine/orders.h
- chainlightning: jumps reach Blitzschlag's cast range (20 ray segments of
30, the art code's hit check) via the shared NearestHostile search
- guards: burning bone render hook had the wrong signature (device plus a
4x4 matrix by value, ret 0x44) and corrupted the stack when fire arrows hit
- crash reports follow the ebp chain before the raw stack scan
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- re/crash: unhandled exceptions write sacred_re_crash.txt (module+offset,
registers, return addresses on the stack) and a minidump; the game's own
filter is chained behind ours
- guards: cParticleSystem_burningBone::Render (0x774e10) skips drawing when
given a null device (crash at sacred.exe+0x374e39 after Esc while walking)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- megamap: the zoomed view (0x6cc950) is shared by the large map and the
TAB overview map; its centre is now set per call from the drawing
window's offset (hud::DrawOffsetX) instead of fixed to the render width
- input: drop the Ctrl/Alt pass-through; GetKeyState reports Alt as held
after Alt+Tab, which switched all bindings back to the game's handling
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- respec: the panel's unused second button array becomes − buttons between
name and value; attributes give back invested points, skills give back
skill points, a level-1 skill is removed and can be chosen anew; all
through the game's own point functions (protected copy stays in sync)
- the − is the + icon with its vertical arm covered (no minus image exists)
- hud: RenderCentred / HandleCentred for mods hooking centred windows;
mouse event helpers shared in game/ui/events.h
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- hud: shift SetViewport/Clear with moved windows (TAB overview map)
- megamap: view constants patched to the render width (clip, scroll limit,
edge scrolling, centre, dark band, zoomed view and its markers); frame
stretched to the screen edges, zoom controls and their click area centred
- hud: Anchor::Screen windows are drawn and clicked unshifted but still own
the event scope
- autotest waits for log markers instead of fixed delays (~18 s per run)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>