summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/Interaction.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-28 23:06:20 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-28 23:06:20 +0800
commit07f2e072a14cc74133b187bb8715758790cdfe67 (patch)
tree715efbba87d3be156e927ed5c3ed857a274ea1ae /src/LivingVillage.Desktop/Interaction.fs
parenta26ba18e9710dcdac57d942d2d7ac1ce1e47ca1a (diff)
downloadliving-village-07f2e072a14cc74133b187bb8715758790cdfe67.tar.gz
p52: 玩家交易通道——买/卖经 Sim.quotePrice→Occupation.biasedQuote,背包侧车/钱财增减 + v3 round-trip + HUD 短反馈(design §2.4-2)
Diffstat (limited to 'src/LivingVillage.Desktop/Interaction.fs')
-rw-r--r--src/LivingVillage.Desktop/Interaction.fs40
1 files changed, 35 insertions, 5 deletions
diff --git a/src/LivingVillage.Desktop/Interaction.fs b/src/LivingVillage.Desktop/Interaction.fs
index 9aceff6..6a34b40 100644
--- a/src/LivingVillage.Desktop/Interaction.fs
+++ b/src/LivingVillage.Desktop/Interaction.fs
@@ -32,6 +32,8 @@ type M5Command =
| Intent4
| Intent5
| Intent6
+ | BuyFromTarget
+ | SellToTarget
| Observe
| ToggleNeeds
| ShowChronicle
@@ -352,7 +354,9 @@ module M5Interaction =
| Intent3
| Intent4
| Intent5
- | Intent6 -> view.Panel = DialoguePanel
+ | Intent6
+ | BuyFromTarget
+ | SellToTarget -> view.Panel = DialoguePanel
| Observe
| ToggleNeeds
| ShowChronicle
@@ -406,6 +410,25 @@ module M5Interaction =
| Intent4 -> chooseIntent 3 world view
| Intent5 -> chooseIntent 4 world view
| Intent6 -> chooseIntent 5 world view
+ | BuyFromTarget
+ | SellToTarget ->
+ match view.Menu with
+ | None -> world, { view with Status = "no dialogue menu; press E near an NPC" }
+ | Some menu ->
+ // P52:玩家买/卖走既有 Trade 路径(Sim.quotePrice → Occupation.biasedQuote),
+ // 成交后回到世界面板,让短暂反馈通道显示结果。
+ let outcome =
+ if command = BuyFromTarget then PlayerTrade.buyFood view.Task menu.Target world
+ else PlayerTrade.sellFirst view.Task menu.Target world
+ outcome.World,
+ { view with
+ Panel = WorldPanel
+ Menu = None
+ Prompt = None
+ PromptTargetPos = None
+ Task = outcome.Occupation
+ Status = (if outcome.Succeeded then "trade ok|" else "trade fail|") + outcome.Message
+ StatusTick = Some outcome.World.Tick }
| Observe ->
let observations = Sim.observeVisible (observationBounds world) world
world,
@@ -514,6 +537,8 @@ module M5Interaction =
| value when value.StartsWith("observation") -> "观察完成"
| value when value.StartsWith("chronicle") -> "年鉴已打开"
| "task panel open" -> "任务面板已打开"
+ | value when value.StartsWith("trade ok|") -> value.Substring("trade ok|".Length)
+ | value when value.StartsWith("trade fail|") -> "交易失败:" + value.Substring("trade fail|".Length)
| value when value.StartsWith("no dialogue") -> "当前没有可用对话"
| value when value.StartsWith("invalid dialogue") -> "对话选项无效"
| value when value.StartsWith("no nearby") -> "附近没有可互动目标"
@@ -552,9 +577,12 @@ module M5Interaction =
| TradeAnnal event ->
match event.Kind with
| TradeEvent(buyer, seller, item, quantity, unitPrice) ->
- sprintf "交易:村民 %d 从村民 %d 获得%s ×%d,单价 %.2f"
- (npcNumber buyer)
- (npcNumber seller)
+ // P52:玩家交易以 playerId 记事件,年鉴里显示为「玩家」而非「村民 -1」。
+ let participant (id: NpcId) =
+ if id = playerId then "玩家" else sprintf "村民 %d" (npcNumber id)
+ sprintf "交易:%s 从 %s 获得%s ×%d,单价 %.2f"
+ (participant buyer)
+ (participant seller)
(itemName item)
quantity
unitPrice
@@ -613,7 +641,9 @@ module M5Interaction =
let options =
menu.Options
|> List.mapi (fun index intent -> sprintf "%d %s" (index + 1) (intentName intent))
- [ sprintf "互动:村民 %d" (npcNumber menu.Target) ] @ options @ [ "ESC 关闭"; status ]
+ [ sprintf "互动:村民 %d" (npcNumber menu.Target) ]
+ @ options
+ @ [ "B 买入 食物×1"; "V 卖出 背包物品×1"; "ESC 关闭"; status ]
| ChroniclePanel ->
let entries = chronicleLines world
"年鉴" :: (if entries.IsEmpty then [ "暂无记录" ] else entries) @ [ status ]