From cd503470995ff09fecb0e7b6b1216bd6da821bb7 Mon Sep 17 00:00:00 2001 From: Max Wilson Date: Mon, 12 Feb 2024 13:09:32 -0800 Subject: [PATCH] Start to replace swashbuckler stub with start of actual flags-based implementation. Needs tests for issue #56. ChargenView is still using the menu stubs instead of the flags-based implementation but can be swapped out with one line of code. --- src/Core/Menus.fs | 4 --- src/Domain/DFRPG/Chargen.Templates.fs | 40 +++++++++++++++++++++------ src/UI/DFRPG/Chargen.fs | 8 ++++++ src/UI/DFRPG/ChargenView.fs | 4 +-- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/Core/Menus.fs b/src/Core/Menus.fs index 74d3589..bb40efb 100644 --- a/src/Core/Menus.fs +++ b/src/Core/Menus.fs @@ -144,14 +144,10 @@ type Op = match children with | Fulfilled(value, childMenus) -> // when we're at quota, exclude all the unpicked options from the menu unless and until some current selections are unpicked - // let values = lst |> List.collect fst - // let childMenus = lst |> List.map snd value, Either(config.label, childMenus) | Partial(value, allChildMenus) -> - // let allChildMenus = children |> List.map snd value, Either(config.label, allChildMenus) | Fallback(fallbackValue, allChildMenus) -> - // let allChildMenus = children |> List.map snd fallbackValue, Either(config.label, allChildMenus) ) static let andF config (offers: _ ListOffer list) = diff --git a/src/Domain/DFRPG/Chargen.Templates.fs b/src/Domain/DFRPG/Chargen.Templates.fs index cae5cc7..5eb2988 100644 --- a/src/Domain/DFRPG/Chargen.Templates.fs +++ b/src/Domain/DFRPG/Chargen.Templates.fs @@ -5,22 +5,46 @@ module Flags = open Flags let allFlags = { flags = [] } let flag name = Flag(name, allFlags) - - let combatReflexes = flag "Combat Reflexes" - let highPainThreshold = flag "High Pain Threshold" + type FlagOutput = Literal of FlagKey | Bonus of FlagKey * int + let toString (f:FlagOutput) = + match f with + | Literal s -> s + | Bonus(s, n) -> $"%+d{n} {s}" let ST = flag "ST" let DX = flag "DX" let IQ = flag "IQ" let HT = flag "HT" - let luck = flag "Luck" + let Ambi = flag "Ambidexterity" + let CombatReflexes = flag "Combat Reflexes" + let ETS = flag "Enhanced Time Sense" + let HPT = flag "High Pain Threshold" + let Luck = flag "Luck" open Flags -type FlagOutput = Literal of FlagKey | Bonus of FlagKey * int type Op with - static member adv (flag:Flag) = Op.trait' (Literal flag.Key) - static member bonus (flag:Flag) n = Op.trait' (Bonus(flag.Key, n)) + static member adv (flag:Flag) = + Op.trait' ({ blank() with toString = Some Flags.toString }, Literal flag.Key) + static member bonus (flag:Flag) n = + Op.trait' ({ blank() with toString = Some Flags.toString }, Bonus(flag.Key, n)) + static member bonusRange (flag:Flag) (ns: int list) = + let spec : LevelSpec = { toString = toString; ctor = fun n -> Bonus(flag.Key, n) } + Op.level(flag.Key, spec, ns) + static member chooseN n (options: _ OptionOffer list) = + Op.eitherN(blank(), n, options) open type Op let swashbuckler: FlagOutput ListOffer list = [ - Op.and' [ bonus ST 1; bonus DX 5; bonus HT 3; adv combatReflexes; adv luck ] + Op.and' [ + bonus ST 1 + bonus DX 5 + bonus HT 3 + adv CombatReflexes + adv Luck + ] + Op.chooseN 4 [ + bonusRange ST [1..6] + bonusRange DX [1..3] + adv Ambi + adv ETS + ] ] \ No newline at end of file diff --git a/src/UI/DFRPG/Chargen.fs b/src/UI/DFRPG/Chargen.fs index f0e1b22..68e4d5c 100644 --- a/src/UI/DFRPG/Chargen.fs +++ b/src/UI/DFRPG/Chargen.fs @@ -36,6 +36,14 @@ let swash = [ advantage CombatReflexes skill("Acrobatics", [1..3]) ]) + eitherN(Menus.blank(), 3, [ + skill("Rapier", 3) |> promote + skill("Sling", 3) |> promote + skill("Bow", 3) |> promote + skill("Two-handed Sword", 3) |> promote + skill("Stealth", 3) |> promote + skill("Climbing", 3) |> promote + ]) let mainWeapons = ["Rapier"; "Broadsword"; "Polearm"; "Two-handed sword"] let weaponsAt (bonus: int) = mainWeapons |> List.map (fun name -> skill(name, bonus)) eitherN [ diff --git a/src/UI/DFRPG/ChargenView.fs b/src/UI/DFRPG/ChargenView.fs index 1fc6c4f..1c43dc4 100644 --- a/src/UI/DFRPG/ChargenView.fs +++ b/src/UI/DFRPG/ChargenView.fs @@ -42,7 +42,7 @@ module private Impl = ] ] } - let eval dispatch selections (template: Trait ListOffer list) = + let eval dispatch selections (template: _ ListOffer list) = let value, menus = [ for offer in template do @@ -56,7 +56,7 @@ open Impl [] let View() = let model, dispatch = React.useElmishSimple init update - let profession = swash + let profession = swash // Domain.DFRPG.Templates.swashbuckler let value, react = eval dispatch model.selections profession // value will be used later for things like enabling/disabling the Save button Html.div [ srcLink