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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94module Duets.Cli.Scenes.MainMenu
open Duets.Agents
open Duets.Agents.Savegame
open Duets.Cli.Components
open Duets.Cli.SceneIndex
open Duets.Cli.Text
open Duets.Data.Savegame.Types
open System.Reflection
let gameVersion =
let assembly = Assembly.GetEntryAssembly()
let infoVersion =
assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
match infoVersion with
| null -> assembly.GetName().Version.ToString()
| attr ->
let version = attr.InformationalVersion
let isNonFinalVersion = version.Contains("-")
if isNonFinalVersion then version else version.Split("+")[0]
type private MainMenuOption =
| NewGame
| LoadGame
| Settings
let private textFromOption opt =
match opt with
| NewGame -> MainMenu.newGame
| LoadGame -> MainMenu.loadGame
| Settings -> MainMenu.settings
let private textFromMigrationError err =
match err with
| MigrationError.InvalidStructure message -> message
| MigrationError.InvalidVersion version ->
$"Unknown savegame version {version}"
/// Main menu of the game where the user can choose to either start a new game
/// or load a previous one.
let rec mainMenu skipSaving =
clearScreen ()
Generic.gameName |> showFiglet
showGameInfo gameVersion
let savegameState = Savegame.load ()
if skipSaving then
Styles.danger
"--no-saving arg detected, all changes during gameplay won't be persisted!"
|> showMessage
let hasSavegameAvailable =
match savegameState with
| Available _ -> true
| NotAvailable -> false
| Incompatible reason ->
textFromMigrationError reason
|> MainMenu.incompatibleSavegame
|> showMessage
false
let selectedChoice =
showOptionalChoicePrompt
MainMenu.prompt
MainMenu.exit
textFromOption
[ NewGame
if hasSavegameAvailable then
LoadGame
Settings ]
match selectedChoice with
| Some NewGame -> createNewGame skipSaving hasSavegameAvailable
| Some LoadGame -> Scene.WorldAfterMovement
| Some Settings -> Scene.Settings
| None -> Scene.Exit ExitMode.SkipSave
and private createNewGame skipSaving hasSavegameAvailable =
if hasSavegameAvailable then
let confirmed = showConfirmationPrompt MainMenu.newGameReplacePrompt
if confirmed then
Scene.CharacterCreator
else
mainMenu skipSaving
else
Scene.CharacterCreator