diff options
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index 6b52225..862e1de 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -337,6 +337,12 @@ type LivingVillageGame() as this = let mutable p64PendingName = "" let mutable p64Pending = false let mutable p64MoveFrames = 0 + // P65 证据钩子(职业切片五):货郎真实开局 → 与村民真实闲聊写入既有 World.Rumors → + // 真实 Interact 打开对话菜单(拍菜单帧)→ 选「提议交易」询价,拍带中文行情短答的帧。 + let p65ShotMode = Environment.GetEnvironmentVariable("LV_P65_SHOT") = "1" + let mutable p65Step = 0 + let mutable p65PendingName = "" + let mutable p65Pending = false // P45 证据钩子:LV_P45_SHOT=1 时拍角色 idle / 行走朝下 / 行走朝右 三帧(真实游戏截图)。 let p45ShotMode = Environment.GetEnvironmentVariable("LV_P45_SHOT") = "1" let mutable p45Step = 0 @@ -1158,6 +1164,75 @@ type LivingVillageGame() as this = p64PendingName world.Tick world.Avatar.Pos.X world.Avatar.Pos.Y camera.X camera.Y m5View.HomeMode p64Step <- p64Step + 1 + /// P65 证据:货郎真实开局 → 闲聊写入既有谣言池 → 真实 Interact 开菜单 → 提议交易询价。 + member private this.PrepareP65Shot () = + let setHour (hour: float) = + let tick = M6Presentation.resolveStartTick (Some hour) false + world <- { world with Tick = tick; Time = float tick * Sim.dtSeconds } + let ask (command: M5Command) = + let nextWorld, nextView = M5Interaction.apply command world m5View + world <- nextWorld + m5View <- nextView + let placeAtNpc () = + let npc = world.Npcs.[0] + world <- { world with Avatar = { world.Avatar with Pos = npc.Pos } } + if not p65Pending then + match p65Step with + | 0 -> + setHour 12.0 + placeAtNpc () + ask M5Command.Interact + this.CenterCamera() + p65PendingName <- "p65-menu" + p65Pending <- true + | 1 -> + // 真实闲聊一次:把玩家对话写入既有 World.Rumors(最新在前),供询价读取。 + ask M5Command.Intent1 + placeAtNpc () + ask M5Command.Interact + // 非货郎回归:同世界跑农夫 Interact + Intent3,应仍得旧 dialogue 文案(无 inquiry|)。 + let farmerView = + { M5Interaction.initial with + Task = Some(Occupation.stateOf Occupation.Farmer) + Seed = m5View.Seed } + let farmerWorld, farmerOpen = M5Interaction.apply M5Command.Interact world farmerView + let _, farmerAnswered = M5Interaction.apply M5Command.Intent3 farmerWorld farmerOpen + printfn "p65-regression status=%s" farmerAnswered.Status + // 同一世界两次查询:证明同输入逐字符串一致(禁随机)。 + let answer1 = Occupation.marketInquiryText (Some Occupation.Peddler) Sim.OfferTrade world + let answer2 = Occupation.marketInquiryText (Some Occupation.Peddler) Sim.OfferTrade world + printfn + "p65-inquiry rumors=%d fresh=%d hit=%b text1=%s text2=%s equal=%b" + world.Rumors.Length + (Occupation.freshReliableRumors world |> List.length) + (Occupation.inquiryRumor world |> Option.isSome) + (answer1 |> Option.defaultValue "<none>") + (answer2 |> Option.defaultValue "<none>") + (answer1 = answer2) + p65Step <- p65Step + 1 + | 2 -> + ask M5Command.Intent3 + p65PendingName <- "p65-answer" + p65Pending <- true + | _ -> + printfn "p65-shot=done" + this.Exit() + + /// P65 证据:落盘并打印帧名/面板/状态,供 analyze 核验「货郎 status=inquiry|...」。 + member private this.CaptureP65Shot () = + if p65Pending then + p65Pending <- false + System.IO.Directory.CreateDirectory recordDirectory |> ignore + this.SaveBackBuffer(sprintf "%s/%s.png" recordDirectory p65PendingName) + printfn + "p65-shot=%s panel=%s avatar=(%.0f,%.0f) status=%s" + p65PendingName + (M5Interaction.panelName m5View) + world.Avatar.Pos.X + world.Avatar.Pos.Y + m5View.Status + p65Step <- p65Step + 1 + member private this.PrepareP45Shot () = let baseTick = M6Presentation.resolveStartTick (Some 12.0) false let setTick (tick: int64) = @@ -2163,6 +2238,16 @@ type LivingVillageGame() as this = else this.DispatchMenuInput Confirm elif menu.Page = Playing then this.PrepareP64Shot() + elif p65ShotMode then + if menu.Page = MainMenu then + this.DispatchMenuInput Confirm + elif menu.Page = OccupationSelect then + let targetIndex = + MenuState.occupationOptions |> List.findIndex (fun option -> option = Some Occupation.Peddler) + if menu.Selected <> targetIndex then this.DispatchMenuInput Down + else this.DispatchMenuInput Confirm + elif menu.Page = Playing then + this.PrepareP65Shot() elif p45ShotMode then if menu.Page = MainMenu then this.DispatchMenuInput Confirm @@ -2639,6 +2724,8 @@ type LivingVillageGame() as this = this.CaptureP62Shot() if p64ShotMode && menu.Page = Playing then this.CaptureP64Shot() + if p65ShotMode && menu.Page = Playing then + this.CaptureP65Shot() if p45ShotMode && menu.Page = Playing then this.CaptureP45Shot() if p46ShotMode then |
