diff --git a/src/Common/Disease.ml b/src/Common/Disease.ml new file mode 100644 index 00000000..cde383ae --- /dev/null +++ b/src/Common/Disease.ml @@ -0,0 +1,197 @@ +type resistance = Spirit | Toughness | LowerOfSpiritAndToughness + +module Cause = struct + type chance = Percent of int | Text of string + + type t = { chance : chance; name : string } + + module Decode = struct + open Decoders_bs.Decode + + type translation = { name : string; chance : string option } + + let translation = + field "name" string + >>= fun name -> + field_opt "chance" string + >>= fun chance -> succeed ({ name; chance } : translation) + + type multilingual = { + chance : int option; + translations : translation TranslationMap.t; + } + + let multilingual = + field_opt "chance" int + >>= fun chance -> + field "translations" (TranslationMap.Decode.t translation) + >>= fun translations -> succeed { chance; translations } + + let make locale_order = + multilingual + >>= fun multilingual -> + multilingual.translations + |> TranslationMap.preferred locale_order + |> function + | Some translation -> + (match (multilingual.chance, translation.chance) with + | Some percent, _ -> succeed (Percent percent) + | None, Some text -> succeed (Text text) + | None, None -> + fail "Either a percent chance or a text chance must be defined") + >>= fun chance -> + succeed (Some ({ chance; name = translation.name } : t)) + | None -> succeed None + end +end + +type alternative_name = { name : string; region : string option } + +type varying_parameter = { default : string; lessened : string option } + +type t = { + id : Id.Disease.t; + name : string; + alternative_names : alternative_name list; + level : int; + progress : string; + resistance : resistance; + incubation_time : string; + damage : varying_parameter; + duration : varying_parameter; + cause : Cause.t list; + special : string option; + treatment : string; + cure : string; + src : PublicationRef.list; + errata : Erratum.list; +} + +module Decode = struct + open Decoders_bs.Decode + + let alternative_name = + one_of + [ + ("simple", string >>= fun name -> succeed { name; region = None }); + ( "regional", + field "name" string + >>= fun name -> + field "region" string + >>= fun region -> succeed { name; region = Some region } ); + ] + + let varying_parameter = + field "default" string + >>= fun default -> + field_opt "lessened" string + >>= fun lessened -> succeed { default; lessened } + + type translation = { + name : string; + alternative_names : alternative_name list option; + progress : string; + incubation_time : string; + damage : varying_parameter; + duration : varying_parameter; + special : string option; + treatment : string; + cure : string; + errata : Erratum.list option; + } + + let translation = + field "name" string + >>= fun name -> + field_opt "alternative_names" (list alternative_name) + >>= fun alternative_names -> + field "progress" string + >>= fun progress -> + field "incubation_time" string + >>= fun incubation_time -> + field "damage" varying_parameter + >>= fun damage -> + field "duration" varying_parameter + >>= fun duration -> + field_opt "special" string + >>= fun special -> + field "treatment" string + >>= fun treatment -> + field "cure" string + >>= fun cure -> + field_opt "errata" Erratum.Decode.list + >>= fun errata -> + succeed + { + name; + alternative_names; + progress; + incubation_time; + damage; + duration; + special; + treatment; + cure; + errata; + } + + let resistance = + string + >>= function + | "Spirit" -> succeed Spirit + | "Toughness" -> succeed Toughness + | "LowerOfSpiritAndToughness" -> succeed LowerOfSpiritAndToughness + | _ -> fail "Expected a resistance" + + type multilingual = { + id : Id.Disease.t; + level : int; + resistance : resistance; + cause : Cause.t list; + src : PublicationRef.list; + translations : translation TranslationMap.t; + } + + let multilingual locale_order = + field "id" Id.Disease.Decode.t + >>= fun id -> + field "level" int + >>= fun level -> + field "resistance" resistance + >>= fun resistance -> + field "cause" (list (Cause.Decode.make locale_order)) + >|= Option.catOptions + >>= fun cause -> + field "src" (PublicationRef.Decode.make_list locale_order) + >>= fun src -> + field "translations" (TranslationMap.Decode.t translation) + >>= fun translations -> + succeed { id; level; resistance; cause; src; translations } + + let make_assoc locale_order = + let open Option.Infix in + multilingual locale_order + >|= fun multilingual -> + multilingual.translations + |> TranslationMap.preferred locale_order + <&> fun translation -> + ( multilingual.id, + { + id = multilingual.id; + name = translation.name; + alternative_names = + translation.alternative_names |> Option.value ~default:[]; + level = multilingual.level; + progress = translation.progress; + resistance = multilingual.resistance; + incubation_time = translation.incubation_time; + damage = translation.damage; + duration = translation.duration; + cause = multilingual.cause; + special = translation.special; + treatment = translation.treatment; + cure = translation.cure; + src = multilingual.src; + errata = translation.errata |> Option.value ~default:[]; + } ) +end diff --git a/src/Common/Disease.mli b/src/Common/Disease.mli new file mode 100644 index 00000000..c15f8684 --- /dev/null +++ b/src/Common/Disease.mli @@ -0,0 +1,46 @@ +(** This module contains definitions and simple utility functions for the + regions of Aventuria. *) + +type resistance = Spirit | Toughness | LowerOfSpiritAndToughness + +module Cause : sig + type chance = + | Percent of int + (** The chance as a percent value, e.g. 25 % would be [25]. *) + | Text of string + (** A more complex chance, which cannot be (easily) expressed using + atomic values and thus need to be handled manually. *) + + type t = { chance : chance; name : string } +end + +type alternative_name = { + name : string; + region : string option; + (** The alternative name is only known in a certain region. *) +} + +type varying_parameter = { default : string; lessened : string option } + +type t = { + id : Id.Disease.t; + name : string; + alternative_names : alternative_name list; + level : int; + progress : string; + resistance : resistance; + incubation_time : string; + damage : varying_parameter; + duration : varying_parameter; + cause : Cause.t list; + special : string option; + treatment : string; + cure : string; + src : PublicationRef.list; + errata : Erratum.list; +} +(** The region type. *) + +module Decode : sig + val make_assoc : (Id.Disease.t, t) Parsing.make_assoc +end diff --git a/src/Common/ExperienceLevel.ml b/src/Common/ExperienceLevel.ml index 4c180936..dd0dda4c 100644 --- a/src/Common/ExperienceLevel.ml +++ b/src/Common/ExperienceLevel.ml @@ -1,13 +1,13 @@ type t = { id : Id.ExperienceLevel.t; name : string; - ap : int; + adventure_points : int; max_attribute_value : int; max_skill_rating : int; max_combat_technique_rating : int; max_attribute_total : int; - max_number_spells_liturgical_chants : int; - max_unfamiliar_spells : int; + max_number_of_spells_liturgical_chants : int; + max_number_of_unfamiliar_spells : int; } module Decode = struct @@ -19,45 +19,45 @@ module Decode = struct type multilingual = { id : Id.ExperienceLevel.t; - ap : int; - maxAttributeValue : int; - maxSkillRating : int; - maxCombatTechniqueRating : int; - maxAttributeTotal : int; - maxNumberSpellsLiturgicalChants : int; - maxUnfamiliarSpells : int; + adventure_points : int; + max_attribute_value : int; + max_skill_rating : int; + max_combat_technique_rating : int; + max_attribute_total : int; + max_number_of_spells_liturgical_chants : int; + max_number_of_unfamiliar_spells : int; translations : translation TranslationMap.t; } let multilingual = field "id" Id.ExperienceLevel.Decode.t >>= fun id -> - field "ap" int - >>= fun ap -> - field "maxAttributeValue" int - >>= fun maxAttributeValue -> - field "maxSkillRating" int - >>= fun maxSkillRating -> - field "maxCombatTechniqueRating" int - >>= fun maxCombatTechniqueRating -> - field "maxAttributeTotal" int - >>= fun maxAttributeTotal -> - field "maxNumberSpellsLiturgicalChants" int - >>= fun maxNumberSpellsLiturgicalChants -> - field "maxUnfamiliarSpells" int - >>= fun maxUnfamiliarSpells -> + field "adventure_points" int + >>= fun adventure_points -> + field "max_attribute_value" int + >>= fun max_attribute_value -> + field "max_skill_rating" int + >>= fun max_skill_rating -> + field "max_combat_technique_rating" int + >>= fun max_combat_technique_rating -> + field "max_attribute_total" int + >>= fun max_attribute_total -> + field "max_number_of_spells_liturgical_chants" int + >>= fun max_number_of_spells_liturgical_chants -> + field "max_number_of_unfamiliar_spells" int + >>= fun max_number_of_unfamiliar_spells -> field "translations" (TranslationMap.Decode.t translation) >>= fun translations -> succeed { id; - ap; - maxAttributeValue; - maxSkillRating; - maxCombatTechniqueRating; - maxAttributeTotal; - maxNumberSpellsLiturgicalChants; - maxUnfamiliarSpells; + adventure_points; + max_attribute_value; + max_skill_rating; + max_combat_technique_rating; + max_attribute_total; + max_number_of_spells_liturgical_chants; + max_number_of_unfamiliar_spells; translations; } @@ -72,13 +72,14 @@ module Decode = struct { id = multilingual.id; name = translation.name; - ap = multilingual.ap; - max_attribute_value = multilingual.maxAttributeValue; - max_skill_rating = multilingual.maxSkillRating; - max_combat_technique_rating = multilingual.maxCombatTechniqueRating; - max_attribute_total = multilingual.maxAttributeTotal; - max_number_spells_liturgical_chants = - multilingual.maxNumberSpellsLiturgicalChants; - max_unfamiliar_spells = multilingual.maxUnfamiliarSpells; + adventure_points = multilingual.adventure_points; + max_attribute_value = multilingual.max_attribute_value; + max_skill_rating = multilingual.max_skill_rating; + max_combat_technique_rating = multilingual.max_combat_technique_rating; + max_attribute_total = multilingual.max_attribute_total; + max_number_of_spells_liturgical_chants = + multilingual.max_number_of_spells_liturgical_chants; + max_number_of_unfamiliar_spells = + multilingual.max_number_of_unfamiliar_spells; } ) end diff --git a/src/Common/ExperienceLevel.mli b/src/Common/ExperienceLevel.mli index 02e017aa..7831123d 100644 --- a/src/Common/ExperienceLevel.mli +++ b/src/Common/ExperienceLevel.mli @@ -4,13 +4,13 @@ type t = { id : Id.ExperienceLevel.t; name : string; - ap : int; + adventure_points : int; max_attribute_value : int; max_skill_rating : int; max_combat_technique_rating : int; max_attribute_total : int; - max_number_spells_liturgical_chants : int; - max_unfamiliar_spells : int; + max_number_of_spells_liturgical_chants : int; + max_number_of_unfamiliar_spells : int; } module Decode : sig diff --git a/src/Common/Id.ml b/src/Common/Id.ml index c9c6fc98..7b62c09e 100644 --- a/src/Common/Id.ml +++ b/src/Common/Id.ml @@ -1941,3 +1941,15 @@ module Disease = struct let to_int = function Other x -> x end) end + +module Region = struct + type t = Other of int + + include Make (struct + type nonrec t = t + + let from_int = function x -> Other x + + let to_int = function Other x -> x + end) +end diff --git a/src/Common/Id.mli b/src/Common/Id.mli index 3fc05e3c..1ea7443f 100644 --- a/src/Common/Id.mli +++ b/src/Common/Id.mli @@ -844,3 +844,9 @@ module Disease : sig include Id with type t := t end + +module Region : sig + type t = Other of int + + include Id with type t := t +end diff --git a/src/Common/IdGroup.ml b/src/Common/IdGroup.ml index ca4c7357..d2ab72c3 100644 --- a/src/Common/IdGroup.ml +++ b/src/Common/IdGroup.ml @@ -4,6 +4,28 @@ let decode_many f g = Decoders_bs.Decode.( field "value" (NonEmptyList.Decode.t int) >|= NonEmptyList.fmap f >|= g) +module type IdGroup = sig + type t + + val compare : t -> t -> int + + module Map : MapX.T with type key = t +end + +module Make (S : sig + type t + + val compare : t -> t -> int +end) : IdGroup with type t := S.t = struct + include S + + module Map = MapX.Make (struct + type nonrec t = S.t + + let compare = compare + end) +end + module ExtensionRule = struct type t = FocusRule of Id.FocusRule.t | OptionalRule of Id.OptionalRule.t [@@bs.deriving accessors] @@ -12,7 +34,7 @@ module ExtensionRule = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "FocusRule" -> decode_one Id.FocusRule.from_int focusRule | "OptionalRule" -> decode_one Id.OptionalRule.from_int optionalRule @@ -85,7 +107,7 @@ module Activatable = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "Advantage" -> decode_many Id.Advantage.from_int advantage | "Disadvantage" -> decode_many Id.Disadvantage.from_int disadvantage @@ -244,7 +266,7 @@ module Activatable = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "Advantage" -> decode_one Id.Advantage.from_int advantage | "Disadvantage" -> decode_one Id.Disadvantage.from_int disadvantage @@ -379,7 +401,7 @@ module SelectOption = struct let t = let generic = int |> map generic in let specific = - field "type" string + field "tag" string >>= function | "Blessing" -> decode_one Id.Blessing.from_int blessing | "Cantrip" -> decode_one Id.Cantrip.from_int cantrip @@ -438,7 +460,7 @@ module Rated = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "Attribute" -> decode_many Id.Attribute.from_int attribute | "Skill" -> decode_many Id.Skill.from_int skill @@ -470,7 +492,7 @@ module Rated = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "Attribute" -> decode_one Id.Attribute.from_int attribute | "Skill" -> decode_one Id.Skill.from_int skill @@ -500,7 +522,7 @@ module Skill = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "Skill" -> decode_one Id.Skill.from_int skill | "Spell" -> decode_one Id.Spell.from_int spell @@ -524,7 +546,7 @@ module ActivatableSkill = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "Spell" -> decode_one Id.Spell.from_int spell | "Ritual" -> decode_one Id.Ritual.from_int ritual @@ -535,6 +557,22 @@ module ActivatableSkill = struct end end +module Spellwork = struct + type t = Spell of Id.Spell.t | Ritual of Id.Ritual.t + [@@bs.deriving accessors] + + module Decode = struct + open Decoders_bs.Decode + + let t = + field "tag" string + >>= function + | "Spell" -> decode_one Id.Spell.from_int spell + | "Ritual" -> decode_one Id.Ritual.from_int ritual + | _ -> fail "Expected a spellwork category" + end +end + module ActivatableAndSkill = struct type t = | Activatable of Activatable.t @@ -561,9 +599,35 @@ module AnimistPower = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "AnimistPower" -> decode_one Id.AnimistPower.from_int animistPower | _ -> fail "Expected the animist power category" end end + +module Application = struct + type t = Generic of int | Region of Id.Region.t | Disease of Id.Disease.t + + include Make (struct + type nonrec t = t + + let outer_to_int = function + | Generic _ -> 0 + | Region _ -> 1 + | Disease _ -> 2 + + let compare a b = + match (a, b) with + | Generic a', Generic b' -> a' - b' + | Region a', Region b' -> Id.Region.compare a' b' + | Disease a', Disease b' -> Id.Disease.compare a' b' + | (Generic _ as a), (Region _ as b) + | (Generic _ as a), (Disease _ as b) + | (Region _ as a), (Generic _ as b) + | (Region _ as a), (Disease _ as b) + | (Disease _ as a), (Generic _ as b) + | (Disease _ as a), (Region _ as b) -> + outer_to_int a - outer_to_int b + end) +end diff --git a/src/Common/IdGroup.mli b/src/Common/IdGroup.mli index 4bf83c25..3319622b 100644 --- a/src/Common/IdGroup.mli +++ b/src/Common/IdGroup.mli @@ -8,6 +8,18 @@ Each module works exactly the same way, which is outlined above, and why no duplicate documentation is present below. *) +module type IdGroup = sig + type t + + val compare : t -> t -> int + (** [compare x y] returns [0] if [x] is equal to [y], a negative integer if + [x] is less than [y], and a positive integer if [x] is greater than [y]. + *) + + module Map : MapX.T with type key = t + (** A configured [Map] module with the identifier variant as the key. *) +end + module ExtensionRule : sig type t = FocusRule of Id.FocusRule.t | OptionalRule of Id.OptionalRule.t @@ -225,6 +237,14 @@ module ActivatableSkill : sig end end +module Spellwork : sig + type t = Spell of Id.Spell.t | Ritual of Id.Ritual.t + + module Decode : sig + val t : t Decoders_bs.Decode.decoder + end +end + module ActivatableAndSkill : sig type t = | Activatable of Activatable.t @@ -242,3 +262,9 @@ module AnimistPower : sig val t : t Decoders_bs.Decode.decoder end end + +module Application : sig + type t = Generic of int | Region of Id.Region.t | Disease of Id.Disease.t + + include IdGroup with type t := t +end diff --git a/src/Common/Patron.ml b/src/Common/Patron.ml index 2b8f3326..dc58dfbd 100644 --- a/src/Common/Patron.ml +++ b/src/Common/Patron.ml @@ -14,18 +14,18 @@ module Category = struct type multilingual = { id : int; - primaryPatronCultures : int list; + primary_patron_cultures : Id.Culture.Set.t; translations : translation TranslationMap.t; } let multilingual = field "id" int >>= fun id -> - field "primaryPatronCultures" (list int) - >>= fun primaryPatronCultures -> + field "primary_patron_cultures" Id.Culture.Decode.set + >>= fun primary_patron_cultures -> field "translations" (TranslationMap.Decode.t translation) >>= fun translations -> - succeed { id; primaryPatronCultures; translations } + succeed { id; primary_patron_cultures; translations } let make_assoc locale_order = let open Option.Infix in @@ -38,12 +38,13 @@ module Category = struct { id = multilingual.id; name = translation.name; - primary_patron_cultures = - multilingual.primaryPatronCultures |> Id.Culture.Set.from_int_list; + primary_patron_cultures = multilingual.primary_patron_cultures; } ) end end +type culture = All | Only of Id.Culture.Set.t | Except of Id.Culture.Set.t + type combat_value = | Attack | Parry @@ -67,8 +68,7 @@ type t = { name : string; category : int; skills : Id.Skill.t * Id.Skill.t * Id.Skill.t; - limited_to_cultures : Id.Culture.Set.t; - is_limited_to_cultures_reverse : bool; + culture : culture; powers : power NonEmptyList.t list; cost : int option; ic : ImprovementCost.t option; @@ -77,9 +77,15 @@ type t = { module Decode = struct open Decoders_bs.Decode - type translation = { name : string } - - let translation = field "name" string >>= fun name -> succeed { name } + let culture = + field "tag" string + >>= function + | "All" -> succeed All + | "Only" -> + field "list" Id.Culture.Decode.set >>= fun list -> succeed (Only list) + | "Except" -> + field "list" Id.Culture.Decode.set >>= fun list -> succeed (Except list) + | _ -> fail "Expected a culture" let combat_value = string @@ -96,37 +102,36 @@ module Decode = struct field "type" string >>= function | "Advantage" -> - field "value" - (field "id" Id.Advantage.Decode.t - >>= fun id -> - field_opt "level" int - >>= fun level -> - field_opt "option" int - >>= fun option -> succeed (Advantage { id; level; option })) + field "id" Id.Advantage.Decode.t + >>= fun id -> + field_opt "level" int + >>= fun level -> + field_opt "option" int + >>= fun option -> succeed (Advantage { id; level; option }) | "Skill" -> - field "value" - (field "id" Id.Skill.Decode.t - >>= fun id -> - field "value" int >>= fun value -> succeed (Skill { id; value })) + field "id" Id.Skill.Decode.t + >>= fun id -> + field "value" int >>= fun value -> succeed (Skill { id; value }) | "Combat" -> - field "value" - (field "id" combat_value - >>= fun combat_value -> - field "value" int - >>= fun value -> succeed (Combat { combat_value; value })) + field "id" combat_value + >>= fun combat_value -> + field "value" int + >>= fun value -> succeed (Combat { combat_value; value }) | "Attribute" -> - field "value" - (field "id" Id.Attribute.Decode.t - >>= fun id -> - field "value" int >>= fun value -> succeed (Attribute { id; value })) + field "id" Id.Attribute.Decode.t + >>= fun id -> + field "value" int >>= fun value -> succeed (Attribute { id; value }) | _ -> fail "Expected a power" + type translation = { name : string } + + let translation = field "name" string >>= fun name -> succeed { name } + type multilingual = { id : int; category : int; skills : Id.Skill.t * Id.Skill.t * Id.Skill.t; - limitedToCultures : int list; - isLimitedToCulturesReverse : bool; + culture : culture; powers : power NonEmptyList.t NonEmptyList.t option; cost : int option; ic : ImprovementCost.t option; @@ -139,37 +144,22 @@ module Decode = struct field "category" int >>= fun category -> field "skills" - Parsing.Infix.( - Id.Skill.Decode.t - >>=:: fun id1 -> - Id.Skill.Decode.t - >>=:: fun id2 -> - Id.Skill.Decode.t >>=:: fun id3 -> succeed (id1, id2, id3)) + (list Id.Skill.Decode.t + >>= function + | [ id1; id2; id3 ] -> succeed (id1, id2, id3) + | _ -> fail "Expected an array of three identifiers") >>= fun skills -> - field "limitedToCultures" (list int) - >>= fun limitedToCultures -> + field "culture" culture + >>= fun culture -> field_opt "powers" (NonEmptyList.Decode.t (NonEmptyList.Decode.t power)) >>= fun powers -> field_opt "cost" int >>= fun cost -> field_opt "ic" ImprovementCost.Decode.t >>= fun ic -> - field "isLimitedToCulturesReverse" bool - >>= fun isLimitedToCulturesReverse -> field "translations" (TranslationMap.Decode.t translation) >>= fun translations -> - succeed - { - id; - category; - skills; - limitedToCultures; - powers; - cost; - ic; - isLimitedToCulturesReverse; - translations; - } + succeed { id; category; skills; culture; powers; cost; ic; translations } let make_assoc locale_order = let open Option.Infix in @@ -184,12 +174,10 @@ module Decode = struct name = translation.name; category = multilingual.category; skills = multilingual.skills; - limited_to_cultures = - multilingual.limitedToCultures |> Id.Culture.Set.from_int_list; + culture = multilingual.culture; powers = multilingual.powers |> Option.fold ~none:[] ~some:NonEmptyList.to_list; cost = multilingual.cost; ic = multilingual.ic; - is_limited_to_cultures_reverse = multilingual.isLimitedToCulturesReverse; } ) end diff --git a/src/Common/Patron.mli b/src/Common/Patron.mli index 1ca6b9e8..e98f92de 100644 --- a/src/Common/Patron.mli +++ b/src/Common/Patron.mli @@ -14,6 +14,11 @@ module Category : sig end end +(** The patron is only available to a certain set of cultures. It may be + available to all, it may be available to only specific ones and it may be + available to all except specific ones to the listed cultures. *) +type culture = All | Only of Id.Culture.Set.t | Except of Id.Culture.Set.t + (** The target value of a combat power. *) type combat_value = | Attack @@ -39,8 +44,7 @@ type t = { name : string; category : int; skills : Id.Skill.t * Id.Skill.t * Id.Skill.t; - limited_to_cultures : Id.Culture.Set.t; - is_limited_to_cultures_reverse : bool; + culture : culture; powers : power NonEmptyList.t list; (** The list represents the powers for different levels of an animal power that grants them based on the primary patron. So the powers at index 0 diff --git a/src/Common/Region.ml b/src/Common/Region.ml new file mode 100644 index 00000000..4c6e5124 --- /dev/null +++ b/src/Common/Region.ml @@ -0,0 +1,29 @@ +type t = { id : Id.Region.t; name : string } + +module Decode = struct + open Decoders_bs.Decode + + type translation = { name : string } + + let translation = field "name" string >>= fun name -> succeed { name } + + type multilingual = { + id : Id.Region.t; + translations : translation TranslationMap.t; + } + + let multilingual = + field "id" Id.Region.Decode.t + >>= fun id -> + field "translations" (TranslationMap.Decode.t translation) + >>= fun translations -> succeed { id; translations } + + let make_assoc locale_order = + let open Option.Infix in + multilingual + >|= fun multilingual -> + multilingual.translations + |> TranslationMap.preferred locale_order + <&> fun translation -> + (multilingual.id, { id = multilingual.id; name = translation.name }) +end diff --git a/src/Common/Region.mli b/src/Common/Region.mli new file mode 100644 index 00000000..674439bb --- /dev/null +++ b/src/Common/Region.mli @@ -0,0 +1,9 @@ +(** This module contains definitions and simple utility functions for the + regions of Aventuria. *) + +type t = { id : Id.Region.t; name : string } +(** The region type. *) + +module Decode : sig + val make_assoc : (Id.Region.t, t) Parsing.make_assoc +end diff --git a/src/Common/Static.ml b/src/Common/Static.ml index c95c1372..7279514c 100644 --- a/src/Common/Static.ml +++ b/src/Common/Static.ml @@ -7,21 +7,21 @@ type t = { (* animal_shapes : AnimalShape.t IntMap.t; *) (* animal_shape_paths : string IntMap.t; *) (* animal_shape_sizes : AnimalShape.Size.t IntMap.t; *) - (* animist_forces : Animistenkraft.Static.t IntMap.t; *) + animist_powers : AnimistPower.Static.t Id.AnimistPower.Map.t; (* arcane_bard_traditions : ArcaneTradition.t IntMap.t; *) (* arcane_dancer_traditions : ArcaneTradition.t IntMap.t; *) (* armors : abc IntMap.t; *) (* armor_types : string IntMap.t; *) (* aspects : Aspect.t IntMap.t; *) (* attire_enchantments : AttireEnchantment.Static.t IntMap.t; *) - (* attributes : Attribute.Static.t IntMap.t; *) + attributes : Attribute.Static.t Id.Attribute.Map.t; (* blessed_traditions : BlessedTradition.Static.t IntMap.t; *) (* blessings : Blessing.Static.t IntMap.t; *) (* brawling_special_abilities : BrawlingSpecialAbility.Static.t IntMap.t; *) (* brews : string IntMap.t; *) (* cantrips : Cantrip.Static.t IntMap.t; *) (* ceremonial_item_special_abilities : CeremonialItemSpecialAbility.Static.t IntMap.t; *) - (* ceremonies : Ceremony.Static.t IntMap.t; *) + ceremonies : Ceremony.Static.t Id.Ceremony.Map.t; (* chronikzauber : Chronikzauber.Static.t IntMap.t; *) (* combat_special_abilities : CombatSpecialAbility.Static.t IntMap.t; *) (* combat_special_ability_groups : string IntMap.t; *) @@ -32,85 +32,88 @@ type t = { (* core_rules : CoreRule.t IntMap.t; *) (* cultures : Culture.Static.t IntMap.t; *) (* curricula : Curriculum.Static.t IntMap.t; *) - (* curses : Curse.Static.t IntMap.t; *) + curses : Curse.Static.t Id.Curse.Map.t; (* dagger_rituals : DaggerRitual.Static.t IntMap.t; *) (* derived_characteristics : DerivedCharacteristic.Static.t IntMap.t; *) (* disadvantages : Disadvantage.Static.t IntMap.t; *) - (* diseases : Disease.t IntMap.t; *) - (* domination_rituals : DominationRitual.Static.t IntMap.t; *) + diseases : Disease.t Id.Disease.Map.t; + domination_rituals : DominationRitual.Static.t Id.DominationRitual.Map.t; (* elements : Element.t IntMap.t; *) - (* elven_magical_songs : ElvenMagicalSong.Static.t IntMap.t; *) + elven_magical_songs : ElvenMagicalSong.Static.t Id.ElvenMagicalSong.Map.t; (* equipment_packages : EquipmentPackage.t IntMap.t; *) (* erweiterte_talentsonderfertigkeiten : ErweiterteTalentsonderfertigkeit.Static.t IntMap.t; *) experience_levels : ExperienceLevel.t Id.ExperienceLevel.Map.t; - (* eye_colors : string IntMap.t; *) - (* familiar_special_abilities : FamiliarSpecialAbility.Static.t IntMap.t; *) - (* fate_point_special_abilities : FatePointSpecialAbility.Static.t IntMap.t; *) - (* focus_rules : FocusRule.Static.t IntMap.t; *) - (* general_special_abilities : GeneralSpecialAbility.Static.t IntMap.t; *) - (* geodenrituale : Geodenritual.Static.t IntMap.t; *) - (* hair_colors : string IntMap.t; *) - (* instrument_enchantments : InstrumentEnchantment.Static.t IntMap.t; *) - (* items : Item.t IntMap.t; *) - (* item_groups : string IntMap.t; *) - (* kappenzauber : Kappenzauber.Static.t IntMap.t; *) - (* karma_special_abilities : KarmaSpecialAbility.Static.t IntMap.t; *) - (* kesselzauber : Kesselzauber.Static.t IntMap.t; *) - (* kugelzauber : Kugelzauber.Static.t IntMap.t; *) - (* languages : Language.t IntMap.t; *) - (* liturgical_chants : LiturgicalChant.Static.t IntMap.t; *) - (* liturgical_chant_groups : string IntMap.t; *) - (* liturgical_style_special_abilities : LiturgicalStyleSpecialAbility.Static.t IntMap.t; *) - (* lykanthropische_gaben : LykanthropischeGabe.Static.t IntMap.t; *) - (* magical_dances : MagicalDance.Static.t IntMap.t; *) - (* magical_melodies : MagicalMelody.Static.t IntMap.t; *) - (* magical_special_abilities : MagicalSpecialAbility.Static.t IntMap.t; *) - (* magical_traditions : MagicalTradition.Static.t IntMap.t; *) - (* magic_style_special_abilities : MagicStyleSpecialAbility.Static.t IntMap.t; *) - (* melee_combat_techniques : CombatTechnique.Melee.Static.t IntMap.t; *) - (* optional_rules : OptionalRule.Static.t IntMap.t; *) - (* orb_enchantments : OrbEnchantment.Static.t IntMap.t; *) - (* pact : Pact.Static.t IntMap.t; *) - (* paktgeschenke : Paktgeschenk.Static.t IntMap.t; *) - (* patrons : Patron.t IntMap.t; *) - (* patron_categories : Patron.Category.t IntMap.t; *) - (* poisons : Poison.t IntMap.t; *) - (* professions : Profession.Static.t IntMap.t; *) - (* properties : Property.t IntMap.t; *) - (* protective_warding_circle_special_abilities : ProtectiveWardingCircleSpecialAbility.Static.t IntMap.t; *) - (* publications : Publication.t IntMap.t; *) - (* races : Race.Static.t IntMap.t; *) - (* ranged_combat_techniques : CombatTechnique.Ranged.Static.t IntMap.t; *) - (* reaches : string IntMap.t; *) - (* ringzauber : Ringzauber.Static.t IntMap.t; *) - (* rituals : Ritual.Static.t IntMap.t; *) - (* schalenzauber : Schalenzauber.Static.t IntMap.t; *) - (* schelmenzauber : Schelmenzauber.Static.t IntMap.t; *) - (* scripts : Script.t IntMap.t; *) - (* sermons : Sermon.Static.t IntMap.t; *) - (* sex_schicksalspunkte_sonderfertigkeiten : SexSchicksalspunkteSonderfertigkeit.Static.t IntMap.t; *) - (* sex_sonderfertigkeiten : SexSonderfertigkeit.Static.t IntMap.t; *) - (* sichelrituale : Sichelritual.Static.t IntMap.t; *) - (* sikaryan_raub_sonderfertigkeiten : SikaryanRaubSonderfertigkeit.Static.t IntMap.t; *) - (* skills : Skill.Static.t Id.Skill.Map.t; *) - (* skill_groups : Skill.Group.t IntMap.t; *) - (* social_statuses : string IntMap.t; *) - (* special_ability_groups : string IntMap.t; *) - (* spells : Spell.Static.t IntMap.t; *) - (* spell_groups : string IntMap.t; *) - (* spell_sword_enchantments : SpellSwordEnchantment.Static.t IntMap.t; *) - (* spielzeugzauber : Spielzeugzauber.Static.t IntMap.t; *) - (* staff_enchantments : StaffEnchantment.Static.t IntMap.t; *) - (* states : State.Static.t IntMap.t; *) - (* subjects : string IntMap.t; *) - (* talentstilsonderfertigkeiten : Talentstilsonderfertigkeit.Static.t IntMap.t; *) - (* trade_secrets : TradeSecret.t IntMap.t; *) - (* tribes : string IntMap.t; *) - (* ui : Messages.t IntMap.t; *) - (* vampirische_gaben : VampirischeGabe.Static.t IntMap.t; *) - (* visions : Vision.Static.t IntMap.t; *) - (* waffenzauber : Waffenzauber.Static.t IntMap.t; *) - (* wand_enchantments : WandEnchantment.Static.t IntMap.t; *) - (* weapons : abc IntMap.t; *) - (* zibiljarituale : Zibiljaritual.Static.t IntMap.t; *) + (* eye_colors : string IntMap.t; *) + (* familiar_special_abilities : FamiliarSpecialAbility.Static.t IntMap.t; *) + (* fate_point_special_abilities : FatePointSpecialAbility.Static.t IntMap.t; *) + focus_rules : FocusRule.Static.t Id.FocusRule.Map.t; + (* general_special_abilities : GeneralSpecialAbility.Static.t IntMap.t; *) + geode_rituals : GeodeRitual.Static.t Id.GeodeRitual.Map.t; + (* hair_colors : string IntMap.t; *) + (* instrument_enchantments : InstrumentEnchantment.Static.t IntMap.t; *) + (* items : Item.t IntMap.t; *) + (* item_groups : string IntMap.t; *) + (* kappenzauber : Kappenzauber.Static.t IntMap.t; *) + (* karma_special_abilities : KarmaSpecialAbility.Static.t IntMap.t; *) + (* kesselzauber : Kesselzauber.Static.t IntMap.t; *) + (* kugelzauber : Kugelzauber.Static.t IntMap.t; *) + (* languages : Language.t IntMap.t; *) + liturgical_chants : LiturgicalChant.Static.t Id.LiturgicalChant.Map.t; + (* liturgical_chant_groups : string IntMap.t; *) + (* liturgical_style_special_abilities : LiturgicalStyleSpecialAbility.Static.t IntMap.t; *) + (* lykanthropische_gaben : LykanthropischeGabe.Static.t IntMap.t; *) + magical_dances : MagicalDance.Static.t Id.MagicalDance.Map.t; + magical_melodies : MagicalMelody.Static.t Id.MagicalMelody.Map.t; + (* magical_special_abilities : MagicalSpecialAbility.Static.t IntMap.t; *) + (* magical_traditions : MagicalTradition.Static.t IntMap.t; *) + (* magic_style_special_abilities : MagicStyleSpecialAbility.Static.t IntMap.t; *) + melee_combat_techniques : + CombatTechnique.Melee.Static.t Id.MeleeCombatTechnique.Map.t; + optional_rules : OptionalRule.Static.t Id.OptionalRule.Map.t; + (* orb_enchantments : OrbEnchantment.Static.t IntMap.t; *) + (* pact : Pact.Static.t IntMap.t; *) + (* paktgeschenke : Paktgeschenk.Static.t IntMap.t; *) + patrons : Patron.t IntMap.t; + patron_categories : Patron.Category.t IntMap.t; + (* poisons : Poison.t IntMap.t; *) + (* professions : Profession.Static.t IntMap.t; *) + (* properties : Property.t IntMap.t; *) + (* protective_warding_circle_special_abilities : ProtectiveWardingCircleSpecialAbility.Static.t IntMap.t; *) + publications : Publication.t Id.Publication.Map.t; + (* races : Race.Static.t IntMap.t; *) + ranged_combat_techniques : + CombatTechnique.Ranged.Static.t Id.RangedCombatTechnique.Map.t; + (* reaches : string IntMap.t; *) + regions : Region.t Id.Region.Map.t; + (* ringzauber : Ringzauber.Static.t IntMap.t; *) + rituals : Ritual.Static.t Id.Ritual.Map.t; + (* schalenzauber : Schalenzauber.Static.t IntMap.t; *) + jester_tricks : JesterTrick.Static.t Id.JesterTrick.Map.t; + (* scripts : Script.t IntMap.t; *) + (* sermons : Sermon.Static.t IntMap.t; *) + (* sex_schicksalspunkte_sonderfertigkeiten : SexSchicksalspunkteSonderfertigkeit.Static.t IntMap.t; *) + (* sex_sonderfertigkeiten : SexSonderfertigkeit.Static.t IntMap.t; *) + (* sichelrituale : Sichelritual.Static.t IntMap.t; *) + (* sikaryan_raub_sonderfertigkeiten : SikaryanRaubSonderfertigkeit.Static.t IntMap.t; *) + skills : Skill.Static.t Id.Skill.Map.t; + skill_groups : Skill.Group.t IntMap.t; + (* social_statuses : string IntMap.t; *) + (* special_ability_groups : string IntMap.t; *) + spells : Spell.Static.t Id.Spell.Map.t; + (* spell_groups : string IntMap.t; *) + (* spell_sword_enchantments : SpellSwordEnchantment.Static.t IntMap.t; *) + (* spielzeugzauber : Spielzeugzauber.Static.t IntMap.t; *) + (* staff_enchantments : StaffEnchantment.Static.t IntMap.t; *) + (* states : State.Static.t IntMap.t; *) + (* subjects : string IntMap.t; *) + (* talentstilsonderfertigkeiten : Talentstilsonderfertigkeit.Static.t IntMap.t; *) + (* trade_secrets : TradeSecret.t IntMap.t; *) + (* tribes : string IntMap.t; *) + (* ui : Messages.t IntMap.t; *) + (* vampirische_gaben : VampirischeGabe.Static.t IntMap.t; *) + (* visions : Vision.Static.t IntMap.t; *) + (* waffenzauber : Waffenzauber.Static.t IntMap.t; *) + (* wand_enchantments : WandEnchantment.Static.t IntMap.t; *) + (* weapons : abc IntMap.t; *) + zibilja_rituals : ZibiljaRitual.Static.t Id.ZibiljaRitual.Map.t; } diff --git a/src/Common/Static.mli b/src/Common/Static.mli index c95c1372..7279514c 100644 --- a/src/Common/Static.mli +++ b/src/Common/Static.mli @@ -7,21 +7,21 @@ type t = { (* animal_shapes : AnimalShape.t IntMap.t; *) (* animal_shape_paths : string IntMap.t; *) (* animal_shape_sizes : AnimalShape.Size.t IntMap.t; *) - (* animist_forces : Animistenkraft.Static.t IntMap.t; *) + animist_powers : AnimistPower.Static.t Id.AnimistPower.Map.t; (* arcane_bard_traditions : ArcaneTradition.t IntMap.t; *) (* arcane_dancer_traditions : ArcaneTradition.t IntMap.t; *) (* armors : abc IntMap.t; *) (* armor_types : string IntMap.t; *) (* aspects : Aspect.t IntMap.t; *) (* attire_enchantments : AttireEnchantment.Static.t IntMap.t; *) - (* attributes : Attribute.Static.t IntMap.t; *) + attributes : Attribute.Static.t Id.Attribute.Map.t; (* blessed_traditions : BlessedTradition.Static.t IntMap.t; *) (* blessings : Blessing.Static.t IntMap.t; *) (* brawling_special_abilities : BrawlingSpecialAbility.Static.t IntMap.t; *) (* brews : string IntMap.t; *) (* cantrips : Cantrip.Static.t IntMap.t; *) (* ceremonial_item_special_abilities : CeremonialItemSpecialAbility.Static.t IntMap.t; *) - (* ceremonies : Ceremony.Static.t IntMap.t; *) + ceremonies : Ceremony.Static.t Id.Ceremony.Map.t; (* chronikzauber : Chronikzauber.Static.t IntMap.t; *) (* combat_special_abilities : CombatSpecialAbility.Static.t IntMap.t; *) (* combat_special_ability_groups : string IntMap.t; *) @@ -32,85 +32,88 @@ type t = { (* core_rules : CoreRule.t IntMap.t; *) (* cultures : Culture.Static.t IntMap.t; *) (* curricula : Curriculum.Static.t IntMap.t; *) - (* curses : Curse.Static.t IntMap.t; *) + curses : Curse.Static.t Id.Curse.Map.t; (* dagger_rituals : DaggerRitual.Static.t IntMap.t; *) (* derived_characteristics : DerivedCharacteristic.Static.t IntMap.t; *) (* disadvantages : Disadvantage.Static.t IntMap.t; *) - (* diseases : Disease.t IntMap.t; *) - (* domination_rituals : DominationRitual.Static.t IntMap.t; *) + diseases : Disease.t Id.Disease.Map.t; + domination_rituals : DominationRitual.Static.t Id.DominationRitual.Map.t; (* elements : Element.t IntMap.t; *) - (* elven_magical_songs : ElvenMagicalSong.Static.t IntMap.t; *) + elven_magical_songs : ElvenMagicalSong.Static.t Id.ElvenMagicalSong.Map.t; (* equipment_packages : EquipmentPackage.t IntMap.t; *) (* erweiterte_talentsonderfertigkeiten : ErweiterteTalentsonderfertigkeit.Static.t IntMap.t; *) experience_levels : ExperienceLevel.t Id.ExperienceLevel.Map.t; - (* eye_colors : string IntMap.t; *) - (* familiar_special_abilities : FamiliarSpecialAbility.Static.t IntMap.t; *) - (* fate_point_special_abilities : FatePointSpecialAbility.Static.t IntMap.t; *) - (* focus_rules : FocusRule.Static.t IntMap.t; *) - (* general_special_abilities : GeneralSpecialAbility.Static.t IntMap.t; *) - (* geodenrituale : Geodenritual.Static.t IntMap.t; *) - (* hair_colors : string IntMap.t; *) - (* instrument_enchantments : InstrumentEnchantment.Static.t IntMap.t; *) - (* items : Item.t IntMap.t; *) - (* item_groups : string IntMap.t; *) - (* kappenzauber : Kappenzauber.Static.t IntMap.t; *) - (* karma_special_abilities : KarmaSpecialAbility.Static.t IntMap.t; *) - (* kesselzauber : Kesselzauber.Static.t IntMap.t; *) - (* kugelzauber : Kugelzauber.Static.t IntMap.t; *) - (* languages : Language.t IntMap.t; *) - (* liturgical_chants : LiturgicalChant.Static.t IntMap.t; *) - (* liturgical_chant_groups : string IntMap.t; *) - (* liturgical_style_special_abilities : LiturgicalStyleSpecialAbility.Static.t IntMap.t; *) - (* lykanthropische_gaben : LykanthropischeGabe.Static.t IntMap.t; *) - (* magical_dances : MagicalDance.Static.t IntMap.t; *) - (* magical_melodies : MagicalMelody.Static.t IntMap.t; *) - (* magical_special_abilities : MagicalSpecialAbility.Static.t IntMap.t; *) - (* magical_traditions : MagicalTradition.Static.t IntMap.t; *) - (* magic_style_special_abilities : MagicStyleSpecialAbility.Static.t IntMap.t; *) - (* melee_combat_techniques : CombatTechnique.Melee.Static.t IntMap.t; *) - (* optional_rules : OptionalRule.Static.t IntMap.t; *) - (* orb_enchantments : OrbEnchantment.Static.t IntMap.t; *) - (* pact : Pact.Static.t IntMap.t; *) - (* paktgeschenke : Paktgeschenk.Static.t IntMap.t; *) - (* patrons : Patron.t IntMap.t; *) - (* patron_categories : Patron.Category.t IntMap.t; *) - (* poisons : Poison.t IntMap.t; *) - (* professions : Profession.Static.t IntMap.t; *) - (* properties : Property.t IntMap.t; *) - (* protective_warding_circle_special_abilities : ProtectiveWardingCircleSpecialAbility.Static.t IntMap.t; *) - (* publications : Publication.t IntMap.t; *) - (* races : Race.Static.t IntMap.t; *) - (* ranged_combat_techniques : CombatTechnique.Ranged.Static.t IntMap.t; *) - (* reaches : string IntMap.t; *) - (* ringzauber : Ringzauber.Static.t IntMap.t; *) - (* rituals : Ritual.Static.t IntMap.t; *) - (* schalenzauber : Schalenzauber.Static.t IntMap.t; *) - (* schelmenzauber : Schelmenzauber.Static.t IntMap.t; *) - (* scripts : Script.t IntMap.t; *) - (* sermons : Sermon.Static.t IntMap.t; *) - (* sex_schicksalspunkte_sonderfertigkeiten : SexSchicksalspunkteSonderfertigkeit.Static.t IntMap.t; *) - (* sex_sonderfertigkeiten : SexSonderfertigkeit.Static.t IntMap.t; *) - (* sichelrituale : Sichelritual.Static.t IntMap.t; *) - (* sikaryan_raub_sonderfertigkeiten : SikaryanRaubSonderfertigkeit.Static.t IntMap.t; *) - (* skills : Skill.Static.t Id.Skill.Map.t; *) - (* skill_groups : Skill.Group.t IntMap.t; *) - (* social_statuses : string IntMap.t; *) - (* special_ability_groups : string IntMap.t; *) - (* spells : Spell.Static.t IntMap.t; *) - (* spell_groups : string IntMap.t; *) - (* spell_sword_enchantments : SpellSwordEnchantment.Static.t IntMap.t; *) - (* spielzeugzauber : Spielzeugzauber.Static.t IntMap.t; *) - (* staff_enchantments : StaffEnchantment.Static.t IntMap.t; *) - (* states : State.Static.t IntMap.t; *) - (* subjects : string IntMap.t; *) - (* talentstilsonderfertigkeiten : Talentstilsonderfertigkeit.Static.t IntMap.t; *) - (* trade_secrets : TradeSecret.t IntMap.t; *) - (* tribes : string IntMap.t; *) - (* ui : Messages.t IntMap.t; *) - (* vampirische_gaben : VampirischeGabe.Static.t IntMap.t; *) - (* visions : Vision.Static.t IntMap.t; *) - (* waffenzauber : Waffenzauber.Static.t IntMap.t; *) - (* wand_enchantments : WandEnchantment.Static.t IntMap.t; *) - (* weapons : abc IntMap.t; *) - (* zibiljarituale : Zibiljaritual.Static.t IntMap.t; *) + (* eye_colors : string IntMap.t; *) + (* familiar_special_abilities : FamiliarSpecialAbility.Static.t IntMap.t; *) + (* fate_point_special_abilities : FatePointSpecialAbility.Static.t IntMap.t; *) + focus_rules : FocusRule.Static.t Id.FocusRule.Map.t; + (* general_special_abilities : GeneralSpecialAbility.Static.t IntMap.t; *) + geode_rituals : GeodeRitual.Static.t Id.GeodeRitual.Map.t; + (* hair_colors : string IntMap.t; *) + (* instrument_enchantments : InstrumentEnchantment.Static.t IntMap.t; *) + (* items : Item.t IntMap.t; *) + (* item_groups : string IntMap.t; *) + (* kappenzauber : Kappenzauber.Static.t IntMap.t; *) + (* karma_special_abilities : KarmaSpecialAbility.Static.t IntMap.t; *) + (* kesselzauber : Kesselzauber.Static.t IntMap.t; *) + (* kugelzauber : Kugelzauber.Static.t IntMap.t; *) + (* languages : Language.t IntMap.t; *) + liturgical_chants : LiturgicalChant.Static.t Id.LiturgicalChant.Map.t; + (* liturgical_chant_groups : string IntMap.t; *) + (* liturgical_style_special_abilities : LiturgicalStyleSpecialAbility.Static.t IntMap.t; *) + (* lykanthropische_gaben : LykanthropischeGabe.Static.t IntMap.t; *) + magical_dances : MagicalDance.Static.t Id.MagicalDance.Map.t; + magical_melodies : MagicalMelody.Static.t Id.MagicalMelody.Map.t; + (* magical_special_abilities : MagicalSpecialAbility.Static.t IntMap.t; *) + (* magical_traditions : MagicalTradition.Static.t IntMap.t; *) + (* magic_style_special_abilities : MagicStyleSpecialAbility.Static.t IntMap.t; *) + melee_combat_techniques : + CombatTechnique.Melee.Static.t Id.MeleeCombatTechnique.Map.t; + optional_rules : OptionalRule.Static.t Id.OptionalRule.Map.t; + (* orb_enchantments : OrbEnchantment.Static.t IntMap.t; *) + (* pact : Pact.Static.t IntMap.t; *) + (* paktgeschenke : Paktgeschenk.Static.t IntMap.t; *) + patrons : Patron.t IntMap.t; + patron_categories : Patron.Category.t IntMap.t; + (* poisons : Poison.t IntMap.t; *) + (* professions : Profession.Static.t IntMap.t; *) + (* properties : Property.t IntMap.t; *) + (* protective_warding_circle_special_abilities : ProtectiveWardingCircleSpecialAbility.Static.t IntMap.t; *) + publications : Publication.t Id.Publication.Map.t; + (* races : Race.Static.t IntMap.t; *) + ranged_combat_techniques : + CombatTechnique.Ranged.Static.t Id.RangedCombatTechnique.Map.t; + (* reaches : string IntMap.t; *) + regions : Region.t Id.Region.Map.t; + (* ringzauber : Ringzauber.Static.t IntMap.t; *) + rituals : Ritual.Static.t Id.Ritual.Map.t; + (* schalenzauber : Schalenzauber.Static.t IntMap.t; *) + jester_tricks : JesterTrick.Static.t Id.JesterTrick.Map.t; + (* scripts : Script.t IntMap.t; *) + (* sermons : Sermon.Static.t IntMap.t; *) + (* sex_schicksalspunkte_sonderfertigkeiten : SexSchicksalspunkteSonderfertigkeit.Static.t IntMap.t; *) + (* sex_sonderfertigkeiten : SexSonderfertigkeit.Static.t IntMap.t; *) + (* sichelrituale : Sichelritual.Static.t IntMap.t; *) + (* sikaryan_raub_sonderfertigkeiten : SikaryanRaubSonderfertigkeit.Static.t IntMap.t; *) + skills : Skill.Static.t Id.Skill.Map.t; + skill_groups : Skill.Group.t IntMap.t; + (* social_statuses : string IntMap.t; *) + (* special_ability_groups : string IntMap.t; *) + spells : Spell.Static.t Id.Spell.Map.t; + (* spell_groups : string IntMap.t; *) + (* spell_sword_enchantments : SpellSwordEnchantment.Static.t IntMap.t; *) + (* spielzeugzauber : Spielzeugzauber.Static.t IntMap.t; *) + (* staff_enchantments : StaffEnchantment.Static.t IntMap.t; *) + (* states : State.Static.t IntMap.t; *) + (* subjects : string IntMap.t; *) + (* talentstilsonderfertigkeiten : Talentstilsonderfertigkeit.Static.t IntMap.t; *) + (* trade_secrets : TradeSecret.t IntMap.t; *) + (* tribes : string IntMap.t; *) + (* ui : Messages.t IntMap.t; *) + (* vampirische_gaben : VampirischeGabe.Static.t IntMap.t; *) + (* visions : Vision.Static.t IntMap.t; *) + (* waffenzauber : Waffenzauber.Static.t IntMap.t; *) + (* wand_enchantments : WandEnchantment.Static.t IntMap.t; *) + (* weapons : abc IntMap.t; *) + zibilja_rituals : ZibiljaRitual.Static.t Id.ZibiljaRitual.Map.t; } diff --git a/src/Dependencies/Prerequisite.ml b/src/Dependencies/Prerequisite.ml index e3caf8bf..f9aa79bf 100644 --- a/src/Dependencies/Prerequisite.ml +++ b/src/Dependencies/Prerequisite.ml @@ -17,7 +17,7 @@ module Sex = struct open Decoders_bs.Decode let t = - string + field "id" string >>= function | "Male" -> succeed Male | "Female" -> succeed Female @@ -32,16 +32,11 @@ module Race = struct open Decoders_bs.Decode let t = - one_of - [ - ( "Simple", - NonEmptyList.Decode.one_or_many int - >>= fun id -> succeed { id; active = true } ); - ( "Extended", - field "races" (NonEmptyList.Decode.one_or_many int) - >>= fun id -> - field "active" bool >>= fun active -> succeed { id; active } ); - ] + field "id" (NonEmptyList.Decode.one_or_many int) + >>= fun id -> + field_opt "active" bool + >>= fun active -> + succeed { id; active = Option.value ~default:false active } end end @@ -51,7 +46,7 @@ module Culture = struct module Decode = struct open Decoders_bs.Decode - let t = NonEmptyList.Decode.one_or_many int + let t = field "id" (NonEmptyList.Decode.one_or_many int) end end @@ -62,10 +57,12 @@ module PrimaryAttribute = struct open Decoders_bs.Decode let t = + field "value" int + >>= fun value -> field "type" string >>= function - | "Blessed" -> field "value" int >|= fun value -> Blessed value - | "Magical" -> field "value" int >|= fun value -> Magical value + | "Blessed" -> succeed (Blessed value) + | "Magical" -> succeed (Magical value) | _ -> fail "Expected a primary attribute type" end end @@ -93,7 +90,9 @@ module SocialStatus = struct type t = int module Decode = struct - let t = Decoders_bs.Decode.int + open Decoders_bs.Decode + + let t = field "id" int end end @@ -103,7 +102,7 @@ module State = struct module Decode = struct open Decoders_bs.Decode - let t = NonEmptyList.Decode.one_or_many int + let t = field "id" (NonEmptyList.Decode.one_or_many int) end end @@ -111,7 +110,9 @@ module Rule = struct type t = IdGroup.ExtensionRule.t module Decode = struct - let t = IdGroup.ExtensionRule.Decode.t + open Decoders_bs.Decode + + let t = field "id" IdGroup.ExtensionRule.Decode.t end end @@ -119,7 +120,9 @@ module Publication = struct type t = int module Decode = struct - let t = Decoders_bs.Decode.int + open Decoders_bs.Decode + + let t = field "id" int end end @@ -220,6 +223,33 @@ module Activatable = struct end end +module MagicalTradition = struct + type t = { can_learn_rituals : bool option; can_bind_familiars : bool option } + + module Decode = struct + open Decoders_bs.Decode + + let t = + field_opt "can_learn_rituals" bool + >>= fun can_learn_rituals -> + field_opt "can_bind_familiars" bool + >>= fun can_bind_familiars -> + succeed { can_learn_rituals; can_bind_familiars } + end +end + +module BlessedTradition = struct + type t = { is_shamanistic : bool option } + + module Decode = struct + open Decoders_bs.Decode + + let t = + field_opt "is_shamanistic" bool + >>= fun is_shamanistic -> succeed { is_shamanistic } + end +end + module Rated = struct module AnyOf = struct type t = { id : IdGroup.Rated.Many.t; value : int } @@ -259,11 +289,79 @@ module AnimistPower = struct end end -module Enhancement = struct - type t = int +module MinimumSkillRating = struct + type targets = + | Skills of Id.Skill.t list + | Spellworks of Id.Property.t + | Liturgies of Id.Aspect.t + + type t = { number : int; value : int; targets : targets } module Decode = struct - let t = Decoders_bs.Decode.int + open Decoders_bs.Decode + + let targets = + field "tag" string + >>= function + | "Skills" -> + field "id" (list Id.Skill.Decode.t) + >>= fun list -> succeed (Skills list) + | "Spellworks" -> + field "property" Id.Property.Decode.t + >>= fun property -> succeed (Spellworks property) + | "Liturgies" -> + field "aspect" Id.Aspect.Decode.t + >>= fun aspect -> succeed (Liturgies aspect) + | _ -> fail "Expected a skill rating target" + + let t = + field "number" int + >>= fun number -> + field "value" int + >>= fun value -> + field "targets" targets + >>= fun targets -> succeed { number; value; targets } + end +end + +module Enhancement = struct + module Internal = struct + type t = { id : int } + + module Decode = struct + open Decoders_bs.Decode + + let t = field "id" int >>= fun id -> succeed { id } + end + end + + type t = { spellwork : IdGroup.Spellwork.t; enhancement : int } + + module Decode = struct + open Decoders_bs.Decode + + let t = + field "spellwork" IdGroup.Spellwork.Decode.t + >>= fun spellwork -> + field "enhancement" int + >>= fun enhancement -> succeed { spellwork; enhancement } + end +end + +module Special = struct + type t = { text : string } + + module Decode = struct + open Decoders_bs.Decode + + let t locale_order = + field "text" (TranslationMap.Decode.t string) + >>= fun translation -> + translation + |> TranslationMap.preferred locale_order + |> function + | Some text -> succeed { text } + | None -> fail "Expected a prerequisite text" end end @@ -309,7 +407,7 @@ module When = struct open Decoders_bs.Decode let t = - field "type" string + field "tag" string >>= function | "Publication" -> field "value" Publication.Decode.t >|= fun x -> Publication x @@ -318,32 +416,32 @@ module When = struct end module Config = struct - type 'a t = { value : 'a; displayMode : DisplayMode.t; when_ : When.t list } + type 'a t = { value : 'a; display_mode : DisplayMode.t; when_ : When.t list } module Decode = struct open Decoders_bs.Decode type 'a multilingual = { value : 'a; - displayOption : DisplayMode.t option; + display_option : DisplayMode.t option; when_ : When.t NonEmptyList.t option; } let multilingual locale_order decoder wrap = - field "value" decoder + decoder >>= fun value -> - field_opt "displayOption" (DisplayMode.Decode.make locale_order) - >>= fun displayOption -> + field_opt "display_option" (DisplayMode.Decode.make locale_order) + >>= fun display_option -> field_opt "when" (NonEmptyList.Decode.t When.Decode.t) - >>= fun when_ -> succeed { value = value |> wrap; displayOption; when_ } + >>= fun when_ -> succeed { value = value |> wrap; display_option; when_ } let make locale_order decoder wrap = multilingual locale_order decoder wrap >|= fun multilingual : 'b t -> { value = multilingual.value; - displayMode = - multilingual.displayOption + display_mode = + multilingual.display_option |> Option.value ~default:DisplayMode.Generate; when_ = multilingual.when_ |> Option.fold ~none:[] ~some:NonEmptyList.to_list; @@ -367,9 +465,13 @@ module Group = struct | Activatable of Activatable.t | ActivatableAnyOf of Activatable.AnyOf.t | ActivatableAnyOfSelect of Activatable.AnyOf.Select.t + | MagicalTradition of MagicalTradition.t + | BlessedTradition of BlessedTradition.t | Rated of Rated.t | RatedAnyOf of Rated.AnyOf.t + | MinimumSkillRating of MinimumSkillRating.t | AnimistPower of AnimistPower.t + | Enhancement of Enhancement.t | Other type t = value Config.t @@ -388,8 +490,12 @@ module Group = struct | Activatable of Activatable.t | ActivatableAnyOf of Activatable.AnyOf.t | ActivatableAnyOfSelect of Activatable.AnyOf.Select.t + | MagicalTradition of MagicalTradition.t + | BlessedTradition of BlessedTradition.t | Rated of Rated.t | RatedAnyOf of Rated.AnyOf.t + | MinimumSkillRating of MinimumSkillRating.t + | Enhancement of Enhancement.t type t = value Config.t @@ -409,15 +515,19 @@ module Group = struct | Activatable x -> Activatable x | ActivatableAnyOf x -> ActivatableAnyOf x | ActivatableAnyOfSelect x -> ActivatableAnyOfSelect x + | MagicalTradition x -> MagicalTradition x + | BlessedTradition x -> BlessedTradition x | Rated x -> Rated x - | RatedAnyOf x -> RatedAnyOf x); + | RatedAnyOf x -> RatedAnyOf x + | MinimumSkillRating x -> MinimumSkillRating x + | Enhancement x -> Enhancement x); } module Decode = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Sex" -> Config.Decode.make locale_order Sex.Decode.t (fun v -> Sex v) | "Race" -> @@ -446,11 +556,23 @@ module Group = struct | "ActivatableMultiSelect" -> Config.Decode.make locale_order Activatable.AnyOf.Select.Decode.t (fun v -> ActivatableAnyOfSelect v) + | "MagicalTradition" -> + Config.Decode.make locale_order MagicalTradition.Decode.t (fun v -> + MagicalTradition v) + | "BlessedTradition" -> + Config.Decode.make locale_order BlessedTradition.Decode.t (fun v -> + BlessedTradition v) | "Increasable" -> Config.Decode.make locale_order Rated.Decode.t (fun v -> Rated v) | "IncreasableMultiEntry" -> Config.Decode.make locale_order Rated.AnyOf.Decode.t (fun v -> RatedAnyOf v) + | "MinimumSkillRating" -> + Config.Decode.make locale_order MinimumSkillRating.Decode.t + (fun v -> MinimumSkillRating v) + | "Enhancement" -> + Config.Decode.make locale_order Enhancement.Decode.t (fun v -> + Enhancement v) | _ -> fail "Expected special ability prerequisite type" end end @@ -481,7 +603,7 @@ module Group = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Sex" -> Config.Decode.make locale_order Sex.Decode.t (fun v -> Sex v) | "Race" -> @@ -512,8 +634,11 @@ module Group = struct | Activatable of Activatable.t | ActivatableAnyOf of Activatable.AnyOf.t | ActivatableAnyOfSelect of Activatable.AnyOf.Select.t + | MagicalTradition of MagicalTradition.t + | BlessedTradition of BlessedTradition.t | Rated of Rated.t | RatedAnyOf of Rated.AnyOf.t + | MinimumSkillRating of MinimumSkillRating.t type t = value Config.t @@ -534,21 +659,24 @@ module Group = struct | Activatable x -> Activatable x | ActivatableAnyOf x -> ActivatableAnyOf x | ActivatableAnyOfSelect x -> ActivatableAnyOfSelect x + | MagicalTradition x -> MagicalTradition x + | BlessedTradition x -> BlessedTradition x | Rated x -> Rated x - | RatedAnyOf x -> RatedAnyOf x); + | RatedAnyOf x -> RatedAnyOf x + | MinimumSkillRating x -> MinimumSkillRating x); } module Decode = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "CommonSuggestedByRCP" -> succeed ({ value = CommonSuggestedByRCP; - displayMode = Generate; + display_mode = Generate; when_ = []; } : t) @@ -579,11 +707,20 @@ module Group = struct | "ActivatableMultiSelect" -> Config.Decode.make locale_order Activatable.AnyOf.Select.Decode.t (fun v -> ActivatableAnyOfSelect v) + | "MagicalTradition" -> + Config.Decode.make locale_order MagicalTradition.Decode.t (fun v -> + MagicalTradition v) + | "BlessedTradition" -> + Config.Decode.make locale_order BlessedTradition.Decode.t (fun v -> + BlessedTradition v) | "Increasable" -> Config.Decode.make locale_order Rated.Decode.t (fun v -> Rated v) | "IncreasableMultiEntry" -> Config.Decode.make locale_order Rated.AnyOf.Decode.t (fun v -> RatedAnyOf v) + | "MinimumSkillRating" -> + Config.Decode.make locale_order MinimumSkillRating.Decode.t + (fun v -> MinimumSkillRating v) | _ -> fail "Expected advantage/disadvantage prerequisite type" end end @@ -603,7 +740,7 @@ module Group = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Sex" -> Config.Decode.make locale_order Sex.Decode.t (fun v -> Sex v) | "Culture" -> @@ -614,24 +751,26 @@ module Group = struct end module PersonalityTrait = struct - type value = Culture of Culture.t | Special + type value = Culture of Culture.t | Special of Special.t type t = value Config.t let unify (x : t) : Unified.t = { x with - value = (match x.value with Special -> Other | Culture x -> Culture x); + value = + (match x.value with Special _ -> Other | Culture x -> Culture x); } module Decode = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Special" -> - Config.Decode.make locale_order value (Function.const Special) + Config.Decode.make locale_order (Special.Decode.t locale_order) + (fun v -> Special v) | "Culture" -> Config.Decode.make locale_order Culture.Decode.t (fun v -> Culture v) @@ -654,11 +793,11 @@ module Group = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Rule" -> Config.Decode.make locale_order Rule.Decode.t (fun v -> Rule v) - | "Culture" -> + | "Increasable" -> Config.Decode.make locale_order Rated.Decode.t (fun v -> Rated v) | _ -> fail "Expected spellwork prerequisite type" end @@ -676,7 +815,7 @@ module Group = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Rule" -> Config.Decode.make locale_order Rule.Decode.t (fun v -> Rule v) @@ -700,7 +839,7 @@ module Group = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Special" -> Config.Decode.make locale_order value (Function.const Special) @@ -729,7 +868,7 @@ module Group = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "Race" -> Config.Decode.make locale_order Race.Decode.t (fun v -> Race v) @@ -752,7 +891,7 @@ module Group = struct open Decoders_bs.Decode let make locale_order = - field "type" string + field "tag" string >>= function | "AnimistPower" -> Config.Decode.make locale_order AnimistPower.Decode.t (fun v -> @@ -762,15 +901,16 @@ module Group = struct end module Enhancement = struct - type t = Enhancement of Enhancement.t + type t = Enhancement of Enhancement.Internal.t module Decode = struct open Decoders_bs.Decode let make _ = - field "type" string + field "tag" string >>= function - | "Enhancement" -> Enhancement.Decode.t |> map (fun v -> Enhancement v) + | "Enhancement" -> + Enhancement.Internal.Decode.t |> map (fun v -> Enhancement v) | _ -> fail "Expected enhancement prerequisite type" end end @@ -784,7 +924,7 @@ module Collection = struct open Decoders_bs.Decode let make decoder = - field "type" string + field "tag" string >>= function | "Plain" -> field "value" (list decoder) | _ -> fail "Expected collection type" @@ -822,7 +962,7 @@ module Collection = struct open Decoders_bs.Decode let make decoder = - field "type" string + field "tag" string >>= function | "Plain" -> field "value" (list decoder) |> map plain | "ByLevel" -> diff --git a/src/Dependencies/Prerequisite.mli b/src/Dependencies/Prerequisite.mli index 42f87ff4..bdec466b 100644 --- a/src/Dependencies/Prerequisite.mli +++ b/src/Dependencies/Prerequisite.mli @@ -146,6 +146,29 @@ module Activatable : sig end end +(** Magical tradition prerequisite. *) +module MagicalTradition : sig + type t = { + can_learn_rituals : bool option; + (** If defined, the tradition's ability to learn rituals must equal this + prerequisite. *) + can_bind_familiars : bool option; + (** If defined, the tradition's ability to bind familiars must equal + this prerequisite. *) + } + (** If no options are defined, this prerequisite requires any tradition. *) +end + +(** Blessed tradition prerequisite. *) +module BlessedTradition : sig + type t = { + is_shamanistic : bool option; + (** If defined, the tradition representing a church or shamanistic + tradition must equal this prerequisite. *) + } + (** If no options are defined, this prerequisite requires any tradition. *) +end + (** Rated prerequisite. *) module Rated : sig type t = { @@ -176,10 +199,48 @@ module AnimistPower : sig } end +(** Minimum number of skills skill rating prerequisite. *) +module MinimumSkillRating : sig + type targets = + | Skills of Id.Skill.t list + (** The target set is a list of specific skills. *) + | Spellworks of Id.Property.t + (** The target set is a list of all spellworks from a property. *) + | Liturgies of Id.Aspect.t + (** The target set is a list of all liturgies from an aspect. *) + + type t = { + number : int; (** The minimum number of skills. *) + value : int; (** The required value. *) + targets : targets; (** The target set. *) + } + (** A minimum number of skills from the target set is required to match a + minimum value. *) +end + (** Spellwork or liturgy enhancement prerequisite. *) module Enhancement : sig - type t = int - (** The identifier of the required enhancement of the associated entry. *) + type t = { + spellwork : IdGroup.Spellwork.t; + (** The identifier of the associated entry. *) + enhancement : int; + (** The identifier of the required enhancement of the associated entry. + *) + } + + module Internal : sig + type t = { + id : int; + (** The identifier of the required enhancement of the associated + entry. *) + } + end +end + +(** A prerequisite that cannot be ensured by Optolith but rely on roleplay or + other background information of the character. *) +module Special : sig + type t = { text : string } end (** The mode in which the prerequisite's text should be generated. *) @@ -202,7 +263,7 @@ end module Config : sig type 'a t = { value : 'a; (** The actual prerequisite definition *) - displayMode : DisplayMode.t; + display_mode : DisplayMode.t; (** The display mode for rendering the prerequisite as text. *) when_ : When.t list; (** If non-empty, the prerequisite only takes effect if all @@ -230,9 +291,13 @@ module Group : sig | Activatable of Activatable.t | ActivatableAnyOf of Activatable.AnyOf.t | ActivatableAnyOfSelect of Activatable.AnyOf.Select.t + | MagicalTradition of MagicalTradition.t + | BlessedTradition of BlessedTradition.t | Rated of Rated.t | RatedAnyOf of Rated.AnyOf.t + | MinimumSkillRating of MinimumSkillRating.t | AnimistPower of AnimistPower.t + | Enhancement of Enhancement.t | Other type t = value Config.t @@ -254,8 +319,12 @@ module Group : sig | Activatable of Activatable.t | ActivatableAnyOf of Activatable.AnyOf.t | ActivatableAnyOfSelect of Activatable.AnyOf.Select.t + | MagicalTradition of MagicalTradition.t + | BlessedTradition of BlessedTradition.t | Rated of Rated.t | RatedAnyOf of Rated.AnyOf.t + | MinimumSkillRating of MinimumSkillRating.t + | Enhancement of Enhancement.t type t = value Config.t (** Full configuration of a special ability prerequisite definition. *) @@ -298,8 +367,11 @@ module Group : sig | Activatable of Activatable.t | ActivatableAnyOf of Activatable.AnyOf.t | ActivatableAnyOfSelect of Activatable.AnyOf.Select.t + | MagicalTradition of MagicalTradition.t + | BlessedTradition of BlessedTradition.t | Rated of Rated.t | RatedAnyOf of Rated.AnyOf.t + | MinimumSkillRating of MinimumSkillRating.t type t = value Config.t (** Full configuration of an advantages or disadvantages prerequisite @@ -324,7 +396,7 @@ module Group : sig (** Possible prerequisites of personality traits. *) module PersonalityTrait : sig (** A set of possible prerequisite definitions of personality traits. *) - type value = Culture of Culture.t | Special + type value = Culture of Culture.t | Special of Special.t type t = value Config.t (** Full configuration of a personality trait prerequisite definition. *) @@ -396,7 +468,7 @@ module Group : sig (** Possible prerequisites of enhancements. *) module Enhancement : sig (** A set of possible prerequisite definitions of enhancements. *) - type t = Enhancement of Enhancement.t + type t = Enhancement of Enhancement.Internal.t end end diff --git a/src/IO/DatabaseDecoder.ml b/src/IO/DatabaseDecoder.ml index dc910edd..04d108e3 100644 --- a/src/IO/DatabaseDecoder.ml +++ b/src/IO/DatabaseDecoder.ml @@ -1,91 +1,322 @@ module Entities = struct - let decode_type ~log_err empty insert decoder - (file_contents : DatabaseReader.Entities.raw_collection) = - ListX.foldl' - (fun file_content -> - file_content |> Yaml.parse - |> Decoders_bs.Decode.decode_value decoder - |> function - | Ok (Some (parsed_key, parsed_value)) -> insert parsed_key parsed_value - | Ok None -> Function.id - | Error err -> - let () = log_err err in - Function.id) - empty file_contents - let categories_total = DatabaseReader.Entities.dirs_number |> Js.Int.toFloat let percent_per_category = 1.0 /. categories_total + (** Prepare decoders for each type in the database. *) + module DecodeType = struct + open DatabaseReader.Entities + + let decode empty insert make_assoc data_acc ~log_err locale_order data = + data |> data_acc + |> ListX.foldl' + (fun file_content -> + file_content |> Yaml.parse + |> Decoders_bs.Decode.decode_value (make_assoc locale_order) + |> function + | Ok (Some (parsed_key, parsed_value)) -> + insert parsed_key parsed_value + | Ok None -> Function.id + | Error err -> + let () = log_err err in + Function.id) + empty + + (* let animal_shapes = decode_type (AnimalShape.Decode.assoc langs) parsed_data.animal_shapes in let () = progress 1.0 in *) + (* let animal_shape_paths = decode_type (IdName.Decode.assoc langs) parsed_data.animal_shape_paths in let () = progress 2.0 in *) + (* let animal_shape_sizes = decode_type (AnimalShape.Size.Decode.assoc langs) parsed_data.animal_shape_sizes in let () = progress 3.0 in *) + + let animist_powers = + let open Id.AnimistPower.Map in + let open AnimistPower.Static.Decode in + let data_acc data = data.animist_powers in + decode empty insert make_assoc data_acc + + (* let arcane_bard_traditions ~log_err langs data = + let open Id.MagicalTradition.ArcaneBardTradition.Map in + let open ArcaneBardTradition.Static.Decode in + decode ~log_err empty insert (make_assoc langs) data.arcane_bard_traditions *) + + (* let arcane_dancer_traditions ~log_err langs data = + let open Id.MagicalTradition.ArcaneDancerTradition.Map in + let open ArcaneDancerTradition.Static.Decode in + decode ~log_err empty insert (make_assoc langs) data.arcane_dancer_traditions *) + + (* let armor_types = decode_type (IdName.Decode.assoc langs) parsed_data.armor_types in let () = progress 7.0 in *) + (* let aspects = decode_type (Aspect.Decode.assoc langs) parsed_data.aspects in let () = progress 8.0 in *) + + let attributes = + let open Id.Attribute.Map in + let open Attribute.Static.Decode in + let data_acc data = data.attributes in + decode empty insert make_assoc data_acc + + (* let blessings = decode_type (Blessing.Static.Decode.assoc langs) parsed_data.blessings in let () = progress 10.0 in *) + (* let brews = decode_type (IdName.Decode.assoc langs) parsed_data.brews in let () = progress 11.0 in *) + (* let cantrips = decode_type (Cantrip.Static.Decode.assoc langs) parsed_data.cantrips in let () = progress 12.0 in *) + + let ceremonies = + let open Id.Ceremony.Map in + let open Ceremony.Static.Decode in + let data_acc data = data.ceremonies in + decode empty insert make_assoc data_acc + + (* let combat_special_ability_groups = decode_type (IdName.Decode.assoc langs) parsed_data.combat_special_ability_groups in let () = progress 14.0 in *) + (* let combat_technique_groups = decode_type (IdName.Decode.assoc langs) parsed_data.combat_technique_groups in let () = progress 15.0 in *) + (* let conditions = decode_type (Condition.Static.Decode.assoc langs) parsed_data.conditions in let () = progress 16.0 in *) + (* let core_rules = decode_type (CoreRule.Decode.assoc langs) parsed_data.core_rules in let () = progress 17.0 in *) + (* let cultures = decode_type (Culture.Static.Decode.assoc langs) parsed_data.cultures in let () = progress 18.0 in *) + (* let curricula = decode_type (Curriculum.Static.Decode.assoc langs) parsed_data.curricula in let () = progress 19.0 in *) + + let curses = + let open Id.Curse.Map in + let open Curse.Static.Decode in + let data_acc data = data.curses in + decode empty insert make_assoc data_acc + + (* let derived_characteristics = decode_type (DerivedCharacteristic.Static.Decode.assoc langs) parsed_data.derived_characteristics in let () = progress 21.0 in *) + + let diseases = + let open Id.Disease.Map in + let open Disease.Decode in + let data_acc data = data.diseases in + decode empty insert make_assoc data_acc + + let domination_rituals = + let open Id.DominationRitual.Map in + let open DominationRitual.Static.Decode in + let data_acc data = data.domination_rituals in + decode empty insert make_assoc data_acc + + (* let elements = decode_type (Element.Decode.assoc langs) parsed_data.elements in let () = progress 24.0 in *) + + let elven_magical_songs = + let open Id.ElvenMagicalSong.Map in + let open ElvenMagicalSong.Static.Decode in + let data_acc data = data.elven_magical_songs in + decode empty insert make_assoc data_acc + + (* let equipment_packages = decode_type (EquipmentPackage.Decode.assoc langs) parsed_data.equipment_packages in let () = progress 26.0 in *) + + let experience_levels = + let open Id.ExperienceLevel.Map in + let open ExperienceLevel.Decode in + let data_acc data = data.experience_levels in + decode empty insert make_assoc data_acc + + (* let eye_colors = decode_type (IdName.Decode.assoc langs) parsed_data.eye_colors in let () = progress 28.0 in *) + + let focus_rules = + let open Id.FocusRule.Map in + let open FocusRule.Static.Decode in + let data_acc data = data.focus_rules in + decode empty insert make_assoc data_acc + + let geode_rituals = + let open Id.GeodeRitual.Map in + let open GeodeRitual.Static.Decode in + let data_acc data = data.geode_rituals in + decode empty insert make_assoc data_acc + + (* let hair_colors = decode_type (strinDecode.assoc langs) parsed_data.hair_colors in let () = progress 31.0 in *) + (* let items = decode_type (Item.Decode.assoc langs) parsed_data.items in let () = progress 32.0 in *) + (* let item_groups = decode_type (IdName.Decode.assoc langs) parsed_data.item_groups in let () = progress 33.0 in *) + + let jester_tricks = + let open Id.JesterTrick.Map in + let open JesterTrick.Static.Decode in + let data_acc data = data.jester_tricks in + decode empty insert make_assoc data_acc + + (* let languages = decode_type (Language.Decode.assoc langs) parsed_data.languages in let () = progress 34.0 in *) + + let liturgical_chants = + let open Id.LiturgicalChant.Map in + let open LiturgicalChant.Static.Decode in + let data_acc data = data.liturgical_chants in + decode empty insert make_assoc data_acc + + (* let liturgical_chant_groups = decode_type (IdName.Decode.assoc langs) parsed_data.liturgical_chant_groups in let () = progress 36.0 in *) + + let magical_dances = + let open Id.MagicalDance.Map in + let open MagicalDance.Static.Decode in + let data_acc data = data.magical_dances in + decode empty insert make_assoc data_acc + + let magical_melodies = + let open Id.MagicalMelody.Map in + let open MagicalMelody.Static.Decode in + let data_acc data = data.magical_melodies in + decode empty insert make_assoc data_acc + + let melee_combat_techniques = + let open Id.MeleeCombatTechnique.Map in + let open CombatTechnique.Melee.Static.Decode in + let data_acc data = data.melee_combat_techniques in + decode empty insert make_assoc data_acc + + let optional_rules = + let open Id.OptionalRule.Map in + let open OptionalRule.Static.Decode in + let data_acc data = data.optional_rules in + decode empty insert make_assoc data_acc + + (* let pact = decode_type (Pact.Static.Decode.assoc langs) parsed_data.pact in let () = progress 41.0 in *) + + let patrons = + let open IntMap in + let open Patron.Decode in + let data_acc data = data.patrons in + decode empty insert make_assoc data_acc + + let patron_categories = + let open IntMap in + let open Patron.Category.Decode in + let data_acc data = data.patron_categories in + decode empty insert make_assoc data_acc + + (* let poisons = decode_type (Poison.Decode.assoc langs) parsed_data.poisons in let () = progress 44.0 in *) + (* let professions = decode_type (Profession.Static.Decode.assoc langs) parsed_data.professions in let () = progress 45.0 in *) + (* let properties = decode_type (Property.Decode.assoc langs) parsed_data.properties in let () = progress 46.0 in *) + + let publications = + let open Id.Publication.Map in + let open Publication.Decode in + let data_acc data = data.publications in + decode empty insert make_assoc data_acc + + (* let races = decode_type (Race.Static.Decode.assoc langs) parsed_data.races in let () = progress 48.0 in *) + + let ranged_combat_techniques = + let open Id.RangedCombatTechnique.Map in + let open CombatTechnique.Ranged.Static.Decode in + let data_acc data = data.ranged_combat_techniques in + decode empty insert make_assoc data_acc + + (* let reaches = decode_type (IdName.Decode.assoc langs) parsed_data.reaches in let () = progress 50.0 in *) + + let regions = + let open Id.Region.Map in + let open Region.Decode in + let data_acc data = data.regions in + decode empty insert make_assoc data_acc + + let rituals = + let open Id.Ritual.Map in + let open Ritual.Static.Decode in + let data_acc data = data.rituals in + decode empty insert make_assoc data_acc + + (* let scripts = decode_type (Script.Decode.assoc langs) parsed_data.scripts in let () = progress 53.0 in *) + + let skills ~regions ~diseases = + let open Id.Skill.Map in + let open Skill.Static.Decode in + let data_acc data = data.skills in + decode empty insert (make_assoc ~regions ~diseases) data_acc + + let skill_groups = + let open IntMap in + let open Skill.Group.Decode in + let data_acc data = data.skill_groups in + decode empty insert make_assoc data_acc + + (* let social_statuses = decode_type (IdName.Decode.assoc langs) parsed_data.social_statuses in let () = progress 56.0 in *) + (* let special_ability_groups = decode_type (IdName.Decode.assoc langs) parsed_data.special_ability_groups in let () = progress 57.0 in *) + + let spells = + let open Id.Spell.Map in + let open Spell.Static.Decode in + let data_acc data = data.spells in + decode empty insert make_assoc data_acc + + (* let spell_groups = decode_type (IdName.Decode.assoc langs) parsed_data.spell_groups in let () = progress 59.0 in *) + (* let states = decode_type (State.Static.Decode.assoc langs) parsed_data.states in let () = progress 60.0 in *) + (* let subjects = decode_type (IdName.Decode.assoc langs) parsed_data.subjects in let () = progress 61.0 in *) + (* let trade_secrets = decode_type (TradeSecret.Decode.assoc langs) parsed_data.trade_secrets in let () = progress 62.0 in *) + (* let tribes = decode_type (IdName.Decode.assoc langs) parsed_data.tribes in let () = progress 63.0 in *) + (* let ui = decode_type (Messages.Decode.assoc langs) parsed_data.ui in let () = progress 64.0 in *) + + let zibilja_rituals = + let open Id.ZibiljaRitual.Map in + let open ZibiljaRitual.Static.Decode in + let data_acc data = data.zibilja_rituals in + decode empty insert make_assoc data_acc + end + let decode_files - ~set_progress ~log_err langs _messages (parsed_data: DatabaseReader.Entities.t): Static.t = - let progress part = set_progress(percent_per_category *. part) in + ~set_progress ~log_err langs _messages (parsed: DatabaseReader.Entities.t): Static.t = + let count = ref 0 in + let progress () = let () = count := !count + 1 in set_progress(percent_per_category *. Js.Int.toFloat(!count)) in (* let animal_shapes = decode_type (AnimalShape.Decode.assoc langs) parsed_data.animal_shapes in let () = progress 1.0 in *) (* let animal_shape_paths = decode_type (IdName.Decode.assoc langs) parsed_data.animal_shape_paths in let () = progress 2.0 in *) (* let animal_shape_sizes = decode_type (AnimalShape.Size.Decode.assoc langs) parsed_data.animal_shape_sizes in let () = progress 3.0 in *) - (* let animist_forces = decode_type (AnimistForce.Static.Decode.assoc langs) parsed_data.animist_forces in let () = progress 4.0 in *) + let animist_powers = DecodeType.animist_powers ~log_err langs parsed in let () = progress () in (* let arcane_bard_traditions = decode_type (ArcaneTradition.Decode.assoc langs) parsed_data.arcane_bard_traditions in let () = progress 5.0 in *) (* let arcane_dancer_traditions = decode_type (ArcaneTradition.Decode.assoc langs) parsed_data.arcane_dancer_traditions in let () = progress 6.0 in *) (* let armor_types = decode_type (IdName.Decode.assoc langs) parsed_data.armor_types in let () = progress 7.0 in *) (* let aspects = decode_type (Aspect.Decode.assoc langs) parsed_data.aspects in let () = progress 8.0 in *) - (* let attributes = decode_type (Attribute.Static.Decode.assoc langs) parsed_data.attributes in let () = progress 9.0 in *) + let attributes = DecodeType.attributes ~log_err langs parsed in let () = progress () in (* let blessings = decode_type (Blessing.Static.Decode.assoc langs) parsed_data.blessings in let () = progress 10.0 in *) (* let brews = decode_type (IdName.Decode.assoc langs) parsed_data.brews in let () = progress 11.0 in *) (* let cantrips = decode_type (Cantrip.Static.Decode.assoc langs) parsed_data.cantrips in let () = progress 12.0 in *) - (* let ceremonies = decode_type (Ceremony.Static.Decode.assoc langs) parsed_data.ceremonies in let () = progress 13.0 in *) + let ceremonies = DecodeType.ceremonies ~log_err langs parsed in let () = progress () in (* let combat_special_ability_groups = decode_type (IdName.Decode.assoc langs) parsed_data.combat_special_ability_groups in let () = progress 14.0 in *) (* let combat_technique_groups = decode_type (IdName.Decode.assoc langs) parsed_data.combat_technique_groups in let () = progress 15.0 in *) (* let conditions = decode_type (Condition.Static.Decode.assoc langs) parsed_data.conditions in let () = progress 16.0 in *) (* let core_rules = decode_type (CoreRule.Decode.assoc langs) parsed_data.core_rules in let () = progress 17.0 in *) (* let cultures = decode_type (Culture.Static.Decode.assoc langs) parsed_data.cultures in let () = progress 18.0 in *) (* let curricula = decode_type (Curriculum.Static.Decode.assoc langs) parsed_data.curricula in let () = progress 19.0 in *) - (* let curses = decode_type (Curse.Static.Decode.assoc langs) parsed_data.curses in let () = progress 20.0 in *) + let curses = DecodeType.curses ~log_err langs parsed in let () = progress () in (* let derived_characteristics = decode_type (DerivedCharacteristic.Static.Decode.assoc langs) parsed_data.derived_characteristics in let () = progress 21.0 in *) - (* let diseases = decode_type (Disease.Decode.assoc langs) parsed_data.diseases in let () = progress 22.0 in *) - (* let domination_rituals = decode_type (DominationRitual.Static.Decode.assoc langs) parsed_data.domination_rituals in let () = progress 23.0 in *) + let diseases = DecodeType.diseases ~log_err langs parsed in let () = progress () in + let domination_rituals = DecodeType.domination_rituals ~log_err langs parsed in let () = progress () in (* let elements = decode_type (Element.Decode.assoc langs) parsed_data.elements in let () = progress 24.0 in *) - (* let elven_magical_songs = decode_type (ElvenMagicalSong.Static.Decode.assoc langs) parsed_data.elven_magical_songs in let () = progress 25.0 in *) + let elven_magical_songs = DecodeType.elven_magical_songs ~log_err langs parsed in let () = progress () in (* let equipment_packages = decode_type (EquipmentPackage.Decode.assoc langs) parsed_data.equipment_packages in let () = progress 26.0 in *) - let experience_levels = Id.ExperienceLevel.Map.(decode_type ~log_err empty insert (ExperienceLevel.Decode.make_assoc langs) parsed_data.experience_levels) in let () = progress 27.0 in + let experience_levels = DecodeType.experience_levels ~log_err langs parsed in let () = progress () in (* let eye_colors = decode_type (IdName.Decode.assoc langs) parsed_data.eye_colors in let () = progress 28.0 in *) - (* let focus_rules = decode_type (FocusRule.Static.Decode.assoc langs) parsed_data.focus_rules in let () = progress 29.0 in *) - (* let geodenrituale = decode_type (Geodenritual.Static.Decode.assoc langs) parsed_data.geodenrituale in let () = progress 30.0 in *) + let focus_rules = DecodeType.focus_rules ~log_err langs parsed in let () = progress () in + let geode_rituals = DecodeType.geode_rituals ~log_err langs parsed in let () = progress () in (* let hair_colors = decode_type (strinDecode.assoc langs) parsed_data.hair_colors in let () = progress 31.0 in *) (* let items = decode_type (Item.Decode.assoc langs) parsed_data.items in let () = progress 32.0 in *) (* let item_groups = decode_type (IdName.Decode.assoc langs) parsed_data.item_groups in let () = progress 33.0 in *) + let jester_tricks = DecodeType.jester_tricks ~log_err langs parsed in let () = progress () in (* let languages = decode_type (Language.Decode.assoc langs) parsed_data.languages in let () = progress 34.0 in *) - (* let liturgical_chants = decode_type (LiturgicalChant.Static.Decode.assoc langs) parsed_data.liturgical_chants in let () = progress 35.0 in *) + let liturgical_chants = DecodeType.liturgical_chants ~log_err langs parsed in let () = progress () in (* let liturgical_chant_groups = decode_type (IdName.Decode.assoc langs) parsed_data.liturgical_chant_groups in let () = progress 36.0 in *) - (* let magical_dances = decode_type (MagicalDance.Static.Decode.assoc langs) parsed_data.magical_dances in let () = progress 37.0 in *) - (* let magical_melodies = decode_type (MagicalMelody.Static.Decode.assoc langs) parsed_data.magical_melodies in let () = progress 38.0 in *) - (* let melee_combat_techniques = decode_type (CombatTechnique.Melee.Static.Decode.assoc langs) parsed_data.melee_combat_techniques in let () = progress 39.0 in *) - (* let optional_rules = decode_type (OptionalRule.Static.Decode.assoc langs) parsed_data.optional_rules in let () = progress 40.0 in *) + let magical_dances = DecodeType.magical_dances ~log_err langs parsed in let () = progress () in + let magical_melodies = DecodeType.magical_melodies ~log_err langs parsed in let () = progress () in + let melee_combat_techniques = DecodeType.melee_combat_techniques ~log_err langs parsed in let () = progress () in + let optional_rules = DecodeType.optional_rules ~log_err langs parsed in let () = progress () in (* let pact = decode_type (Pact.Static.Decode.assoc langs) parsed_data.pact in let () = progress 41.0 in *) - (* let patrons = decode_type (Patron.Decode.assoc langs) parsed_data.patrons in let () = progress 42.0 in *) - (* let patron_categories = decode_type (Patron.Category.Decode.assoc langs) parsed_data.patron_categories in let () = progress 43.0 in *) + let patrons = DecodeType.patrons ~log_err langs parsed in let () = progress () in + let patron_categories = DecodeType.patron_categories ~log_err langs parsed in let () = progress () in (* let poisons = decode_type (Poison.Decode.assoc langs) parsed_data.poisons in let () = progress 44.0 in *) (* let professions = decode_type (Profession.Static.Decode.assoc langs) parsed_data.professions in let () = progress 45.0 in *) (* let properties = decode_type (Property.Decode.assoc langs) parsed_data.properties in let () = progress 46.0 in *) - (* let publications = decode_type (Publication.Decode.assoc langs) parsed_data.publications in let () = progress 47.0 in *) + let publications = DecodeType.publications ~log_err langs parsed in let () = progress () in (* let races = decode_type (Race.Static.Decode.assoc langs) parsed_data.races in let () = progress 48.0 in *) - (* let ranged_combat_techniques = decode_type (CombatTechnique.Ranged.Static.Decode.assoc langs) parsed_data.ranged_combat_techniques in let () = progress 49.0 in *) + let ranged_combat_techniques = DecodeType.ranged_combat_techniques ~log_err langs parsed in let () = progress () in (* let reaches = decode_type (IdName.Decode.assoc langs) parsed_data.reaches in let () = progress 50.0 in *) - (* let rituals = decode_type (Ritual.Static.Decode.assoc langs) parsed_data.rituals in let () = progress 51.0 in *) - (* let schelmenzauber = decode_type (Schelmenzauber.Static.Decode.assoc langs) parsed_data.schelmenzauber in let () = progress 52.0 in *) + let regions = DecodeType.regions ~log_err langs parsed in let () = progress () in + let rituals = DecodeType.rituals ~log_err langs parsed in let () = progress () in (* let scripts = decode_type (Script.Decode.assoc langs) parsed_data.scripts in let () = progress 53.0 in *) - (* let skills = Id.Skill.Map.(decode_type empty insert (Skill.Static.Decode.make_assoc langs) parsed_data.skills) in let () = progress 54.0 in *) - (* let skill_groups = decode_type (Skill.Group.Decode.assoc langs) parsed_data.skill_groups in let () = progress 55.0 in *) + let skill_groups = DecodeType.skill_groups ~log_err langs parsed in let () = progress () in (* let social_statuses = decode_type (IdName.Decode.assoc langs) parsed_data.social_statuses in let () = progress 56.0 in *) (* let special_ability_groups = decode_type (IdName.Decode.assoc langs) parsed_data.special_ability_groups in let () = progress 57.0 in *) - (* let spells = decode_type (Spell.Static.Decode.assoc langs) parsed_data.spells in let () = progress 58.0 in *) + let spells = DecodeType.spells ~log_err langs parsed in let () = progress () in (* let spell_groups = decode_type (IdName.Decode.assoc langs) parsed_data.spell_groups in let () = progress 59.0 in *) (* let states = decode_type (State.Static.Decode.assoc langs) parsed_data.states in let () = progress 60.0 in *) (* let subjects = decode_type (IdName.Decode.assoc langs) parsed_data.subjects in let () = progress 61.0 in *) (* let trade_secrets = decode_type (TradeSecret.Decode.assoc langs) parsed_data.trade_secrets in let () = progress 62.0 in *) (* let tribes = decode_type (IdName.Decode.assoc langs) parsed_data.tribes in let () = progress 63.0 in *) (* let ui = decode_type (Messages.Decode.assoc langs) parsed_data.ui in let () = progress 64.0 in *) - (* let zibiljarituale = decode_type (ZibiljaRitual.Static.Decode.assoc langs) parsed_data.zibiljarituale in let () = progress 65.0 in *) + let zibilja_rituals = DecodeType.zibilja_rituals ~log_err langs parsed in let () = progress () in + + let skills = DecodeType.skills ~regions ~diseases ~log_err langs parsed in let () = progress () in (* let advanced_combat_special_abilities = decode_type (AdvancedCombatSpecialAbility.Static.Decode.assoc langs) parsed_data.advanced_combat_special_abilities in let () = progress 1.0 in *) (* let advanced_karma_special_abilities = decode_type (AdvancedKarmaSpecialAbility.Static.Decode.assoc langs) parsed_data.advanced_karma_special_abilities in let () = progress 2.0 in *) @@ -144,21 +375,21 @@ module Entities = struct (* animal_shape_paths; *) (* animal_shapes; *) (* animal_shape_sizes; *) - (* animist_forces; *) + animist_powers; (* arcane_bard_traditions; *) (* arcane_dancer_traditions; *) (* armors; *) (* armor_types; *) (* aspects; *) (* attire_enchantments; *) - (* attributes; *) + attributes; (* blessed_traditions; *) (* blessings; *) (* brawling_special_abilities; *) (* brews; *) (* cantrips; *) (* ceremonial_item_special_abilities; *) - (* ceremonies; *) + ceremonies; (* chronikzauber; *) (* combat_special_abilities; *) (* combat_special_ability_groups; *) @@ -169,59 +400,60 @@ module Entities = struct (* core_rules; *) (* cultures; *) (* curricula; *) - (* curses; *) + curses; (* dagger_rituals; *) (* derived_characteristics; *) (* disadvantages; *) - (* diseases; *) - (* domination_rituals; *) + diseases; + domination_rituals; (* elements; *) - (* elven_magical_songs; *) + elven_magical_songs; (* equipment_packages; *) (* erweiterte_talentsonderfertigkeiten; *) experience_levels; (* eye_colors; *) (* familiar_special_abilities; *) (* fate_point_special_abilities; *) - (* focus_rules; *) + focus_rules; (* general_special_abilities; *) - (* geodenrituale; *) + geode_rituals; (* hair_colors; *) (* instrument_enchantments; *) (* item_groups; *) (* items; *) + jester_tricks; (* kappenzauber; *) (* karma_special_abilities; *) (* kesselzauber; *) (* kugelzauber; *) (* languages; *) (* liturgical_chant_groups; *) - (* liturgical_chants; *) + liturgical_chants; (* liturgical_style_special_abilities; *) (* lykanthropische_gaben; *) - (* magical_dances; *) - (* magical_melodies; *) + magical_dances; + magical_melodies; (* magical_special_abilities; *) (* magical_traditions; *) (* magic_style_special_abilities; *) - (* melee_combat_techniques; *) - (* optional_rules; *) + melee_combat_techniques; + optional_rules; (* orb_enchantments; *) (* pact_categories; *) (* paktgeschenke; *) - (* patron_categories; *) - (* patrons; *) + patron_categories; + patrons; (* poisons; *) (* professions; *) (* properties; *) (* protective_warding_circle_special_abilities; *) - (* publications; *) + publications; (* races; *) - (* ranged_combat_techniques; *) + ranged_combat_techniques; (* reaches; *) + regions; (* ringzauber; *) - (* rituals; *) - (* schelmenzauber; *) + rituals; (* schalenzauber; *) (* scripts; *) (* sermons; *) @@ -229,12 +461,12 @@ module Entities = struct (* sex_sonderfertigkeiten; *) (* sichelrituale; *) (* sikaryan_raub_sonderfertigkeiten; *) - (* skill_groups; *) - (* skills; *) + skill_groups; + skills; (* social_statuses; *) (* special_ability_groups; *) (* spell_groups; *) - (* spells; *) + spells; (* spell_sword_enchantments; *) (* spielzeugzauber; *) (* staff_enchantments; *) @@ -249,6 +481,6 @@ module Entities = struct (* waffenzauber; *) (* wand_enchantments; *) (* weapons; *) - (* zibiljarituale; *) + zibilja_rituals; }[@@ocamlformat "disable"] end diff --git a/src/Main.ml b/src/Main.ml index 258918b1..80491110 100644 --- a/src/Main.ml +++ b/src/Main.ml @@ -22,58 +22,67 @@ let make_window (window_state : ElectronWindowState.t) = in make ~options ()) +let manage_window_state window_state window = + window_state |. ElectronWindowState.manage window + +let load_content window = + let url = + Node.Url.(path_to_file_url (Node.Path.join2 __dirname "index.html") |> href) + in + window |. Electron.BrowserWindow.load_url url + +let restore_secondary_window_state (window_state : ElectronWindowState.t) window + = + let () = window |. Electron.BrowserWindow.show in + if Option.value ~default:false window_state.isMaximized then + Electron.BrowserWindow.maximize window + else () + +let read_files _ = + let () = Js.Console.timeStart "Read Database" in + DatabaseReader.Entities.read_files ~set_progress:(fun _progress -> ()) + +let decode_files window raw_data = + let () = Js.Console.timeEnd "Read Database" in + Js.Promise.make (fun ~resolve ~reject -> + Node.WorkerThreads.Worker.( + make' "./src/DatabaseWorker.bs.js" + (options + ~workerData: + ((Locale.Order.from_list "de-DE" [ "de-DE" ], raw_data) + : DatabaseWorker.worker_data)) + |. on (`online (fun () -> Js.Console.timeStart "Decode Database")) + |. on + (`message + (function + | DatabaseWorker.Progress progress -> + window |. Electron.BrowserWindow.web_contents + |. Electron.WebContents.send (`DatabaseProcess progress) + | Finished data -> + let () = Js.Console.timeEnd "Decode Database" in + (resolve data [@bs]) + | Error err -> + window |. Electron.BrowserWindow.web_contents + |. Electron.WebContents.send (`DatabaseDecodeError err))) + |. on (`error (fun err -> (reject err [@bs]))) + |. on (`messageerror (fun err -> (reject err [@bs]))) + |. on (`exit (fun ~exit_code -> Js.Console.log exit_code)) + |> ignore)) + +let send_decoded_data window data = + window |. Electron.BrowserWindow.web_contents + |. Electron.WebContents.send (`DatabaseProcessed data) + let main () = let open Promise.Infix in let () = Electron.App.(t |. set_app_user_model_id "lukasobermann.optolith") in let window_state = make_window_state () in let window = make_window window_state in - let () = window_state |. ElectronWindowState.manage window in + let () = manage_window_state window_state window in install_devtools () - >>= (fun _ -> - window - |. Electron.BrowserWindow.load_url - Node.Url.( - path_to_file_url (Node.Path.join2 __dirname "index.html") |> href)) - <&> (fun _ -> - let () = window |. Electron.BrowserWindow.show in - if Option.value ~default:false window_state.isMaximized then - Electron.BrowserWindow.maximize window - else ()) - >>= (fun _ -> - DatabaseReader.Entities.read_files ~set_progress:(fun _progress -> ())) - >>= (fun raw_data -> - Js.Promise.make (fun ~resolve ~reject -> - Node.WorkerThreads.Worker.( - make' "./src/DatabaseWorker.bs.js" - (options - ~workerData: - ((Locale.Order.from_list "de-DE" [ "de-DE" ], raw_data) - : DatabaseWorker.worker_data)) - |. on - (`online - (fun () -> - let () = Js.Console.log "online" in - Js.Console.timeStart "Database Decoding")) - |. on - (`message - (function - | DatabaseWorker.Progress progress -> - window |. Electron.BrowserWindow.web_contents - |. Electron.WebContents.send - (`DatabaseProcess progress) - | Finished data -> - let () = Js.Console.timeEnd "Database Decoding" in - (resolve data [@bs]) - | Error err -> - window |. Electron.BrowserWindow.web_contents - |. Electron.WebContents.send (`DatabaseDecodeError err))) - |. on (`error (fun err -> (reject err [@bs]))) - |. on (`messageerror (fun err -> (reject err [@bs]))) - |. on (`exit (fun ~exit_code -> Js.Console.log exit_code)) - |> ignore))) - <&> (fun data -> - window |. Electron.BrowserWindow.web_contents - |. Electron.WebContents.send (`DatabaseProcessed data)) + >>= (fun _ -> load_content window) + <&> (fun () -> restore_secondary_window_state window_state window) + >>= read_files >>= decode_files window <&> send_decoded_data window |> Js.Promise.catch (fun err -> let () = Js.Console.error err in Js.Promise.resolve ()) diff --git a/src/Rated/ArcaneSpellworks/Ritual.ml b/src/Rated/ArcaneSpellworks/Ritual.ml index 1cf7e447..adeb0745 100644 --- a/src/Rated/ArcaneSpellworks/Ritual.ml +++ b/src/Rated/ArcaneSpellworks/Ritual.ml @@ -5,14 +5,18 @@ module Static = struct check : Check.t; check_mod : Check.Modifier.t option; effect : string; + effect_quality_levels : + Rated.Static.Activatable.EffectByQualityLevel.t option; + effect_after_quality_levels : string option; casting_time : Rated.Static.Activatable.MainParameter.t; cost : Rated.Static.Activatable.MainParameter.t; range : Rated.Static.Activatable.MainParameter.t; duration : Rated.Static.Activatable.MainParameter.t; target : string; - property : int; + property : Id.Property.t; traditions : Id.MagicalTradition.Set.t; - ic : ImprovementCost.t; + tradition_placeholders : int list; + improvement_cost : ImprovementCost.t; prerequisites : Prerequisite.Collection.Spellwork.t; enhancements : Enhancement.Static.t IntMap.t; src : PublicationRef.list; @@ -25,7 +29,10 @@ module Static = struct type translation = { name : string; effect : string; - castingTime : Rated.Static.Activatable.MainParameter.Decode.translation; + effect_quality_levels : + Rated.Static.Activatable.EffectByQualityLevel.t option; + effect_after_quality_levels : string option; + casting_time : Rated.Static.Activatable.MainParameter.Decode.translation; cost : Rated.Static.Activatable.MainParameter.Decode.translation; range : Rated.Static.Activatable.MainParameter.Decode.translation; duration : Rated.Static.Activatable.MainParameter.Decode.translation; @@ -38,9 +45,14 @@ module Static = struct >>= fun name -> field "effect" string >>= fun effect -> - field "castingTime" + field_opt "effect_quality_levels" + Rated.Static.Activatable.EffectByQualityLevel.Decode.t + >>= fun effect_quality_levels -> + field_opt "effect_after_quality_levels" string + >>= fun effect_after_quality_levels -> + field "casting_time" Rated.Static.Activatable.MainParameter.Decode.translation - >>= fun castingTime -> + >>= fun casting_time -> field "cost" Rated.Static.Activatable.MainParameter.Decode.translation >>= fun cost -> field "range" Rated.Static.Activatable.MainParameter.Decode.translation @@ -52,19 +64,31 @@ module Static = struct field_opt "errata" Erratum.Decode.list >>= fun errata -> succeed - { name; effect; castingTime; cost; range; duration; target; errata } + { + name; + effect; + effect_quality_levels; + effect_after_quality_levels; + casting_time; + cost; + range; + duration; + target; + errata; + } type multilingual = { id : Id.Ritual.t; check : Check.t; - checkMod : Check.Modifier.t option; - castingTimeNoMod : bool; - costNoMod : bool; - rangeNoMod : bool; - durationNoMod : bool; - property : int; - traditions : int list; - ic : ImprovementCost.t; + check_mod : Check.Modifier.t option; + is_casting_time_modifiable : bool; + is_cost_modifiable : bool; + is_range_modifiable : bool; + is_duration_modifiable : bool; + property : Id.Property.t; + traditions : Id.MagicalTradition.Set.t; + tradition_placeholders : int list; + improvement_cost : ImprovementCost.t; prerequisites : Prerequisite.Collection.Spellwork.t option; enhancements : Enhancement.Static.t IntMap.t option; src : PublicationRef.list; @@ -76,22 +100,24 @@ module Static = struct >>= fun id -> field "check" Check.Decode.t >>= fun check -> - field_opt "checkMod" Check.Modifier.Decode.t - >>= fun checkMod -> - field "castingTimeNoMod" bool - >>= fun castingTimeNoMod -> - field "costNoMod" bool - >>= fun costNoMod -> - field "rangeNoMod" bool - >>= fun rangeNoMod -> - field "durationNoMod" bool - >>= fun durationNoMod -> - field "property" int + field_opt "check_mod" Check.Modifier.Decode.t + >>= fun check_mod -> + field "is_casting_time_modifiable" bool + >>= fun is_casting_time_modifiable -> + field "is_cost_modifiable" bool + >>= fun is_cost_modifiable -> + field "is_range_modifiable" bool + >>= fun is_range_modifiable -> + field "is_duration_modifiable" bool + >>= fun is_duration_modifiable -> + field "property" Id.Property.Decode.t >>= fun property -> - field "traditions" (list int) + field "traditions" Id.MagicalTradition.Decode.set >>= fun traditions -> - field "ic" ImprovementCost.Decode.t - >>= fun ic -> + field "tradition_placeholders" (list int) + >>= fun tradition_placeholders -> + field "improvement_cost" ImprovementCost.Decode.t + >>= fun improvement_cost -> field_opt "prerequisites" (Prerequisite.Collection.Spellwork.Decode.make locale_order) >>= fun prerequisites -> @@ -105,14 +131,15 @@ module Static = struct { id; check; - checkMod; - castingTimeNoMod; - costNoMod; - rangeNoMod; - durationNoMod; + check_mod; + is_casting_time_modifiable; + is_cost_modifiable; + is_range_modifiable; + is_duration_modifiable; property; traditions; - ic; + tradition_placeholders; + improvement_cost; prerequisites; enhancements; src; @@ -131,25 +158,27 @@ module Static = struct id = multilingual.id; name = translation.name; check = multilingual.check; - check_mod = multilingual.checkMod; + check_mod = multilingual.check_mod; effect = translation.effect; + effect_quality_levels = translation.effect_quality_levels; + effect_after_quality_levels = translation.effect_after_quality_levels; casting_time = Rated.Static.Activatable.MainParameter.Decode.make - multilingual.castingTimeNoMod translation.castingTime; + multilingual.is_casting_time_modifiable translation.casting_time; cost = Rated.Static.Activatable.MainParameter.Decode.make - multilingual.costNoMod translation.cost; + multilingual.is_cost_modifiable translation.cost; range = Rated.Static.Activatable.MainParameter.Decode.make - multilingual.rangeNoMod translation.range; + multilingual.is_range_modifiable translation.range; duration = Rated.Static.Activatable.MainParameter.Decode.make - multilingual.durationNoMod translation.duration; + multilingual.is_duration_modifiable translation.duration; target = translation.target; property = multilingual.property; - traditions = - multilingual.traditions |> Id.MagicalTradition.Set.from_int_list; - ic = multilingual.ic; + traditions = multilingual.traditions; + tradition_placeholders = multilingual.tradition_placeholders; + improvement_cost = multilingual.improvement_cost; prerequisites = multilingual.prerequisites |> Option.value ~default:[]; enhancements = multilingual.enhancements |> Option.value ~default:IntMap.empty; @@ -166,7 +195,7 @@ module Dynamic = Rated.Dynamic.Activatable.ByMagicalTradition.Make (struct type static = t - let ic x = x.ic + let ic x = x.improvement_cost let enhancements x = x.enhancements end) diff --git a/src/Rated/ArcaneSpellworks/Ritual.mli b/src/Rated/ArcaneSpellworks/Ritual.mli index cd76c348..995f5a3c 100644 --- a/src/Rated/ArcaneSpellworks/Ritual.mli +++ b/src/Rated/ArcaneSpellworks/Ritual.mli @@ -8,14 +8,18 @@ module Static : sig check : Check.t; check_mod : Check.Modifier.t option; effect : string; + effect_quality_levels : + Rated.Static.Activatable.EffectByQualityLevel.t option; + effect_after_quality_levels : string option; casting_time : Rated.Static.Activatable.MainParameter.t; cost : Rated.Static.Activatable.MainParameter.t; range : Rated.Static.Activatable.MainParameter.t; duration : Rated.Static.Activatable.MainParameter.t; target : string; - property : int; + property : Id.Property.t; traditions : Id.MagicalTradition.Set.t; - ic : ImprovementCost.t; + tradition_placeholders : int list; + improvement_cost : ImprovementCost.t; prerequisites : Prerequisite.Collection.Spellwork.t; enhancements : Enhancement.Static.t IntMap.t; src : PublicationRef.list; diff --git a/src/Rated/Attribute.ml b/src/Rated/Attribute.ml index 477a4d49..67bfb8fb 100644 --- a/src/Rated/Attribute.ml +++ b/src/Rated/Attribute.ml @@ -2,7 +2,7 @@ module Static = struct type t = { id : Id.Attribute.t; name : string; - abbr : string; + abbreviation : string; description : string; } @@ -11,17 +11,17 @@ module Static = struct type translation = { name : string; - nameAbbr : string; + abbreviation : string; description : string; } let translation = field "name" string >>= fun name -> - field "nameAbbr" string - >>= fun nameAbbr -> + field "abbreviation" string + >>= fun abbreviation -> field "description" string - >>= fun description -> succeed { name; nameAbbr; description } + >>= fun description -> succeed { name; abbreviation; description } type multilingual = { id : Id.Attribute.t; @@ -45,7 +45,7 @@ module Static = struct { id = multilingual.id; name = translation.name; - abbr = translation.nameAbbr; + abbreviation = translation.abbreviation; description = translation.description; } ) end diff --git a/src/Rated/Attribute.mli b/src/Rated/Attribute.mli index ef838d0f..6540fb77 100644 --- a/src/Rated/Attribute.mli +++ b/src/Rated/Attribute.mli @@ -5,7 +5,7 @@ module Static : sig type t = { id : Id.Attribute.t; name : string; - abbr : string; + abbreviation : string; description : string; } (** The attribute type. *) diff --git a/src/Rated/CombatTechnique.ml b/src/Rated/CombatTechnique.ml index 2d3c27a2..170aa4a1 100644 --- a/src/Rated/CombatTechnique.ml +++ b/src/Rated/CombatTechnique.ml @@ -1,13 +1,34 @@ +(** Common static functionality for both melee and ranged combat techniques. *) +module Static = struct + module Decode = struct + open Decoders_bs.Decode + + type translation = { + name : string; + special : string option; + errata : Erratum.list option; + } + + let translation = + field "name" string + >>= fun name -> + field_opt "special" string + >>= fun special -> + field_opt "errata" Erratum.Decode.list + >>= fun errata -> succeed { name; special; errata } + end +end + module Melee = struct module Static = struct type t = { id : Id.MeleeCombatTechnique.t; name : string; - ic : ImprovementCost.t; - primary : int list; special : string option; - hasNoParry : bool; - breakingPointRating : int; + primary_attribute : Id.Attribute.t list; + improvement_cost : ImprovementCost.t; + breaking_point_rating : int; + parry : bool; src : PublicationRef.list; errata : Erratum.list; } @@ -15,52 +36,38 @@ module Melee = struct module Decode = struct open Decoders_bs.Decode - type translation = { - name : string; - special : string option; - errata : Erratum.list option; - } - - let translation = - field "name" string - >>= fun name -> - field_opt "special" string - >>= fun special -> - field_opt "errata" Erratum.Decode.list - >>= fun errata -> succeed { name; special; errata } - type multilingual = { id : Id.MeleeCombatTechnique.t; - ic : ImprovementCost.t; - primary : int list; - hasNoParry : bool; - breakingPointRating : int; + improvement_cost : ImprovementCost.t; + primary_attribute : Id.Attribute.t list; + parry : bool; + breaking_point_rating : int; src : PublicationRef.list; - translations : translation TranslationMap.t; + translations : Static.Decode.translation TranslationMap.t; } let multilingual locale_order = field "id" Id.MeleeCombatTechnique.Decode.t >>= fun id -> - field "ic" ImprovementCost.Decode.t - >>= fun ic -> - field "primary" (list int) - >>= fun primary -> - field "hasNoParry" bool - >>= fun hasNoParry -> - field "breakingPointRating" int - >>= fun breakingPointRating -> + field "improvement_cost" ImprovementCost.Decode.t + >>= fun improvement_cost -> + field "primary_attribute" (list Id.Attribute.Decode.t) + >>= fun primary_attribute -> + field "parry" bool + >>= fun parry -> + field "breaking_point_rating" int + >>= fun breaking_point_rating -> field "src" (PublicationRef.Decode.make_list locale_order) >>= fun src -> - field "translations" (TranslationMap.Decode.t translation) + field "translations" (TranslationMap.Decode.t Static.Decode.translation) >>= fun translations -> succeed { id; - ic; - primary; - hasNoParry; - breakingPointRating; + improvement_cost; + primary_attribute; + parry; + breaking_point_rating; src; translations; } @@ -76,11 +83,11 @@ module Melee = struct { id = multilingual.id; name = translation.name; - ic = multilingual.ic; - primary = multilingual.primary; + improvement_cost = multilingual.improvement_cost; + primary_attribute = multilingual.primary_attribute; special = translation.special; - hasNoParry = multilingual.hasNoParry; - breakingPointRating = multilingual.breakingPointRating; + parry = multilingual.parry; + breaking_point_rating = multilingual.breaking_point_rating; src = multilingual.src; errata = translation.errata |> Option.value ~default:[]; } ) @@ -94,7 +101,7 @@ module Melee = struct type static = t - let ic x = x.ic + let ic x = x.improvement_cost let min_value = 6 end) @@ -105,10 +112,10 @@ module Ranged = struct type t = { id : Id.RangedCombatTechnique.t; name : string; - ic : ImprovementCost.t; - primary : int list; special : string option; - breakingPointRating : int; + primary_attribute : Id.Attribute.t list; + improvement_cost : ImprovementCost.t; + breaking_point_rating : int; src : PublicationRef.list; errata : Erratum.list; } @@ -116,43 +123,37 @@ module Ranged = struct module Decode = struct open Decoders_bs.Decode - type translation = { - name : string; - special : string option; - errata : Erratum.list option; - } - - let translation = - field "name" string - >>= fun name -> - field_opt "special" string - >>= fun special -> - field_opt "errata" Erratum.Decode.list - >>= fun errata -> succeed { name; special; errata } - type multilingual = { id : Id.RangedCombatTechnique.t; - ic : ImprovementCost.t; - primary : int list; - breakingPointRating : int; + improvement_cost : ImprovementCost.t; + primary_attribute : Id.Attribute.t list; + breaking_point_rating : int; src : PublicationRef.list; - translations : translation TranslationMap.t; + translations : Static.Decode.translation TranslationMap.t; } let multilingual locale_order = field "id" Id.RangedCombatTechnique.Decode.t >>= fun id -> - field "ic" ImprovementCost.Decode.t - >>= fun ic -> - field "primary" (list int) - >>= fun primary -> - field "breakingPointRating" int - >>= fun breakingPointRating -> + field "improvement_cost" ImprovementCost.Decode.t + >>= fun improvement_cost -> + field "primary_attribute" (list Id.Attribute.Decode.t) + >>= fun primary_attribute -> + field "breaking_point_rating" int + >>= fun breaking_point_rating -> field "src" (PublicationRef.Decode.make_list locale_order) >>= fun src -> - field "translations" (TranslationMap.Decode.t translation) + field "translations" (TranslationMap.Decode.t Static.Decode.translation) >>= fun translations -> - succeed { id; ic; primary; breakingPointRating; src; translations } + succeed + { + id; + improvement_cost; + primary_attribute; + breaking_point_rating; + src; + translations; + } let make_assoc locale_order = let open Option.Infix in @@ -165,10 +166,10 @@ module Ranged = struct { id = multilingual.id; name = translation.name; - ic = multilingual.ic; - primary = multilingual.primary; + improvement_cost = multilingual.improvement_cost; + primary_attribute = multilingual.primary_attribute; special = translation.special; - breakingPointRating = multilingual.breakingPointRating; + breaking_point_rating = multilingual.breaking_point_rating; src = multilingual.src; errata = translation.errata |> Option.value ~default:[]; } ) @@ -182,7 +183,7 @@ module Ranged = struct type static = t - let ic x = x.ic + let ic x = x.improvement_cost let min_value = 6 end) diff --git a/src/Rated/CombatTechnique.mli b/src/Rated/CombatTechnique.mli index 49c1292d..53e83008 100644 --- a/src/Rated/CombatTechnique.mli +++ b/src/Rated/CombatTechnique.mli @@ -8,11 +8,11 @@ module Melee : sig type t = { id : Id.MeleeCombatTechnique.t; name : string; - ic : ImprovementCost.t; - primary : int list; special : string option; - hasNoParry : bool; - breakingPointRating : int; + primary_attribute : Id.Attribute.t list; + improvement_cost : ImprovementCost.t; + breaking_point_rating : int; + parry : bool; src : PublicationRef.list; errata : Erratum.list; } @@ -33,10 +33,10 @@ module Ranged : sig type t = { id : Id.RangedCombatTechnique.t; name : string; - ic : ImprovementCost.t; - primary : int list; special : string option; - breakingPointRating : int; + primary_attribute : Id.Attribute.t list; + improvement_cost : ImprovementCost.t; + breaking_point_rating : int; src : PublicationRef.list; errata : Erratum.list; } diff --git a/src/Rated/MagicalActions/AnimistPower.ml b/src/Rated/MagicalActions/AnimistPower.ml index 708673a1..3c763105 100644 --- a/src/Rated/MagicalActions/AnimistPower.ml +++ b/src/Rated/MagicalActions/AnimistPower.ml @@ -113,7 +113,7 @@ module Static = struct id : Id.AnimistPower.t; check : Check.t; costFromPrimaryPatron : string option; - tribes : int list; + tribes : int list option; property : int; ic : ic; prerequisites : Prerequisite.Collection.AnimistPower.t option; @@ -127,9 +127,10 @@ module Static = struct >>= fun id -> field "check" Check.Decode.t >>= fun check -> - field "costFromPrimaryPatron" (CostFromPrimaryPatron.make locale_order) + field_opt "costFromPrimaryPatron" + (CostFromPrimaryPatron.make locale_order) >>= fun costFromPrimaryPatron -> - field "tribes" (list int) + field_opt "tribes" (list int) >>= fun tribes -> field "property" int >>= fun property -> @@ -148,7 +149,7 @@ module Static = struct { id; check; - costFromPrimaryPatron; + costFromPrimaryPatron = Option.join costFromPrimaryPatron; tribes; property; ic; @@ -178,7 +179,8 @@ module Static = struct duration = Rated.Static.Activatable.MainParameter.Decode.make false translation.duration; - tribes = multilingual.tribes |> IntSet.fromList; + tribes = + multilingual.tribes |> Option.value ~default:[] |> IntSet.fromList; property = multilingual.property; ic = multilingual.ic; prerequisites = multilingual.prerequisites |> Option.value ~default:[]; diff --git a/src/Rated/Rated.ml b/src/Rated/Rated.ml index b15bfea6..c04e5789 100644 --- a/src/Rated/Rated.ml +++ b/src/Rated/Rated.ml @@ -604,7 +604,7 @@ end module Static = struct module Activatable = struct module MainParameter = struct - type t = { full : string; abbr : string; isNotModifiable : bool } + type t = { full : string; abbr : string; is_modifiable : bool } module Decode = struct open Decoders_bs.Decode @@ -616,8 +616,46 @@ module Static = struct >>= fun full -> field "abbr" string >>= fun abbr -> succeed { full; abbr } - let make isNotModifiable ({ full; abbr } : translation) = - { full; abbr; isNotModifiable } + let make is_modifiable ({ full; abbr } : translation) = + { full; abbr; is_modifiable } + end + end + + module EffectByQualityLevel = struct + type t = + | PerOne of { + ql1 : string; + ql2 : string; + ql3 : string; + ql4 : string; + ql5 : string; + ql6 : string; + } + | PerTwo of { ql1 : string; ql3 : string; ql5 : string } + + module Decode = struct + open Decoders_bs.Decode + + let t = + Parsing.Infix.( + string + >>=:: fun ql1 -> + string + >>=:: fun ql2 -> + string + >>=:: fun ql3 -> + one_of + [ + ( "per one", + string + >>=:: fun ql4 -> + string + >>=:: fun ql5 -> + string + >>=:: fun ql6 -> + succeed (PerOne { ql1; ql2; ql3; ql4; ql5; ql6 }) ); + ("per two", succeed (PerTwo { ql1; ql3 = ql2; ql5 = ql3 })); + ]) end end end diff --git a/src/Rated/Rated.mli b/src/Rated/Rated.mli index 07daccaf..273ce8e5 100644 --- a/src/Rated/Rated.mli +++ b/src/Rated/Rated.mli @@ -462,7 +462,7 @@ module Static : sig Casting/ritual/liturgical/ceremonial time, AE/KP cost, range and duration. *) module MainParameter : sig - type t = { full : string; abbr : string; isNotModifiable : bool } + type t = { full : string; abbr : string; is_modifiable : bool } (** A unified type to store the different values: The full parameter text, an abbreviated version for the character sheet and if the value is not modifiable. *) @@ -475,5 +475,22 @@ module Static : sig val make : bool -> translation -> t end end + + module EffectByQualityLevel : sig + type t = + | PerOne of { + ql1 : string; + ql2 : string; + ql3 : string; + ql4 : string; + ql5 : string; + ql6 : string; + } + | PerTwo of { ql1 : string; ql3 : string; ql5 : string } + + module Decode : sig + val t : t Decoders_bs.Decode.decoder + end + end end end diff --git a/src/Rated/Skill.ml b/src/Rated/Skill.ml index 3dd8caf2..24f7e930 100644 --- a/src/Rated/Skill.ml +++ b/src/Rated/Skill.ml @@ -7,7 +7,7 @@ module Static = struct module Application = struct type t = { - id : int; + id : IdGroup.Application.t; name : string; prerequisite : linked_activatable option; } @@ -37,17 +37,20 @@ module Static = struct multilingual.translations |> TranslationMap.preferred locale_order <&> fun translation -> - ( multilingual.id, - { id = multilingual.id; name = translation.name; prerequisite = None } - ) + ( IdGroup.Application.Generic multilingual.id, + { + id = Generic multilingual.id; + name = translation.name; + prerequisite = None; + } ) let make_map locale_order = list (make_assoc locale_order) >|= ListX.foldl' (function | None -> Function.id - | Some (key, value) -> IntMap.insert key value) - IntMap.empty + | Some (key, value) -> IdGroup.Application.Map.insert key value) + IdGroup.Application.Map.empty end end @@ -55,23 +58,23 @@ module Static = struct type t = { id : int; name : string; prerequisite : linked_activatable } end - type encumbrance = True | False | Maybe of string option + type encumbrance = True | False | Maybe of string type t = { id : Id.Skill.t; name : string; check : Check.t; - encumbrance : encumbrance; - gr : int; - ic : ImprovementCost.t; - applications : Application.t IntMap.t; + applications : Application.t IdGroup.Application.Map.t; applications_input : string option; uses : Use.t IntMap.t; + encumbrance : encumbrance; tools : string option; quality : string; failed : string; critical : string; botch : string; + improvement_cost : ImprovementCost.t; + gr : int; src : PublicationRef.list; errata : Erratum.list; } @@ -123,6 +126,53 @@ module Static = struct errata; } + type derived = Regions | Diseases + + let derived = + string + >>= function + | "Regions" -> succeed Regions + | "Diseases" -> succeed Diseases + | _ -> fail "Expected a category to derive applications from" + + type applications = + | Derived of derived + | Explicit of Application.t IdGroup.Application.Map.t + + let applications locale_order = + field "tag" string + >>= function + | "Derived" -> field "value" derived >|= fun mp -> Derived mp + | "Explicit" -> + field "list" (Application.Decode.make_map locale_order) + >|= fun mp -> Explicit mp + | _ -> fail "Expected either derived or explicit applications" + + let region_to_application (x : Region.t) : Application.t = + { id = Region x.id; name = x.name; prerequisite = None } + + let disease_to_application (x : Disease.t) : Application.t = + { id = Disease x.id; name = x.name; prerequisite = None } + + let resolve_applications ~regions ~diseases = function + | Derived derived -> ( + match derived with + | Regions -> + regions |> Id.Region.Map.to_array + |> IdGroup.Application.Map.( + Js.Array.reduce + (fun mp (key, x) -> + insert (Region key) (region_to_application x) mp) + empty) + | Diseases -> + diseases |> Id.Disease.Map.to_array + |> IdGroup.Application.Map.( + Js.Array.reduce + (fun mp (key, x) -> + insert (Disease key) (disease_to_application x) mp) + empty)) + | Explicit mp -> mp + type encumbrance_multilingual = True | False | Maybe let encumbrance_multilingual = @@ -136,9 +186,9 @@ module Static = struct type multilingual = { id : Id.Skill.t; check : Check.t; - applications : Application.t IntMap.t option; - ic : ImprovementCost.t; + applications : applications option; enc : encumbrance_multilingual; + improvement_cost : ImprovementCost.t; gr : int; src : PublicationRef.list; translations : translation TranslationMap.t; @@ -147,12 +197,12 @@ module Static = struct let multilingual locale_order = field "id" Id.Skill.Decode.t >>= fun id -> - field_opt "applications" (Application.Decode.make_map locale_order) + field_opt "applications" (applications locale_order) >>= fun applications -> field "check" Check.Decode.t >>= fun check -> - field "ic" ImprovementCost.Decode.t - >>= fun ic -> + field "improvement_cost" ImprovementCost.Decode.t + >>= fun improvement_cost -> field "enc" encumbrance_multilingual >>= fun enc -> field "gr" int @@ -161,39 +211,55 @@ module Static = struct >>= fun src -> field "translations" (TranslationMap.Decode.t translation) >>= fun translations -> - succeed { id; applications; check; ic; enc; gr; src; translations } + succeed + { + id; + applications; + check; + improvement_cost; + enc; + gr; + src; + translations; + } - let make_assoc locale_order = - let open Option.Infix in + let make_assoc ~regions ~diseases locale_order = multilingual locale_order - >|= fun multilingual -> + >>= fun multilingual -> multilingual.translations |> TranslationMap.preferred locale_order - <&> fun translation -> - ( multilingual.id, - { - id = multilingual.id; - name = translation.name; - check = multilingual.check; - encumbrance = - (match multilingual.enc with - | True -> True - | False -> False - | Maybe -> Maybe translation.encDescription); - applications = - multilingual.applications |> Option.value ~default:IntMap.empty; - applications_input = translation.applicationsInput; - uses = IntMap.empty; - ic = multilingual.ic; - gr = multilingual.gr; - tools = translation.tools; - quality = translation.quality; - failed = translation.failed; - critical = translation.critical; - botch = translation.botch; - src = multilingual.src; - errata = translation.errata |> Option.value ~default:[]; - } ) + |> function + | Some translation -> + (match (multilingual.enc, translation.encDescription) with + | True, None -> succeed (True : encumbrance) + | False, None -> succeed (False : encumbrance) + | Maybe, Some text -> succeed (Maybe text : encumbrance) + | (True | False), Some _ | Maybe, None -> fail "") + >|= fun encumbrance -> + Some + ( multilingual.id, + { + id = multilingual.id; + name = translation.name; + check = multilingual.check; + encumbrance; + applications = + multilingual.applications + |> Option.fold ~none:IdGroup.Application.Map.empty + ~some:(resolve_applications ~regions ~diseases); + applications_input = translation.applicationsInput; + uses = IntMap.empty; + improvement_cost = multilingual.improvement_cost; + gr = multilingual.gr; + tools = translation.tools; + quality = translation.quality; + failed = translation.failed; + critical = translation.critical; + botch = translation.botch; + src = multilingual.src; + errata = translation.errata |> Option.value ~default:[]; + } ) + | None -> succeed None end end @@ -204,7 +270,7 @@ module Dynamic = Rated.Dynamic.Make (struct type static = t - let ic x = x.ic + let ic x = x.improvement_cost let min_value = 0 end) diff --git a/src/Rated/Skill.mli b/src/Rated/Skill.mli index 9839175b..f9407657 100644 --- a/src/Rated/Skill.mli +++ b/src/Rated/Skill.mli @@ -17,7 +17,7 @@ module Static : sig (** Application of a skill. *) module Application : sig type t = { - id : int; + id : IdGroup.Application.t; name : string; prerequisite : linked_activatable option; (** If a [Some], the entry that needs to be active to enable this @@ -40,7 +40,7 @@ module Static : sig type encumbrance = | True (** Always. *) | False (** Never. *) - | Maybe of string option + | Maybe of string (** Depending on the context, which is explained in the associated localized string. *) @@ -48,23 +48,26 @@ module Static : sig id : Id.Skill.t; name : string; check : Check.t; - encumbrance : encumbrance; - gr : int; - ic : ImprovementCost.t; - applications : Application.t IntMap.t; + applications : Application.t IdGroup.Application.Map.t; applications_input : string option; uses : Use.t IntMap.t; + encumbrance : encumbrance; tools : string option; quality : string; failed : string; critical : string; botch : string; + improvement_cost : ImprovementCost.t; + gr : int; src : PublicationRef.list; errata : Erratum.list; } module Decode : sig - val make_assoc : (Id.Skill.t, t) Parsing.make_assoc + val make_assoc : + regions:Region.t Id.Region.Map.t -> + diseases:Disease.t Id.Disease.Map.t -> + (Id.Skill.t, t) Parsing.make_assoc end end diff --git a/src/Utilities/MapX.ml b/src/Utilities/MapX.ml index 0fd635ac..48754c98 100644 --- a/src/Utilities/MapX.ml +++ b/src/Utilities/MapX.ml @@ -73,6 +73,8 @@ module type T = sig val fromArray : (key * 'a) array -> 'a t + val to_array : 'a t -> (key * 'a) array + val filter : ('a -> bool) -> 'a t -> 'a t val filterWithKey : (key -> 'a -> bool) -> 'a t -> 'a t @@ -231,6 +233,13 @@ module Make (Key : Comparable) : T with type key = Key.t = struct let fromArray ps = Array.fold_left (fun mp (k, v) -> insert k v mp) empty ps + let to_array mp = + foldlWithKey + (fun arr key x -> + let _ = Js.Array.push (key, x) arr in + arr) + [||] mp + let filter pred mp = TypedMap.filter (fun _ x -> pred x) mp let filterWithKey = TypedMap.filter