diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-21 23:03:16 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-21 23:03:16 +0800 |
| commit | 6ce29c5e87d32e49dfe92b398fe45ef0b9de6cdf (patch) | |
| tree | 859a902d27e069e0e087579b6ea38dec76dc4bf3 /src/LivingVillage.Desktop/Game.fs | |
| parent | 11a2a1d8786a660d0f370a46f5ee0c69c108f823 (diff) | |
| parent | 50875bb65cc4cdba92f6745d2430a92d85474872 (diff) | |
| download | living-village-6ce29c5e87d32e49dfe92b398fe45ef0b9de6cdf.tar.gz | |
merge: P15 职业玩法收口——开局职业选择/货郎书生模板/CJK补字/全链路回归(独立复验全绿)
Diffstat (limited to 'src/LivingVillage.Desktop/Game.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/Game.fs | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/LivingVillage.Desktop/Game.fs b/src/LivingVillage.Desktop/Game.fs index 6918e00..1b9508b 100644 --- a/src/LivingVillage.Desktop/Game.fs +++ b/src/LivingVillage.Desktop/Game.fs @@ -204,11 +204,18 @@ type LivingVillageGame() as this = m5View <- M5Interaction.refreshPrompt world M5Interaction.initial this.CenterCamera() - member private this.StartNewGame() = - world <- createInitialWorld () + member private this.StartNewGame (occupation: Occupation.Kind option) = + let state = + occupation + |> Option.map (fun kind -> + let startTick = if daylightAutoplay then 6L * Sim.ticksPerDay / 24L else 0L + WorldBootstrap.occupationStateFor 42UL kind startTick) + world <- WorldBootstrap.initialWorldWithOccupation daylightAutoplay 42UL Sim.npcCount state this.ResetWorldView() + m5View <- { m5View with Task = state } menu <- menu |> MenuState.setCurrentWorld true |> MenuState.enterGame - printfn $"new-game=ok seed=42 npcs={Sim.npcCount}" + let occupationName = occupation |> Option.map Occupation.nameOf |> Option.defaultValue "none" + printfn $"new-game=ok seed=42 npcs={Sim.npcCount} occupation={occupationName}" member private this.SaveWorld (prefix: string) : bool = try @@ -247,7 +254,10 @@ type LivingVillageGame() as this = | ContinueGame -> menu <- menu |> MenuState.setCurrentWorld true |> MenuState.enterGame printfn $"continue=ok tick={world.Tick}" - | StartNewGame -> this.StartNewGame() + | StartNewGame -> + menu <- MenuState.openOccupationSelect menu + printfn "menu=occupation-select" + | StartNewGameWith occupation -> this.StartNewGame occupation | LoadGame -> match this.LoadWorld "load" with | Ok _ -> @@ -278,7 +288,9 @@ type LivingVillageGame() as this = else None match input with | Some nextInput -> this.DispatchMenuInput nextInput - | None when (autoplay || sampleMode) && not autoplayFlow && menu.Page = MainMenu && not menu.HasCurrentWorld -> + | None when (autoplay || sampleMode) && not autoplayFlow + && (menu.Page = MainMenu || menu.Page = OccupationSelect) + && not menu.HasCurrentWorld -> autoplayFrames <- autoplayFrames + 1 if autoplayFrames >= 15 then this.DispatchMenuInput Confirm @@ -435,6 +447,12 @@ type LivingVillageGame() as this = else avatarMoving <- false this.CenterCamera() + match m5View.Task with + | Some state -> + let refreshed = WorldBootstrap.refreshOccupationToday 42UL state world.Tick + if refreshed <> state then + m5View <- { m5View with Task = Some refreshed } + | None -> () m5View <- M5Interaction.refreshPrompt world m5View member private this.RunAutoplayFlow() = @@ -455,6 +473,9 @@ type LivingVillageGame() as this = | 50 -> printfn "flow=new-game" flowStep <- 1 + | 1 when menu.Page = OccupationSelect -> + this.DispatchMenuInput Confirm + printfn "flow=occupation=none" | 1 when menu.Page = Playing -> this.OpenMainMenu() printfn "flow=return-menu" @@ -619,6 +640,7 @@ type LivingVillageGame() as this = let contentRows = match menu.Page with | MainMenu -> MenuState.items menu |> List.length + | OccupationSelect -> MenuState.occupationOptions.Length | Settings -> MenuState.settings.Length | Controls -> MenuState.controlRows.Length | LoadError -> 4 @@ -696,6 +718,12 @@ type LivingVillageGame() as this = MenuState.items menu |> List.iteri (fun index item -> drawSelection index (MenuState.itemLabel item) (contentY + index * lineHeight)) drawText innerX (panelY + panelHeight - 40) mutedColor "UP DOWN 选择 ENTER 确认" + | OccupationSelect -> + drawText innerX headingY mutedColor "选择职业" + MenuState.occupationOptions + |> List.iteri (fun index occupation -> + drawSelection index (MenuState.occupationLabel occupation) (contentY + index * lineHeight)) + drawText innerX (panelY + panelHeight - 40) mutedColor "UP DOWN 选择 ENTER 确认 ESC 返回" | Settings -> drawText innerX headingY mutedColor (ChineseText.menuHeading SettingsHeading) MenuState.settings |
