diff options
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index 0dce3a9..0cf996c 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -350,6 +350,13 @@ type LivingVillageGame() as this = let mutable p52Step = 0 let mutable p52PendingName = "" let mutable p52Pending = false + // P53 证据钩子:LV_P53_REC=1 时在真实世界里录制「远处 → 靠近提示出现 → 互动开对话 → + // 关闭+离开 → 提示消失」帧序列,逐帧打印面板/提示/目标/提示矩形,供 analyze 脚本 verdict。 + // 提示层为瞬时叠加,不新开面板。 + let p53RecordMode = Environment.GetEnvironmentVariable("LV_P53_REC") = "1" + let mutable p53Step = 0 + let mutable p53PendingName = "" + let mutable p53Pending = false let mutable autoplayFrames = 0 let mutable flowStep = 0 let mutable flowHold = 0 @@ -1191,6 +1198,80 @@ type LivingVillageGame() as this = bag p52Step <- p52Step + 1 + /// P53 证据:真实录制提示出现/消失序列(远处 → 靠近 → 互动 → 关闭+离开)。 + member private this.PrepareP53Recording () = + let setHour (hour: float) = + let tick = M6Presentation.resolveStartTick (Some hour) false + world <- { world with Tick = tick; Time = float tick * Sim.dtSeconds } + let placeAwayFromNpc () = + let npc = world.Npcs.[0] + world <- { world with Avatar = { world.Avatar with Pos = { X = npc.Pos.X + 240.0f; Y = npc.Pos.Y } } } + if not p53Pending then + match p53Step with + | 0 -> + setHour 12.0 + // 只保留 0 号村民作候选,其余移远,隔离出唯一的提示对象(真实 resolver 不改)。 + let npcs = Array.copy world.Npcs + for index in 1 .. npcs.Length - 1 do + npcs.[index] <- { npcs.[index] with Pos = { X = 4000.0f; Y = 4000.0f } } + world <- { world with Npcs = npcs } + placeAwayFromNpc () + m5View <- M5Interaction.refreshPrompt world m5View + this.CenterCamera() + p53PendingName <- "p53-far" + p53Pending <- true + | 1 -> + let npc = world.Npcs.[0] + world <- { world with Avatar = { world.Avatar with Pos = npc.Pos } } + m5View <- M5Interaction.refreshPrompt world m5View + this.CenterCamera() + p53PendingName <- "p53-prompt" + p53Pending <- true + | 2 -> + let nextWorld, nextView = M5Interaction.apply M5Command.Interact world m5View + world <- nextWorld + m5View <- nextView + p53PendingName <- "p53-dialog" + p53Pending <- true + | 3 -> + let closedWorld, closedView = M5Interaction.apply M5Command.ClosePanel world m5View + world <- closedWorld + m5View <- closedView + placeAwayFromNpc () + m5View <- M5Interaction.refreshPrompt world m5View + this.CenterCamera() + p53PendingName <- "p53-gone" + p53Pending <- true + | _ -> + printfn "p53-rec=done" + this.Exit() + + /// P53 证据:在 `Draw` 末尾落盘每帧,并打印面板/提示/目标/提示矩形。 + member private this.CaptureP53Recording () = + if p53Pending then + p53Pending <- false + System.IO.Directory.CreateDirectory recordDirectory |> ignore + this.SaveBackBuffer(sprintf "%s/%s.png" recordDirectory p53PendingName) + let targetText = + match InteractionResolver.resolve world m5View.HomeMode with + | Some target -> sprintf "%A" target.Action + | None -> "none" + let rectText = + match m5View.Prompt, m5View.PromptTargetPos with + | Some text, Some position -> + let viewport = this.GraphicsDevice.Viewport + let rect = + FloatingPrompt.layout viewport.Width viewport.Height position.X position.Y camera.X camera.Y 2 text + sprintf "%d,%d,%d,%d" rect.X rect.Y rect.Width rect.Height + | _ -> "none" + printfn "p53-rec=%s panel=%s prompt=%s target=%s rect=%s" + p53PendingName + (M5Interaction.panelName m5View) + (m5View.Prompt |> Option.defaultValue "none") + targetText + rectText + p53Step <- p53Step + 1 + /// P46 证据:菜单阶段按帧表把 menuEntranceFrame 钉到灯笼呼吸的波峰/波谷,拍两相位。 member private this.PrepareP46Shot () = if p46MenuADone && p46MenuBDone then @@ -1612,6 +1693,14 @@ type LivingVillageGame() as this = else this.DispatchMenuInput Confirm elif menu.Page = Playing then this.PrepareP52Shot() + elif p53RecordMode then + if menu.Page = MainMenu then + this.DispatchMenuInput Confirm + elif menu.Page = OccupationSelect then + if menu.Selected <> 0 then this.DispatchMenuInput Down + else this.DispatchMenuInput Confirm + elif menu.Page = Playing then + this.PrepareP53Recording() elif menu.Page = Playing then this.UpdatePlaying gameTime kb pressed pressedAny elif menuShotMode then @@ -2027,6 +2116,8 @@ type LivingVillageGame() as this = this.CaptureP47Shot() if p52ShotMode && menu.Page = Playing then this.CaptureP52Shot() + if p53RecordMode && menu.Page = Playing then + this.CaptureP53Recording() /// 启动画面:分层天色 + 屋脊/水面剪影 + 标题淡入上浮 + 跳过提示,全部为帧计数纯函数。 member private this.DrawSplash() = |
