diff options
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index a0e6fc0..ba925f3 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -343,6 +343,12 @@ type LivingVillageGame() as this = let mutable p65Step = 0 let mutable p65PendingName = "" let mutable p65Pending = false + // P67 证据钩子(职业每日任务 UI 目标展示):农夫真实开局 → 找到当日「帮工」任务 → + // 拍带目标帧(帮工:… → 村民 N)与同模板无目标帧(帮工:…,文案与旧版逐字节一致)各一帧。 + let p67ShotMode = Environment.GetEnvironmentVariable("LV_P67_SHOT") = "1" + let mutable p67Step = 0 + let mutable p67PendingName = "" + let mutable p67Pending = false // P45 证据钩子:LV_P45_SHOT=1 时拍角色 idle / 行走朝下 / 行走朝右 三帧(真实游戏截图)。 let p45ShotMode = Environment.GetEnvironmentVariable("LV_P45_SHOT") = "1" let mutable p45Step = 0 @@ -1238,6 +1244,84 @@ type LivingVillageGame() as this = m5View.Status p65Step <- p65Step + 1 + /// P67 证据:任务面板的目标展示(带目标 / 无目标各一帧),走真实每日任务纯函数生成的 DailyTask。 + member private this.PrepareP67Shot () = + let noonOfDay (day: int64) : int64 = + day * Sim.ticksPerDay + M6Presentation.resolveStartTick (Some 12.0) false + let targets = WorldBootstrap.reachableTargets world + let dayTask (day: int64) (targeted: bool) = + if targeted then + Occupation.dailyTaskOfWith targets 42UL (Occupation.occupationSeedOf Occupation.Farmer) day Occupation.Farmer + else + Occupation.dailyTaskOf 42UL (Occupation.occupationSeedOf Occupation.Farmer) day Occupation.Farmer + // 找一天当日任务为「帮工」(有目标语义),使两帧同模板可直接对照。 + let mutable helpDay = 0L + let mutable found = false + for day in 0L .. 120L do + if not found then + match dayTask day true with + | Some task when task.TemplateId = Occupation.HelpWork -> helpDay <- day; found <- true + | _ -> () + let setToday (task: Occupation.DailyTask) = + match m5View.Task with + | Some state -> m5View <- { m5View with Task = Some { state with Today = Some task } } + | None -> () + let ask (command: M5Command) = + let nextWorld, nextView = M5Interaction.apply command world m5View + world <- nextWorld + m5View <- nextView + if not p67Pending then + match p67Step with + | 0 -> + let tick = noonOfDay helpDay + world <- { world with Tick = tick; Time = float tick * Sim.dtSeconds } + match dayTask helpDay true with + | Some task -> setToday task + | None -> () + ask M5Command.ShowTaskPanel + this.CenterCamera() + p67PendingName <- "p67-target" + p67Pending <- true + | 1 -> + match dayTask helpDay false with + | Some task -> setToday task + | None -> () + p67PendingName <- "p67-wildcard" + p67Pending <- true + | _ -> + printfn "p67-shot=done" + this.Exit() + + /// P67 证据:落盘并打印帧名/面板/模板/目标/整行文案/缺字槽位,供 analyze 核验。 + member private this.CaptureP67Shot () = + if p67Pending then + p67Pending <- false + System.IO.Directory.CreateDirectory recordDirectory |> ignore + this.SaveBackBuffer(sprintf "%s/%s.png" recordDirectory p67PendingName) + let lines = M5Interaction.panelLines world m5View + let missingSlots = + lines + |> List.sumBy (fun line -> + line + |> Seq.filter (fun c -> c <> ' ' && not (PixelText.isRenderable (string c))) + |> Seq.length) + let templateText, targetText, lineText = + match m5View.Task |> Option.bind (fun state -> state.Today) with + | None -> "none", "<none>", "<none>" + | Some task -> + Occupation.taskNameOf task.TemplateId, + (TaskRuntime.targetText task |> Option.defaultValue "<none>"), + (TaskRuntime.taskLine task "进行中") + printfn + "p67-shot=%s panel=%s template=%s target=%s line=%s missing_glyph_slots=%d" + p67PendingName + (M5Interaction.panelName m5View) + templateText + targetText + lineText + missingSlots + p67Step <- p67Step + 1 + member private this.PrepareP45Shot () = let baseTick = M6Presentation.resolveStartTick (Some 12.0) false let setTick (tick: int64) = @@ -2255,6 +2339,14 @@ type LivingVillageGame() as this = else this.DispatchMenuInput Confirm elif menu.Page = Playing then this.PrepareP65Shot() + elif p67ShotMode 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.PrepareP67Shot() elif p45ShotMode then if menu.Page = MainMenu then this.DispatchMenuInput Confirm @@ -2733,6 +2825,8 @@ type LivingVillageGame() as this = this.CaptureP64Shot() if p65ShotMode && menu.Page = Playing then this.CaptureP65Shot() + if p67ShotMode && menu.Page = Playing then + this.CaptureP67Shot() if p45ShotMode && menu.Page = Playing then this.CaptureP45Shot() if p46ShotMode then |
