dnd5e-town-generator/src/Objects/Town.elm

106 lines
2.3 KiB
Elm

module Objects.Town exposing (..)
import Array exposing (Array)
import Hash
import Random
import Generatable exposing (Generatable)
import Objects.District as District exposing (District)
{-| The Msg is the update telling what adjustments are made to the model.
-}
type Msg
= GenerateSize
{-| The Town is the comprehensive model that contains all the information about
a town.
-}
type Town
= Town
{ districts : Generatable (Array (Generatable District))
, name : String
, size : TownSize
}
type TownSize
= Tiny
| Small
| Medium
| Average
| Big
| Huge
-- | Humongous
-- | Massive
-- | Colossal
{-| Determine the number of districts in the town based on its size.
-}
districtNumberGenerator : TownSize -> Random.Generator Int
districtNumberGenerator ts =
case ts of
Tiny ->
Random.int 1 2
Small ->
Random.int 5 8
Medium ->
Random.int 15 20
Average ->
Random.int 35 45
Big ->
Random.int 90 140
Huge ->
Random.int 250 470
{-| Init a new town.
-}
init : { name : String, size : TownSize } -> Town
init data =
Town
{ districts =
data.size
|> districtNumberGenerator
|> Random.map (always never)
|> Generatable.fromGenerator
, name = data.name
, size = data.size
}
{-| Get a town's name.
-}
name : Town -> String
name (Town town) = town.name
{-| Get a town's size.
-}
size : Town -> Maybe Int
size (Town town) =
Generatable.content town.size
{-| Get a town's size. If it isn't generated yet, generate it.
-}
sizeGenerate : Town -> ( Town, Int )
sizeGenerate ((Town t) as town) =
case Generatable.content t.size of
Just s ->
( town, s )
Nothing ->
case Generatable.generateAndReturnFromSeed (sizeSeed town) t.size of
( newSize, s ) ->
( Town { t | size = newSize }, s )
{-| Generate a seed for the town's size.
-}
sizeSeed : Town -> Random.Seed
sizeSeed (Town town) =
Hash.fromString town.name
|> Hash.dependent (Hash.fromString "size")
|> Hash.toString
|> String.toInt
|> Maybe.withDefault 0
|> Random.initialSeed