Skip to content
This repository was archived by the owner on Sep 20, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ Settings-dock rows themselves are data: every cycling or boolean row is a `Cycli

`TooltipPreviewModePolicy` owns preview priority. Upgrade hotkey wins first, then enchant hotkey, then enchant `Always`, then enchant `AutoOnPedestalChoice` only when the current choice pedestal is an enchant pedestal (`src/BazaarPlusPlus/Game/Tooltips/TooltipPreviewModePolicy.cs:52-74`). A `TooltipModifierRefreshController` mountable re-resolves open preview tooltips when the Ctrl/Shift hold state changes; both ordinary game cards and hovered synthetic previews keep the existing native tooltip controller alive, replace its `CardTooltipData` through `ApplyPreviewTooltip`, and synchronously settle layout behind a temporary visibility gate instead of replaying native hide/show positioning and fades (`src/BazaarPlusPlus/Game/Tooltips/TooltipModifierRefreshController.cs:110-173`, `src/BazaarPlusPlus/Game/Tooltips/TooltipPreviewContentRefresh.cs:12-65`, `src/BazaarPlusPlus/GameInterop/Tooltips/NativeCardTooltipContentRefresher.cs:12-52`). The tooltip patch surface also covers encounter/event tooltips (gated by the `Game/EventPreview` settings toggle), quest reward previews and aggregate-item missing types (separate implementations sharing the default-off `QuestPreview/Enabled` gate), and hero level rewards (`src/BazaarPlusPlus/Patches/Tooltips/`). Disabling Quest Preview immediately restores tracked native quest text/layout and hides its pooled aggregate-item sections. Mod-appended text is rendered through the shared `BppTooltipSections` helper. Sections keep the cloned native donor typography and attach the game's own zh-CN fallback chain only when BPP-authored content contains CJK (`src/BazaarPlusPlus/Patches/Tooltips/BppTooltipSections.cs:12-15`, `src/BazaarPlusPlus/Patches/Tooltips/BppTooltipSections.cs:55-76`).

`GameInterop/Tooltips` holds two unrelated native-tooltip adapters that must not be merged. `NativeCardTooltipContentRefresher` replaces the `CardTooltipData` of an already-visible primary tooltip and settles its layout (`src/BazaarPlusPlus/GameInterop/Tooltips/NativeCardTooltipContentRefresher.cs:12-52`). `NativePairedTooltipHost` owns the separate "custom content inside the native auxiliary tooltip, pinned beside the native card tooltip" presentation: native state capture/restore, the `CanvasGroupGate` visibility gates, the cloned native background, the paired fade, side selection, and coordinate conversion (`src/BazaarPlusPlus/GameInterop/Tooltips/NativePairedTooltipHost.cs`). Composition creates one plugin-lifetime host; it is not `IDisposable`, and the releasable unit is the `NativePairedTooltipSession` a feature acquires from it (`src/BazaarPlusPlus/BppComposition.cs:237-252`). The host reports placement outcomes through `PlacementResult` and never logs: reason codes, their once-only latches, and native show/hide arbitration stay with the consuming feature, because that latch behavior decides how many records reach the log. The host also does not arbitrate the native auxiliary singleton — other code drives it directly (`src/BazaarPlusPlus/Game/CombatReplay/CurrentReplayRecordingButtonController.cs:257-261`), so a single active session serializes only this host's own usage. Purely geometric decisions are the unit-tested `NativePairedTooltipPlacementMath`; the shared `NativePairedTooltipMetrics.Epsilon` deliberately serves both as a geometry tolerance and as the CanvasGroup alpha interactivity threshold. Combat Impact is currently the only consumer, and it supplies its own trim strategy through `IPairedContentBudget` (`src/BazaarPlusPlus/Patches/PostCombatImpact/NativePostCombatImpactTooltipView.cs`). `NativePairedTooltipArchitectureTests` ratchets the plumbing into this module.

BPP hotkeys are user-rebindable and persisted in config per action. `BppHotkeyActionId` covers five actions: the two hold-preview hotkeys (Ctrl enchant / Shift upgrade defaults) plus toggles for CollectionPanel, LiveBuildPanel, and HistoryPanel (`src/BazaarPlusPlus/Game/Input/BppHotkeyActionId.cs`); rebinding rows are cloned from native settings rows (`src/BazaarPlusPlus/Game/Input/BppKeyBindRowController.cs`), and panel toggle presses are resolved per frame by the Overlay Panel Host. Binding-path normalization, ctrl/shift alias expansion, conflict detection, and the default/display data tables are the pure `HotkeyBindingPathCore` (`src/BazaarPlusPlus/Game/Input/HotkeyBindingPathCore.cs`, compile-linked into the zero-ManagedPath `tests/HotkeyBindingPath.Tests/`); `BppHotkeyService` remains the Unity/config facade. Binding paths in `BazaarPlusPlus.cfg` `[Hotkeys]` are untrusted input: junk normalizes to empty and falls back to the action default. The conflict check compares BPP actions only against other BPP actions, not native `Gameplay/*` bindings.

The settings dock registers all feature rows through `SettingsDockEntryRegistry` with order constants centralized in `BppSettingsDockOrder` (`src/BazaarPlusPlus/Game/Settings/BppSettingsDockOrder.cs`); the roster spans history, name override, bilingual item names, legendary position, enchant preview, event and quest previews, combat status bar, Chinese locale, supporter list, voice subtitles, end-of-run screenshot, and BazaarDB upload (`src/BazaarPlusPlus/BppComposition.cs:162-180`). There is no BPP font selector because all BPP-owned game UI follows the game's font assets.
Expand Down
Loading