Character panel: minus buttons take back attribute and skill points

- 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>
This commit is contained in:
khallaandClaude Opus 5.5 committed 2026-10-16 01:44:20 +02:00
1 parent c6c5530709
commit 037fc73158
7 files changed
+413 -14

No files matched your search

+19 -14
View File
@@ -29,6 +29,7 @@
#include "game/addresses.h"
#include "game/render/dx_driver7.h"
#include "game/ui/events.h"
#include "mods/widescreen.h"
#include "re/config.h"
#include "re/hook.h"
@@ -262,22 +263,17 @@ private:
CursorOffset cursor_;
};
// Mouse events, by vf04 category (positions in render pixels):
// 1 cEvent_mouseMove: previous x, y at +4 / +8, current at +0xc / +0x10
// 2 cEvent_mouseButton_down,
// 3 cEvent_mouseButton_up: x, y at +8 / +0xc
// Stores the offsets of the x fields; returns their count (0: no mouse event).
// Stores the offsets of a mouse event's x fields (game/ui/events.h); returns
// their count (0: no mouse event).
int MouseEventXOffsets(void* event, int (&offsets)[2]) {
using CategoryFn = int(__fastcall*)(void* self, void* edx);
auto category = reinterpret_cast<CategoryFn>((*static_cast<void***>(event))[1]);
switch (category(event, nullptr)) {
case 1:
switch (game::MouseEventKind(event)) {
case game::MouseEvent::Move:
offsets[0] = 0x4;
offsets[1] = 0xc;
return 2;
case 2:
case 3:
offsets[0] = 0x8;
case game::MouseEvent::ButtonDown:
case game::MouseEvent::ButtonUp:
offsets[0] = game::kMouseButtonX;
return 1;
default:
return 0;
@@ -574,8 +570,7 @@ HUD_EVENT(0x00726880, UiWindow_HandleEvent, Anchor::Center) // cUI_Window2 (sha
HUD_RENDER(0x00727040, UiWindow_Render, Anchor::Center) // cUI_Window2 (shared)
HUD_EVENT(0x006a4140, UiBlacksmith_HandleEvent, Anchor::Center)
HUD_RENDER3(0x006a3160, UiBlacksmith_Render, Anchor::Center)
HUD_EVENT(0x006a5dd0, UiStatisticsChar_HandleEvent, Anchor::Center)
HUD_RENDER(0x006a9be0, UiStatisticsChar_Render, Anchor::Center)
// cUI_StatisticsChar (0x6a5dd0 / 0x6a9be0): hooked by mods/respec.cpp.
HUD_EVENT(0x006acc70, UiChest_HandleEvent, Anchor::Center)
HUD_RENDER(0x006ac8b0, UiChest_Render, Anchor::Center)
HUD_EVENT(0x006adc70, UiConsole_HandleEvent, Anchor::Center)
@@ -688,6 +683,16 @@ int VisibleDialogTooltips(void** out, int max) {
return VisibleDialogTooltipsImpl(out, max);
}
int RenderCentred(void* window, int (*body)(void* context), void* context) {
DrawOffset offset(window, OffsetFor(Anchor::Center));
return body(context);
}
int HandleCentred(void* event, int (*body)(void* context), void* context) {
EventOffset offset(event, OffsetFor(Anchor::Center));
return body(context);
}
} // namespace mods::hud
namespace game {