Arts with launch type 2 (buffs, auras, heals) are only valid on allies
or without a target; with an enemy under the cursor the game dropped
the order. Orders of a player hero for such arts lose a non-ally target,
which casts them on the hero. The launch type comes from the art
definition tables (game/engine/arts.h, tools/arttable.mjs).
Also: skill keys check the relocated taskbar slots (all 7), Ghidra
data labels (g_ names in names.txt).
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>
A digit that selects a combat-art slot now also presses the right mouse
button (posted WM_RBUTTONDOWN, released with the key), so the game casts
the art at the cursor like a right-click. SwapDigits trades the digit
rows; the key rewrite shares the WASD remap in the engine/UI receivers.
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>
New mods/hud: while a HUD window renders, screen-space vertices passed to
D3D7 DrawPrimitive/DrawIndexedPrimitive are shifted by dx; while it handles
an event, the UI event point (category 5, +0x48) is shifted by -dx. Applied
to cUI_Taskbar2 (centred) and cUI_Mercenary (portrait + health, right edge).
3D belt items line up without help (their projection is screen-centred).
re::AttachRuntimeHook hooks functions only known at runtime (COM methods).
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>
- 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>