summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/VillagePresentation.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-21 00:26:30 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-21 00:26:30 +0800
commitb6b95988e525a68ea7426ecc9690b18a1b3bbfe8 (patch)
tree4c19ab58a610c6d783e1dfc45585b12a6ecb2e58 /src/LivingVillage.Desktop/VillagePresentation.fs
parent0ea26337830ada438df144b3a51f429f00dc1967 (diff)
downloadliving-village-b6b95988e525a68ea7426ecc9690b18a1b3bbfe8.tar.gz
feat(m6c): 完成江南村庄中文交付
完成江南村庄场景、角色表现和中文界面的 M6c 交付范围。 新增 CJK 字形图集、中文文案与运行时加载,补充民居情境交互和确定性村庄美术表现。 更新资源复制与 Linux/macOS 打包校验,加入 188 字符清单、资源许可说明和对应原型测试。 补充江南美术方向与 M6c 交付说明,并保持原有模拟内核和桌面构建入口不变。
Diffstat (limited to 'src/LivingVillage.Desktop/VillagePresentation.fs')
-rw-r--r--src/LivingVillage.Desktop/VillagePresentation.fs45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/LivingVillage.Desktop/VillagePresentation.fs b/src/LivingVillage.Desktop/VillagePresentation.fs
index 95dc178..eee7fac 100644
--- a/src/LivingVillage.Desktop/VillagePresentation.fs
+++ b/src/LivingVillage.Desktop/VillagePresentation.fs
@@ -1,5 +1,8 @@
namespace LivingVillage.Desktop
+open System
+open LivingVillage.Kernel.Sim
+
module VillagePresentation =
(**
@@ -18,6 +21,11 @@ module VillagePresentation =
Y: int }
[<Struct>]
+ type PixelPosition =
+ { X: float32
+ Y: float32 }
+
+ [<Struct>]
type SimulationTick =
| SimulationTick of int64
@@ -74,6 +82,11 @@ module VillagePresentation =
| Outside
| Inside of HomeId
+ type HomeInputAction =
+ | EnterHomeAction of HomeId
+ | ExitHomeAction of HomeId
+ | DialogueAction
+
type HomeTransitionError =
| NotNearHomeDoor
| AlreadyInsideHome of HomeId
@@ -120,7 +133,18 @@ module VillagePresentation =
let scene : PrototypeScene =
createScene ()
- let private manhattanDistance first second : int =
+ let sceneOrigin : TilePosition =
+ tile 25 18
+
+ let sceneTileFromPixel (pixel: PixelPosition) : TilePosition =
+ { X = int (Math.Floor(float pixel.X / float tilePixels)) - sceneOrigin.X
+ Y = int (Math.Floor(float pixel.Y / float tilePixels)) - sceneOrigin.Y }
+
+ let worldTileForSceneTile (sceneTile: TilePosition) : TilePosition =
+ { X = sceneOrigin.X + sceneTile.X
+ Y = sceneOrigin.Y + sceneTile.Y }
+
+ let private manhattanDistance (first: TilePosition) (second: TilePosition) : int =
abs (first.X - second.X) + abs (first.Y - second.Y)
let isNearHomeDoor (position: TilePosition) (home: Home) : bool =
@@ -143,6 +167,25 @@ module VillagePresentation =
else
Error(HomeNotFound homeId)
+ let homeInputAction (pixel: PixelPosition) (mode: HomeMode) : HomeInputAction =
+ let scenePosition = sceneTileFromPixel pixel
+
+ match mode with
+ | Outside ->
+ match enterHome scenePosition Outside with
+ | Ok(Inside homeId) -> EnterHomeAction homeId
+ | _ -> DialogueAction
+ | Inside homeId ->
+ match scene.Homes |> List.tryFind (fun home -> home.Id = homeId) with
+ | Some home when isNearHomeDoor scenePosition home ->
+ match exitHome mode with
+ | Ok Outside -> ExitHomeAction homeId
+ | _ -> DialogueAction
+ | _ -> DialogueAction
+
+ let resetHomeMode () : HomeMode =
+ Outside
+
let directionForInput (input: DirectionInput) : Direction option =
match input with
| UpInput -> Some North