diff --git a/AccessibilityMod/Patches/DialoguePatches.cs b/AccessibilityMod/Patches/DialoguePatches.cs index acfa4e2..4fda0c6 100644 --- a/AccessibilityMod/Patches/DialoguePatches.cs +++ b/AccessibilityMod/Patches/DialoguePatches.cs @@ -172,6 +172,36 @@ private static bool IsWaitingForInput() #region Message Board Hooks + /// + /// Hook when message board is about to close. Captures dialogue that might be + /// missed by other hooks (e.g., when dialogue advances quickly without showing + /// the arrow or guide icons). + /// Skips when in court record/evidence details modes to prevent stale dialogue. + /// + [HarmonyPrefix] + [HarmonyPatch(typeof(messageBoardCtrl), "board")] + public static void Board_Prefix(messageBoardCtrl __instance, bool in_board, bool in_mes) + { + try + { + // Only capture when board is about to close while still active + if (!in_board && __instance.body_active) + { + // Skip when message board text is stale (court record, evidence details, 3D evidence) + if (IsInStaleDialogueMode()) + return; + + TryOutputDialogue("Board_Prefix"); + } + } + catch (Exception ex) + { + AccessibilityMod.Core.AccessibilityMod.Logger?.Error( + $"Error in Board_Prefix patch: {ex.Message}" + ); + } + } + /// /// Hook when message board opens/closes. Reset speaker tracking when closed. /// Note: We intentionally do NOT reset _lastAnnouncedText here because the board @@ -472,6 +502,33 @@ private static void TryOutputDialogue(string source = "unknown") return; } + // Check if this is a continuation of previously announced text + // This happens when animations pause mid-sentence: we announce the partial, + // then when the full line is ready, we only announce the new part + if ( + !Net35Extensions.IsNullOrWhiteSpace(_lastAnnouncedText) + && text.StartsWith(_lastAnnouncedText) + ) + { + string continuation = text.Substring(_lastAnnouncedText.Length).TrimStart(); + _lastAnnouncedText = text; + + if (!Net35Extensions.IsNullOrWhiteSpace(continuation)) + { + // Replace button placeholders in continuation + continuation = ReplaceButtonPlaceholders(ctrl, continuation); + +#if DEBUG + AccessibilityMod.Core.AccessibilityMod.Logger?.Msg( + $"[DialoguePatches:{source}] Continuation: \"{continuation}\"" + ); +#endif + // Output just the continuation (no speaker name - same speaker continues) + SpeechManager.Output("", continuation, GameTextType.Dialogue); + } + return; + } + _lastAnnouncedText = text; // Replace button placeholders with actual key names