summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/Game.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
-rw-r--r--src/LivingVillage.Desktop/Game.fs69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs
index 7b1dfb1..8c0b8a1 100644
--- a/src/LivingVillage.Desktop/Game.fs
+++ b/src/LivingVillage.Desktop/Game.fs
@@ -295,6 +295,12 @@ type LivingVillageGame() as this =
let mutable p39Step = 0
let mutable p39PendingName = ""
let mutable p39Pending = false
+ // P40 证据钩子:LV_P40_SHOT=1 时在真实 256x192 生成器世界里拍
+ // p40-day / p40-night / p40-boat-closeup(相机贴近乌篷船,便于 2x 特写)。
+ let p40ShotMode = Environment.GetEnvironmentVariable("LV_P40_SHOT") = "1"
+ let mutable p40Step = 0
+ let mutable p40PendingName = ""
+ let mutable p40Pending = false
let mutable autoplayFrames = 0
let mutable flowStep = 0
let mutable flowHold = 0
@@ -691,6 +697,59 @@ type LivingVillageGame() as this =
p39PendingName world.Tick world.Avatar.Pos.X world.Avatar.Pos.Y camera.X camera.Y
p39Step <- p39Step + 1
+ /// P40 证据:真实生成器世界里拍昼 / 夜整帧与乌篷船近景。位置取自确定性摆放纯函数,
+ /// 含真实 tint 与 P14 光晕;相机贴近船体便于 2x NEAREST 特写。
+ member private this.PrepareP40Shot () =
+ let placeCameraOn (tileX: int) (tileY: int) =
+ world <- { world with Avatar = { world.Avatar with Pos = { X = float32 (tileX * Sim.tilePixels); Y = float32 (tileY * Sim.tilePixels) } } }
+ this.CenterCamera()
+ let setHour (hour: float) =
+ let tick = M6Presentation.resolveStartTick (Some hour) false
+ world <- { world with Tick = tick; Time = float tick * Sim.dtSeconds }
+ let dayHour = 12.0
+ let nightHour = 23.5
+ if not p40Pending then
+ match riverscapeMap with
+ | None -> this.Exit()
+ | Some map ->
+ let boat =
+ match VillageArt.cc0BoatTile map with
+ | Some (bx, by) -> (bx, by)
+ | None ->
+ match map.Bridges |> List.sortBy (fun (x, y) -> (x, y)) |> List.tryHead with
+ | Some (bx, by) -> (bx, by)
+ | None -> (map.Core.MinX, map.Core.MinY)
+ let boatShot = (fst boat + 1, snd boat)
+ match p40Step with
+ | 0 ->
+ setHour dayHour
+ placeCameraOn (fst boat) (snd boat)
+ p40PendingName <- "p40-day"
+ p40Pending <- true
+ | 1 ->
+ setHour nightHour
+ placeCameraOn (fst boat) (snd boat)
+ p40PendingName <- "p40-night"
+ p40Pending <- true
+ | 2 ->
+ setHour dayHour
+ placeCameraOn (fst boatShot) (snd boatShot)
+ p40PendingName <- "p40-boat"
+ p40Pending <- true
+ | _ ->
+ printfn "p40-shot=done"
+ this.Exit()
+
+ /// P40 证据:与 P39 相同,在 `Draw` 末尾落盘当前后台缓冲。
+ member private this.CaptureP40Shot () =
+ if p40Pending then
+ p40Pending <- false
+ System.IO.Directory.CreateDirectory recordDirectory |> ignore
+ this.SaveBackBuffer(sprintf "%s/%s.png" recordDirectory p40PendingName)
+ printfn "p40-shot=%s tick=%d pos=(%.0f,%.0f) camera=(%.0f,%.0f)"
+ p40PendingName world.Tick world.Avatar.Pos.X world.Avatar.Pos.Y camera.X camera.Y
+ p40Step <- p40Step + 1
+
/// P20 第三步取证:真走位巡游(Sim.step 驱动)沿桥/路/民居门移动,用于桥面行走帧与昼夜录制。
member private this.RunRiverscapeTour () =
if not riverscapeTourWatchStarted then
@@ -998,6 +1057,14 @@ type LivingVillageGame() as this =
else this.DispatchMenuInput Confirm
elif menu.Page = Playing then
this.PrepareP39Shot()
+ elif p40ShotMode 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.PrepareP40Shot()
elif p37ShotMode then
this.RunP37Shot()
elif menu.Page = Playing then
@@ -1379,6 +1446,8 @@ type LivingVillageGame() as this =
this.CaptureP36PromptShot()
if p39ShotMode && menu.Page = Playing then
this.CaptureP39Shot()
+ if p40ShotMode && menu.Page = Playing then
+ this.CaptureP40Shot()
/// 启动画面:分层天色 + 屋脊/水面剪影 + 标题淡入上浮 + 跳过提示,全部为帧计数纯函数。
member private this.DrawSplash() =