summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel/Occupation.fs
blob: 28008f5d77b5eaab1038583a0f65aa5ecb8a49e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
namespace LivingVillage.Kernel

/// Occupation system first slice (design §1/§2, docs/design/occupation-system-design.md).
/// Data lives beside the player only — NPCs are never occupied.
/// Nothing here runs inside Sim.step; WorldBootstrap stamps the profile onto the
/// world's avatar at creation time, which keeps the numeric state path untouched.
module Occupation =

    type Kind =
        | Farmer
        | Fisher
        | Peddler
        | Scholar

    /// Chinese labels, shared for a later UI slice (农夫 / 渔夫 / 货郎 / 书生).
    let nameOf (kind: Kind) : string =
        match kind with
        | Farmer -> "农夫"
        | Fisher -> "渔夫"
        | Peddler -> "货郎"
        | Scholar -> "书生"

    let saveToken (kind: Kind) : string =
        match kind with
        | Farmer -> "farmer"
        | Fisher -> "fisher"
        | Peddler -> "peddler"
        | Scholar -> "scholar"

    let all : Kind list = [ Farmer; Fisher; Peddler; Scholar ]

    type Profile =
        { Kind: Kind
          InitialMoney: int
          InitialEnergy: float32
          InitialInventory: (Sim.ItemKind * int) list }

    /// Initial values straight from the approved design §1 table.
    let profileOf (kind: Kind) : Profile =
        match kind with
        | Farmer -> { Kind = Farmer; InitialMoney = 60; InitialEnergy = 100.0f; InitialInventory = [ Sim.Food, 12 ] }
        | Fisher -> { Kind = Fisher; InitialMoney = 45; InitialEnergy = 95.0f; InitialInventory = [ Sim.Food, 8; Sim.Fish, 3 ] }
        | Peddler -> { Kind = Peddler; InitialMoney = 90; InitialEnergy = 100.0f; InitialInventory = [ Sim.Food, 6; Sim.Spice, 4 ] }
        | Scholar -> { Kind = Scholar; InitialMoney = 70; InitialEnergy = 100.0f; InitialInventory = [ Sim.Food, 10; Sim.Scroll, 2 ] }

    /// Placeholder carried in save v3 until the task-system slice lands (design §3).
    type State =
        { Profile: Profile
          TaskToken: int
          StoryStage: int }

    let stateOf (kind: Kind) : State =
        { Profile = profileOf kind; TaskToken = 0; StoryStage = 0 }