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>
- 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>
- Quest dialogs are tooltips. A tooltip now keeps the offset it gets when it
becomes visible (the hovered window's, or centred for dialogs) and records
it for hit tests; its own event handler is shifted too. Hidden windows no
longer count as hovered.
- Esc closes a visible dialog the way its answer buttons do: hide, then
cDialogManager::Answer with no answer (ends the input lock, nothing chosen).
- Autotest can select a save game row (-Save).
- Names for the UI manager, tooltip and dialog functions.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Skill bar: no art selection; slot 0 is the right-click art, keys 0-6 cast
slots directly; cooldown labels in exact seconds; slot 0 set apart.
- Arts regenerate on their own (casting no longer refills the group).
- Auto-attack after targeting or casting at a hostile creature, at the speed
of a held button.
- Auras can be recast while active (renew, no second visual).
- Blicke wie Klingen hits every enemy in range, physical, with life leech.
- Blitzschlag steers the game's own chain: 3 + level/5 hits, 1 + level/10
chains, re-hits a lone enemy.
- Weapon sets: click selects, drag only from the selected set; the leftmost
set is clickable (signed hit tests).
- Esc closes open windows before opening the game menu.
- HUD: standalone buttons and texts are centred.
- Record cache sized for widened views (town lag while walking).
- Shared game code: orders, fx events, text drawing, cooldowns, effects.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Saving marks effect objects dead, so after a load the Heldenmut /
Klingenblick buff was active but its aura effect (cObjectFX 842) was
gone. A few ticks after a save game has loaded, the effect is created
again for each such buff of a player hero (CreateAt + cEventFX 0x42,
as the art's cast effect does), with the buff's remaining time.
Shared game events (game/engine/events): engine tick and "save game
loaded" callbacks; the WASD mod uses the tick through it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
cUI_Taskbar2's slot arrays move behind the (enlarged) object with room
for 7 each; all instructions addressing them, the relative accesses
between the two arrays, the slot loops and the count clamp are patched
from tables in game/addresses.h (belt loops untouched). Slots 6 / 7
unlock at levels 45 / 65; AssignArtToSlot accepts slots up to 6. Slot
keys call the taskbar's selection directly (honouring COMBINE_SLOTS).
Shared code: re::PatchAll / PatchInstructionByte for patch tables,
game/engine/objects.h for object, RTTI and kernel calls, slot-hook
templates in skillslots.cpp.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Weapon sets and combat-art slots 6-7 live in a shadow inventory per
inventory; the slot methods run the original code on it for slots >= 5,
so item references, icon resources and selection events stay the
game's own. Save games (cInventoryManager::Serialize) and hero files
(saveHero / loadHero) store inventories as JSON ("SRIJ" + length);
vanilla blocks are still read, which migrates old saves. Multiplayer
transfers keep the binary format. nlohmann/json fetched via git.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Raw WM_KEYDOWN/WM_KEYUP are handled in both window procedures (the game
swaps 0x8110d0 and 0x8122a0 with SetWindowLong; 0x8110d0 is the in-game
one). Bound keys are swallowed and post the original hotkey's key event
to the kernel, so F-keys work and bindings are layout independent
([keys] in sacred_re.ini). Replaces the WASD hotkey remap and the digit
swap; W/A/S/D and the digit row no longer reach the game. Skill keys
still cast through the right mouse button. Enabled switches removed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
While W/A/S/D are held, the controlled creature gets a plain walk order every
engine tick toward its position plus the pressed screen direction, as the
mouse does while its button is held (every mouse event re-sends a walk to the
cursor point); releasing sends the target-less stop order of a released mouse
button. W/A/S/D key events are swallowed before the hotkeys see them; their
old actions move to G (action slot 3), V (pick up nearby) and K (save game
window) for now, configurable in [wasd].
docs/wasd.md: order format, measured mouse behaviour, hotkey map.
docs/todo.md: better pathfinder; final bindings for the moved hotkeys.
re::ConfigString for string settings.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Primitives covering the whole 1024x768 layout inside a moved window, such as
the dimming behind the exit confirmation, were shifted with the window and
left both sides undimmed; they are stretched to the render width instead.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Creatures were culled beyond 1024+200 x 768+200 screen pixels (cmp 4C8h /
3C8h in both object passes): invisible in the right part of a wide view,
and the player too once the centre passed 1224. The bounds follow the
render size now.
- Centre immediates written as negatives (-200h / -180h), missed before:
the row renderer's static object origin (0x62babb) and aiming at the
cursor (0x4fb620).
- HUD: moved windows no longer shift the shared mouse cursor object; the
cursor accessor (0x6550f0) hands them a per-thread shifted copy and writes
back what they changed. World input on other threads read the shifted
position now and then, which made hold-to-move jerky.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The default render size (1835x768) is below Direct3D 7's 2048 limit, so the
D3D7 -> D3D9 wrapper and its device-info workaround are no longer needed.
The game pauses start-up until its window is active; game-input.ps1 now
activates it reliably (Alt + SetForegroundWindow, polled), which dxwrapper
had masked. borderless logs the first failed presents.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Default render size is 768 high and as wide as the monitor aspect
(1835x768 on 3440x1440), scaled up: everything keeps the size players
know and the view only grows sideways. Height=0 keeps native 1:1.
- Ground: 818/888 clip limits, screen centre floats and integer
immediates, ground quad list (capped at 1749) moved with the tile list.
- 3D: cGranny ortho (+-512 x +-384, incl. HUD items) scaled; inverse
projection 0x623a20 (1/1024, 1/768) follows the render size, which fixes
the camera following the player ("outside world") and the missing
player / ESC menu.
- tools: game-input.ps1 + autotest-load.ps1 drive the game (load the first
save game, screenshots in-game and with the ESC menu).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- mods/widescreen: redirect the world view's reads of the 1024.0/768.0
constants and the 3D ortho extents to our variables; render size =
monitor; relocate the world view's tile draw list (1750 entries, no
bounds check) into an enlarged object (16384 entries).
- mods/dxwrapper: route DirectDraw through dxwrapper (Dd7to9, D3D9) since
Windows' D3D7 cannot render to targets larger than 2048; fix the game's
device info GUID pointer that dxwrapper's enumeration leaves invalid.
Pinned release fetched by CMake (hash-checked), installed next to the DLL.
- Main menu (UI thread) and loading screen render in a 1024x768 viewport
and are presented scaled ("classic" layout); in-game uses the full size.
- re/patch: verified code patches (operand redirect, push immediates,
displacements) and startup hooks; build.ps1/CMake download fixes.
In-game view untested yet; HUD still at the top-left.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Launcher (sacred_re.exe) starts sacred.exe with sacred_re.dll injected
via Detours; the DLL verifies the Sacred Gold 2.28 build before hooking.
- Hook framework: RE_HOOK for game addresses, RE_HOOK_API for Windows
APIs, per-hook enable/disable in sacred_re.ini, sacred_re.log.
- Game code: Log (0x66f1c0) hooked, CmdLineHasFlag (0x813140) rewritten.
- Borderless mod: forces windowed mode, covers the monitor, scales the
1024x768 image aspect-correct, remaps mouse input, keeps running in the
background with keyboard input hidden while unfocused.
- CMake/Ninja/MSVC x86 build, VS Code setup, disasm tool, function map.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>