Finished single inactive entry generation and validation
This commit is contained in:
@@ -32,6 +32,10 @@ function id(x) {
|
||||
}
|
||||
}
|
||||
|
||||
function id$prime(x) {
|
||||
return x._0.id;
|
||||
}
|
||||
|
||||
function name(x) {
|
||||
return x._0.name;
|
||||
}
|
||||
@@ -69,6 +73,24 @@ function apValue(x) {
|
||||
}
|
||||
}
|
||||
|
||||
function apValue$prime(x) {
|
||||
var match = apValue(x);
|
||||
if (match !== undefined) {
|
||||
if (match.TAG) {
|
||||
return {
|
||||
TAG: /* Many */1,
|
||||
_0: match._0
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
TAG: /* One */0,
|
||||
_0: match._0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function max(x) {
|
||||
switch (x.TAG | 0) {
|
||||
case /* Advantage */0 :
|
||||
@@ -84,10 +106,12 @@ export {
|
||||
isActive ,
|
||||
isActiveM ,
|
||||
id ,
|
||||
id$prime ,
|
||||
name ,
|
||||
selectOptions ,
|
||||
input ,
|
||||
apValue ,
|
||||
apValue$prime ,
|
||||
max ,
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,13 @@ let id = x =>
|
||||
| SpecialAbility(y) => `SpecialAbility(y.id)
|
||||
};
|
||||
|
||||
let id' = x =>
|
||||
switch (x) {
|
||||
| Advantage(y) => y.id
|
||||
| Disadvantage(y) => y.id
|
||||
| SpecialAbility(y) => y.id
|
||||
};
|
||||
|
||||
let name = x =>
|
||||
switch (x) {
|
||||
| Advantage(y) => y.name
|
||||
@@ -39,6 +46,13 @@ let apValue = x =>
|
||||
| SpecialAbility(y) => y.apValue
|
||||
};
|
||||
|
||||
let apValue' = x =>
|
||||
switch (apValue(x)) {
|
||||
| Some(Flat(y)) => Some(OneOrMany.One(y))
|
||||
| Some(PerLevel(ys)) => Some(Many(ys))
|
||||
| None => None
|
||||
};
|
||||
|
||||
let max = x =>
|
||||
switch (x) {
|
||||
| Advantage(y) => y.max
|
||||
|
||||
@@ -20,6 +20,8 @@ let isActiveM: option(Hero.Activatable.t) => bool;
|
||||
|
||||
let id: Static.activatable => Id.Activatable.t;
|
||||
|
||||
let id': Static.activatable => int;
|
||||
|
||||
let name: Static.activatable => string;
|
||||
|
||||
let selectOptions: Static.activatable => SelectOption.map;
|
||||
@@ -28,4 +30,6 @@ let input: Static.activatable => option(string);
|
||||
|
||||
let apValue: Static.activatable => option(Advantage.cost);
|
||||
|
||||
let apValue': Static.activatable => option(OneOrMany.t(int));
|
||||
|
||||
let max: Static.activatable => option(int);
|
||||
|
||||
@@ -1,12 +1,382 @@
|
||||
// Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
|
||||
|
||||
import * as Curry from "bs-platform/lib/es6/curry.js";
|
||||
import * as IC$OptolithClient from "../Increasable/IC.bs.js";
|
||||
import * as Id$OptolithClient from "../Misc/Id.bs.js";
|
||||
import * as Skills$OptolithClient from "../Increasable/Skills.bs.js";
|
||||
import * as Ley_List$OptolithClient from "../Data/Ley_List.bs.js";
|
||||
import * as Ley_IntMap$OptolithClient from "../Data/Ley_IntMap.bs.js";
|
||||
import * as Ley_Option$OptolithClient from "../Data/Ley_Option.bs.js";
|
||||
import * as EntryGroups$OptolithClient from "../Misc/EntryGroups.bs.js";
|
||||
import * as ActivatableSkills$OptolithClient from "../Increasable/ActivatableSkills.bs.js";
|
||||
import * as Activatable_Modifier$OptolithClient from "./Activatable_Modifier.bs.js";
|
||||
import * as Activatable_Accessors$OptolithClient from "./Activatable_Accessors.bs.js";
|
||||
import * as Activatable_Active_Validation$OptolithClient from "./Activatable_Active_Validation.bs.js";
|
||||
import * as Activatable_Inactive_Validation$OptolithClient from "./Activatable_Inactive_Validation.bs.js";
|
||||
import * as Activatable_Inactive_SelectOptions$OptolithClient from "./Activatable_Inactive_SelectOptions.bs.js";
|
||||
|
||||
function getSermonOrVisionCountMax(hero, advantageId, disadvantageId) {
|
||||
return Activatable_Modifier$OptolithClient.modifyByLevel(3, Curry._2(Ley_IntMap$OptolithClient.lookup, Id$OptolithClient.Advantage.toInt(advantageId), hero.advantages), Curry._2(Ley_IntMap$OptolithClient.lookup, Id$OptolithClient.Disadvantage.toInt(disadvantageId), hero.disadvantages));
|
||||
}
|
||||
|
||||
function getInactive(cache, staticData, hero, staticEntry, maybeHeroEntry) {
|
||||
var maxLevel = Activatable_Inactive_Validation$OptolithClient.getMaxLevel(staticData, hero, staticEntry, maybeHeroEntry);
|
||||
var isAdditionValid = Activatable_Inactive_Validation$OptolithClient.isAdditionValid(cache, staticData, hero, maxLevel, staticEntry, maybeHeroEntry);
|
||||
if (isAdditionValid) {
|
||||
return Ley_Option$OptolithClient.option({
|
||||
TAG: /* Invalid */1,
|
||||
_0: staticEntry
|
||||
}, (function (base) {
|
||||
return {
|
||||
TAG: /* Valid */0,
|
||||
_0: base
|
||||
};
|
||||
}), Ley_Option$OptolithClient.Monad.$great$great$eq(Ley_Option$OptolithClient.Monad.$less$amp$great(Activatable_Inactive_SelectOptions$OptolithClient.getAvailableSelectOptions(staticData, hero, cache.magicalTraditions, staticEntry, maybeHeroEntry), (function (selectOptions) {
|
||||
var tmp;
|
||||
switch (staticEntry.TAG | 0) {
|
||||
case /* Advantage */0 :
|
||||
tmp = Ley_List$OptolithClient.elem(staticEntry._0.id, cache.automaticAdvantages);
|
||||
break;
|
||||
case /* Disadvantage */1 :
|
||||
case /* SpecialAbility */2 :
|
||||
tmp = false;
|
||||
break;
|
||||
|
||||
}
|
||||
return {
|
||||
id: Activatable_Accessors$OptolithClient.id$prime(staticEntry),
|
||||
name: Activatable_Accessors$OptolithClient.name(staticEntry),
|
||||
apValue: Activatable_Accessors$OptolithClient.apValue$prime(staticEntry),
|
||||
minLevel: undefined,
|
||||
maxLevel: maxLevel,
|
||||
selectOptions: selectOptions,
|
||||
heroEntry: maybeHeroEntry,
|
||||
staticEntry: staticEntry,
|
||||
customCostDisabled: true,
|
||||
isAutomatic: tmp
|
||||
};
|
||||
})), (function (base) {
|
||||
switch (staticEntry.TAG | 0) {
|
||||
case /* Advantage */0 :
|
||||
return base;
|
||||
case /* Disadvantage */1 :
|
||||
var match = Id$OptolithClient.Disadvantage.fromInt(staticEntry._0.id);
|
||||
if (typeof match === "number") {
|
||||
if (match !== 22) {
|
||||
if (match >= 23) {
|
||||
return {
|
||||
id: base.id,
|
||||
name: base.name,
|
||||
apValue: base.apValue,
|
||||
minLevel: base.minLevel,
|
||||
maxLevel: Ley_Option$OptolithClient.ensure((function (param) {
|
||||
return 0 < param;
|
||||
}), Activatable_Active_Validation$OptolithClient.getMaxLevelForDecreaseEntry(3, EntryGroups$OptolithClient.SpecialAbility.countActiveFromGroup(typeof match === "number" && match === 23 ? /* Predigten */23 : /* Visionen */26, cache.specialAbilityPairs))),
|
||||
selectOptions: base.selectOptions,
|
||||
heroEntry: base.heroEntry,
|
||||
staticEntry: base.staticEntry,
|
||||
customCostDisabled: base.customCostDisabled,
|
||||
isAutomatic: base.isAutomatic
|
||||
};
|
||||
} else {
|
||||
return base;
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
id: base.id,
|
||||
name: base.name,
|
||||
apValue: base.apValue,
|
||||
minLevel: base.minLevel,
|
||||
maxLevel: Ley_Option$OptolithClient.ensure((function (param) {
|
||||
return 0 < param;
|
||||
}), Activatable_Active_Validation$OptolithClient.getMaxLevelForDecreaseEntry(3, ActivatableSkills$OptolithClient.countActiveSkillEntries(/* Spells */0, hero))),
|
||||
selectOptions: base.selectOptions,
|
||||
heroEntry: base.heroEntry,
|
||||
staticEntry: base.staticEntry,
|
||||
customCostDisabled: base.customCostDisabled,
|
||||
isAutomatic: base.isAutomatic
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return base;
|
||||
}
|
||||
case /* SpecialAbility */2 :
|
||||
var staticSpecialAbility = staticEntry._0;
|
||||
var match$1 = Id$OptolithClient.SpecialAbility.fromInt(staticSpecialAbility.id);
|
||||
var exit = 0;
|
||||
if (typeof match$1 !== "number") {
|
||||
return base;
|
||||
}
|
||||
if (match$1 >= 54) {
|
||||
if (match$1 >= 71) {
|
||||
switch (match$1 - 71 | 0) {
|
||||
case /* PropertyFocus */11 :
|
||||
exit = 3;
|
||||
break;
|
||||
case /* Harmoniezauberei */21 :
|
||||
exit = 6;
|
||||
break;
|
||||
case /* SkillSpecialization */0 :
|
||||
case /* Hunter */3 :
|
||||
case /* AreaKnowledge */4 :
|
||||
case /* Literacy */5 :
|
||||
case /* Language */6 :
|
||||
case /* CombatReflexes */7 :
|
||||
case /* ImprovedDodge */8 :
|
||||
case /* TraditionGuildMages */9 :
|
||||
case /* PropertyKnowledge */10 :
|
||||
case /* AspectKnowledge */12 :
|
||||
case /* TraditionChurchOfPraios */13 :
|
||||
case /* Feuerschlucker */14 :
|
||||
case /* CombatStyleCombination */15 :
|
||||
case /* AdaptionZauber */16 :
|
||||
case /* Exorzist */17 :
|
||||
case /* FavoriteSpellwork */18 :
|
||||
case /* TraditionWitches */19 :
|
||||
case /* MagicStyleCombination */20 :
|
||||
case /* TraditionElves */23 :
|
||||
case /* TraditionDruids */24 :
|
||||
return base;
|
||||
case /* TerrainKnowledge */1 :
|
||||
case /* CraftInstruments */2 :
|
||||
case /* Matrixzauberei */22 :
|
||||
case /* SpellEnhancement */25 :
|
||||
exit = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
exit = 3;
|
||||
}
|
||||
} else {
|
||||
switch (match$1) {
|
||||
case /* CraftInstruments */2 :
|
||||
var getSkillValue = function (skill) {
|
||||
return Skills$OptolithClient.getValueDef(Curry._2(Ley_IntMap$OptolithClient.lookup, Id$OptolithClient.Skill.toInt(skill), hero.skills));
|
||||
};
|
||||
if ((getSkillValue(/* Woodworking */50) + getSkillValue(/* Metalworking */54) | 0) >= 12) {
|
||||
return base;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
case /* Hunter */3 :
|
||||
if (Curry._2(Ley_IntMap$OptolithClient.IntMap.Foldable.any, (function (param) {
|
||||
var heroEntry = param[1];
|
||||
return heroEntry !== undefined ? heroEntry.value >= 10 : false;
|
||||
}), EntryGroups$OptolithClient.CombatTechnique.getFromGroup(/* Ranged */1, cache.combatTechniquePairs))) {
|
||||
return base;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
case /* PropertyKnowledge */10 :
|
||||
case /* AspectKnowledge */12 :
|
||||
exit = 2;
|
||||
break;
|
||||
case /* TraditionChurchOfPraios */13 :
|
||||
exit = 3;
|
||||
break;
|
||||
case /* Recherchegespuer */29 :
|
||||
return Ley_Option$OptolithClient.Monad.$great$great$eq(Ley_Option$OptolithClient.Monad.$great$great$eq(Ley_Option$OptolithClient.Monad.$great$great$eq(Ley_Option$OptolithClient.Monad.$great$great$eq(Ley_Option$OptolithClient.Monad.$less$amp$great(Curry._2(Ley_IntMap$OptolithClient.lookup, Id$OptolithClient.SpecialAbility.toInt(/* Wissensdurst */28), hero.specialAbilities), (function (param) {
|
||||
return param.active;
|
||||
})), Ley_Option$OptolithClient.listToOption), (function (param) {
|
||||
return Ley_Option$OptolithClient.listToOption(param.options);
|
||||
})), (function (param) {
|
||||
if (typeof param === "number" || param.HASH !== 290194801) {
|
||||
return ;
|
||||
} else {
|
||||
return Curry._2(Ley_IntMap$OptolithClient.lookup, param.VAL, staticData.skills);
|
||||
}
|
||||
})), (function (param) {
|
||||
var match = staticSpecialAbility.apValue;
|
||||
if (match === undefined) {
|
||||
return ;
|
||||
}
|
||||
if (!match.TAG) {
|
||||
return ;
|
||||
}
|
||||
var partial_arg = IC$OptolithClient.getAPForActivatation(param.ic);
|
||||
var sumValues = Ley_List$OptolithClient.map((function (param) {
|
||||
return partial_arg + param | 0;
|
||||
}), match._0);
|
||||
return Ley_Option$OptolithClient.Monad.$$return({
|
||||
id: base.id,
|
||||
name: base.name,
|
||||
apValue: {
|
||||
TAG: /* Many */1,
|
||||
_0: sumValues
|
||||
},
|
||||
minLevel: base.minLevel,
|
||||
maxLevel: base.maxLevel,
|
||||
selectOptions: base.selectOptions,
|
||||
heroEntry: base.heroEntry,
|
||||
staticEntry: base.staticEntry,
|
||||
customCostDisabled: base.customCostDisabled,
|
||||
isAutomatic: base.isAutomatic
|
||||
});
|
||||
}));
|
||||
case /* PredigtDerGemeinschaft */30 :
|
||||
case /* PredigtDerZuversicht */31 :
|
||||
case /* PredigtDesGottvertrauens */32 :
|
||||
case /* PredigtDesWohlgefallens */33 :
|
||||
case /* PredigtWiderMissgeschicke */34 :
|
||||
exit = 4;
|
||||
break;
|
||||
case /* VisionDerBestimmung */35 :
|
||||
case /* VisionDerEntrueckung */36 :
|
||||
case /* VisionDerGottheit */37 :
|
||||
case /* VisionDesSchicksals */38 :
|
||||
case /* VisionDesWahrenGlaubens */39 :
|
||||
exit = 5;
|
||||
break;
|
||||
case /* SkillSpecialization */0 :
|
||||
case /* TerrainKnowledge */1 :
|
||||
case /* AreaKnowledge */4 :
|
||||
case /* Literacy */5 :
|
||||
case /* Language */6 :
|
||||
case /* CombatReflexes */7 :
|
||||
case /* ImprovedDodge */8 :
|
||||
case /* PropertyFocus */11 :
|
||||
case /* Feuerschlucker */14 :
|
||||
case /* CombatStyleCombination */15 :
|
||||
case /* AdaptionZauber */16 :
|
||||
case /* Exorzist */17 :
|
||||
case /* FavoriteSpellwork */18 :
|
||||
case /* MagicStyleCombination */20 :
|
||||
case /* Harmoniezauberei */21 :
|
||||
case /* Matrixzauberei */22 :
|
||||
case /* SpellEnhancement */25 :
|
||||
case /* Forschungsgebiet */26 :
|
||||
case /* Expertenwissen */27 :
|
||||
case /* Wissensdurst */28 :
|
||||
case /* HoheWeihe */40 :
|
||||
case /* Lieblingsliturgie */41 :
|
||||
case /* Zugvoegel */42 :
|
||||
case /* JaegerinnenDerWeissenMaid */43 :
|
||||
case /* AnhaengerDesGueldenen */44 :
|
||||
case /* GebieterDesAspekts */45 :
|
||||
case /* ChantEnhancement */46 :
|
||||
return base;
|
||||
case /* DunklesAbbildDerBuendnisgabe */47 :
|
||||
return Ley_Option$OptolithClient.Monad.$great$great$eq(hero.pact, (function (param) {
|
||||
var level = param.level;
|
||||
if (level > 0) {
|
||||
return {
|
||||
id: base.id,
|
||||
name: base.name,
|
||||
apValue: base.apValue,
|
||||
minLevel: base.minLevel,
|
||||
maxLevel: level,
|
||||
selectOptions: base.selectOptions,
|
||||
heroEntry: base.heroEntry,
|
||||
staticEntry: base.staticEntry,
|
||||
customCostDisabled: base.customCostDisabled,
|
||||
isAutomatic: base.isAutomatic
|
||||
};
|
||||
}
|
||||
|
||||
}));
|
||||
case /* TraditionArcaneBard */49 :
|
||||
case /* TraditionArcaneDancer */50 :
|
||||
case /* TraditionIntuitiveMage */51 :
|
||||
case /* TraditionSavant */52 :
|
||||
exit = 6;
|
||||
break;
|
||||
case /* TraditionGuildMages */9 :
|
||||
case /* TraditionWitches */19 :
|
||||
case /* TraditionElves */23 :
|
||||
case /* TraditionDruids */24 :
|
||||
case /* TraditionIllusionist */48 :
|
||||
case /* TraditionQabalyaMage */53 :
|
||||
exit = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
switch (exit) {
|
||||
case 1 :
|
||||
if (Ley_List$OptolithClient.Foldable.$$null(cache.magicalTraditions)) {
|
||||
return base;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
case 2 :
|
||||
var match$2 = staticSpecialAbility.apValue;
|
||||
if (match$2 === undefined) {
|
||||
return ;
|
||||
}
|
||||
if (!match$2.TAG) {
|
||||
return ;
|
||||
}
|
||||
var index = Ley_Option$OptolithClient.option(0, (function (param) {
|
||||
return Ley_List$OptolithClient.Foldable.length(param.active);
|
||||
}), maybeHeroEntry);
|
||||
return Ley_Option$OptolithClient.Functor.$less$amp$great(Ley_List$OptolithClient.Safe.atMay(match$2._0, index), (function (apValue) {
|
||||
return {
|
||||
id: base.id,
|
||||
name: base.name,
|
||||
apValue: {
|
||||
TAG: /* One */0,
|
||||
_0: apValue
|
||||
},
|
||||
minLevel: base.minLevel,
|
||||
maxLevel: base.maxLevel,
|
||||
selectOptions: base.selectOptions,
|
||||
heroEntry: base.heroEntry,
|
||||
staticEntry: base.staticEntry,
|
||||
customCostDisabled: base.customCostDisabled,
|
||||
isAutomatic: base.isAutomatic
|
||||
};
|
||||
}));
|
||||
case 3 :
|
||||
if (Ley_Option$OptolithClient.isNone(cache.blessedTradition)) {
|
||||
return base;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
case 4 :
|
||||
var isAdvActive = function (id) {
|
||||
return Activatable_Accessors$OptolithClient.isActiveM(Curry._2(Ley_IntMap$OptolithClient.lookup, Id$OptolithClient.Advantage.toInt(id), hero.advantages));
|
||||
};
|
||||
var max = getSermonOrVisionCountMax(hero, /* ZahlreichePredigten */24, /* WenigePredigten */23);
|
||||
var isLessThanMax = EntryGroups$OptolithClient.SpecialAbility.countActiveFromGroup(/* Predigten */23, cache.specialAbilityPairs) < max;
|
||||
if (isAdvActive(/* Prediger */22) && isLessThanMax || isAdvActive(/* Blessed */2)) {
|
||||
return base;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
case 5 :
|
||||
var isAdvActive$1 = function (id) {
|
||||
return Activatable_Accessors$OptolithClient.isActiveM(Curry._2(Ley_IntMap$OptolithClient.lookup, Id$OptolithClient.Advantage.toInt(id), hero.advantages));
|
||||
};
|
||||
var max$1 = getSermonOrVisionCountMax(hero, /* ZahlreicheVisionen */25, /* WenigeVisionen */24);
|
||||
var isLessThanMax$1 = EntryGroups$OptolithClient.SpecialAbility.countActiveFromGroup(/* Visionen */26, cache.specialAbilityPairs) < max$1;
|
||||
if (isAdvActive$1(/* Visionaer */23) && isLessThanMax$1 || isAdvActive$1(/* Blessed */2)) {
|
||||
return base;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
case 6 :
|
||||
if (cache.adventurePoints.spentOnMagicalAdvantages <= 25 && cache.adventurePoints.spentOnMagicalDisadvantages <= 25 && Ley_List$OptolithClient.Foldable.$$null(cache.magicalTraditions)) {
|
||||
return base;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
})));
|
||||
} else {
|
||||
return {
|
||||
TAG: /* Invalid */1,
|
||||
_0: staticEntry
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
getInactive ,
|
||||
|
||||
}
|
||||
/* Skills-OptolithClient Not a pure module */
|
||||
|
||||
@@ -2,19 +2,25 @@ module IM = Ley_IntMap;
|
||||
module L = Ley_List;
|
||||
module O = Ley_Option;
|
||||
|
||||
type t = {
|
||||
id: string,
|
||||
open Activatable_Inactive_Cache;
|
||||
|
||||
type valid = {
|
||||
id: int,
|
||||
name: string,
|
||||
cost: option(OneOrMany.t(int)),
|
||||
apValue: option(OneOrMany.t(int)),
|
||||
minLevel: option(int),
|
||||
maxLevel: option(int),
|
||||
selectOptions: option(list(SelectOption.t)),
|
||||
selectOptions: list(SelectOption.t),
|
||||
heroEntry: option(Hero.Activatable.t),
|
||||
staticEntry: Static.activatable,
|
||||
customCostDisabled: bool,
|
||||
isAutomatic: bool,
|
||||
};
|
||||
|
||||
type t =
|
||||
| Valid(valid)
|
||||
| Invalid(Static.activatable);
|
||||
|
||||
let getSermonOrVisionCountMax = (hero: Hero.t, advantageId, disadvantageId) =>
|
||||
Activatable_Modifier.modifyByLevel(
|
||||
3,
|
||||
@@ -23,18 +29,7 @@ let getSermonOrVisionCountMax = (hero: Hero.t, advantageId, disadvantageId) =>
|
||||
);
|
||||
|
||||
let modifyOtherOptions =
|
||||
(
|
||||
~staticData: Static.t,
|
||||
~hero,
|
||||
~specialAbilityPairs,
|
||||
~combatTechniquePairs,
|
||||
~adventurePoints: AdventurePoints.categories,
|
||||
~magicalTraditions,
|
||||
~blessedTradition,
|
||||
~staticEntry,
|
||||
~maybeHeroEntry,
|
||||
~base,
|
||||
) =>
|
||||
(cache, staticData: Static.t, hero, staticEntry, maybeHeroEntry, base) =>
|
||||
switch (staticEntry) {
|
||||
| Static.Advantage(_) => Some(base)
|
||||
| Disadvantage(staticDisadvantage) =>
|
||||
@@ -46,26 +41,24 @@ let modifyOtherOptions =
|
||||
Some({
|
||||
...base,
|
||||
maxLevel:
|
||||
Some(
|
||||
EntryGroups.SpecialAbility.countActiveFromGroup(
|
||||
switch (id) {
|
||||
| WenigePredigten => Predigten
|
||||
| _ => Visionen
|
||||
},
|
||||
specialAbilityPairs,
|
||||
)
|
||||
|> Activatable_Active_Validation.getMaxLevelForDecreaseEntry(3),
|
||||
),
|
||||
EntryGroups.SpecialAbility.countActiveFromGroup(
|
||||
switch (id) {
|
||||
| WenigePredigten => Predigten
|
||||
| _ => Visionen
|
||||
},
|
||||
cache.specialAbilityPairs,
|
||||
)
|
||||
|> Activatable_Active_Validation.getMaxLevelForDecreaseEntry(3)
|
||||
|> O.ensure((<)(0)),
|
||||
})
|
||||
|
||||
| SmallSpellSelection =>
|
||||
Some({
|
||||
...base,
|
||||
maxLevel:
|
||||
Some(
|
||||
ActivatableSkills.countActiveSkillEntries(Spells, hero)
|
||||
|> Activatable_Active_Validation.getMaxLevelForDecreaseEntry(3),
|
||||
),
|
||||
ActivatableSkills.countActiveSkillEntries(Spells, hero)
|
||||
|> Activatable_Active_Validation.getMaxLevelForDecreaseEntry(3)
|
||||
|> O.ensure((<)(0)),
|
||||
})
|
||||
|
||||
| _ => Some(base)
|
||||
@@ -86,7 +79,10 @@ let modifyOtherOptions =
|
||||
? Some(base) : None;
|
||||
|
||||
| Hunter =>
|
||||
EntryGroups.CombatTechnique.getFromGroup(Ranged, combatTechniquePairs)
|
||||
EntryGroups.CombatTechnique.getFromGroup(
|
||||
Ranged,
|
||||
cache.combatTechniquePairs,
|
||||
)
|
||||
|> IM.Foldable.any(
|
||||
fun
|
||||
// At least one ranged combat technique must be on CtR 10 or higher
|
||||
@@ -106,7 +102,7 @@ let modifyOtherOptions =
|
||||
| TraditionSchelme
|
||||
| TraditionBrobimGeoden =>
|
||||
// Only one tradition allowed
|
||||
L.Foldable.null(magicalTraditions) ? Some(base) : None
|
||||
L.Foldable.null(cache.magicalTraditions) ? Some(base) : None
|
||||
|
||||
| PropertyKnowledge
|
||||
| AspectKnowledge =>
|
||||
@@ -122,7 +118,7 @@ let modifyOtherOptions =
|
||||
|
||||
O.Functor.(
|
||||
L.Safe.atMay(values, index)
|
||||
<&> (apValue => {...base, cost: Some(One(apValue))})
|
||||
<&> (apValue => {...base, apValue: Some(One(apValue))})
|
||||
);
|
||||
| Some(Flat(_))
|
||||
| None => None
|
||||
@@ -148,7 +144,7 @@ let modifyOtherOptions =
|
||||
| TraditionChurchOfSwafnir
|
||||
| TraditionCultOfNuminoru =>
|
||||
// Only one tradition allowed
|
||||
O.isNone(blessedTradition) ? Some(base) : None
|
||||
O.isNone(cache.blessedTradition) ? Some(base) : None
|
||||
|
||||
| Recherchegespuer =>
|
||||
O.Monad.(
|
||||
@@ -170,7 +166,7 @@ let modifyOtherOptions =
|
||||
|> L.map((+)(IC.getAPForActivatation(ic)))
|
||||
|> (
|
||||
sumValues =>
|
||||
{...base, cost: Some(Many(sumValues))} |> return
|
||||
{...base, apValue: Some(Many(sumValues))} |> return
|
||||
)
|
||||
| Some(Flat(_))
|
||||
| None => None
|
||||
@@ -197,7 +193,7 @@ let modifyOtherOptions =
|
||||
let isLessThanMax =
|
||||
EntryGroups.SpecialAbility.countActiveFromGroup(
|
||||
Predigten,
|
||||
specialAbilityPairs,
|
||||
cache.specialAbilityPairs,
|
||||
)
|
||||
< max;
|
||||
|
||||
@@ -219,7 +215,7 @@ let modifyOtherOptions =
|
||||
let isLessThanMax =
|
||||
EntryGroups.SpecialAbility.countActiveFromGroup(
|
||||
Visionen,
|
||||
specialAbilityPairs,
|
||||
cache.specialAbilityPairs,
|
||||
)
|
||||
< max;
|
||||
|
||||
@@ -227,8 +223,12 @@ let modifyOtherOptions =
|
||||
? Some(base) : None;
|
||||
|
||||
| DunklesAbbildDerBuendnisgabe =>
|
||||
O.Functor.(
|
||||
hero.pact <&> (({level, _}) => {...base, maxLevel: Some(level)})
|
||||
O.Monad.(
|
||||
hero.pact
|
||||
>>= (
|
||||
({level, _}) =>
|
||||
level > 0 ? Some({...base, maxLevel: Some(level)}) : None
|
||||
)
|
||||
)
|
||||
|
||||
| TraditionArcaneBard
|
||||
@@ -236,84 +236,77 @@ let modifyOtherOptions =
|
||||
| TraditionIntuitiveMage
|
||||
| TraditionSavant
|
||||
| TraditionAnimisten =>
|
||||
adventurePoints.spentOnMagicalAdvantages <= 25
|
||||
&& adventurePoints.spentOnMagicalDisadvantages <= 25
|
||||
&& L.Foldable.null(magicalTraditions)
|
||||
cache.adventurePoints.spentOnMagicalAdvantages <= 25
|
||||
&& cache.adventurePoints.spentOnMagicalDisadvantages <= 25
|
||||
&& L.Foldable.null(cache.magicalTraditions)
|
||||
? Some(base) : None
|
||||
|
||||
| _ => Some(base)
|
||||
}
|
||||
)
|
||||
};
|
||||
//
|
||||
// /**
|
||||
// * Calculates whether an Activatable is valid to add or not and, if valid,
|
||||
// * calculates and filters necessary properties and selection lists. Returns a
|
||||
// * Maybe of the result or `undefined` if invalid.
|
||||
// */
|
||||
// export const getInactiveView =
|
||||
// (staticData: StaticDataRecord) =>
|
||||
// (hero: HeroModelRecord) =>
|
||||
// (automatic_advantages: List<string>) =>
|
||||
// (required_apply_to_mag_actions: boolean) =>
|
||||
// (matching_script_and_lang_related: Tuple<[boolean, List<number>, List<number>]>) =>
|
||||
// (adventure_points: Record<AdventurePointsCategories>) =>
|
||||
// (validExtendedSpecialAbilities: List<string>) =>
|
||||
// (hero_magical_traditions: List<Record<ActivatableDependent>>) =>
|
||||
// (wiki_entry: Activatable) =>
|
||||
// (mhero_entry: Maybe<Record<ActivatableDependent>>): Maybe<Record<InactiveActivatable>> => {
|
||||
// const current_id = AAL.id (wiki_entry)
|
||||
// const current_prerequisites = AAL.prerequisites (wiki_entry)
|
||||
//
|
||||
// const max_level = isOrderedMap (current_prerequisites)
|
||||
// ? validateLevel (staticData)
|
||||
// (hero)
|
||||
// (current_prerequisites)
|
||||
// (maybe<ActivatableDependent["dependencies"]> (List ())
|
||||
// (ADA.dependencies)
|
||||
// (mhero_entry))
|
||||
// (current_id)
|
||||
// : Nothing
|
||||
//
|
||||
// const isNotValid = isAdditionDisabled (staticData)
|
||||
// (hero)
|
||||
// (required_apply_to_mag_actions)
|
||||
// (validExtendedSpecialAbilities)
|
||||
// (matching_script_and_lang_related)
|
||||
// (wiki_entry)
|
||||
// (mhero_entry)
|
||||
// (max_level)
|
||||
//
|
||||
// if (!isNotValid) {
|
||||
// return pipe_ (
|
||||
// wiki_entry,
|
||||
// AAL.select,
|
||||
// modifySelectOptions (staticData)
|
||||
// (hero)
|
||||
// (hero_magical_traditions)
|
||||
// (wiki_entry)
|
||||
// (mhero_entry),
|
||||
// ensure (maybe (true) (notNull)),
|
||||
// fmap (select_options => InactiveActivatable ({
|
||||
// id: current_id,
|
||||
// name: SpAL.name (wiki_entry),
|
||||
// cost: AAL.cost (wiki_entry),
|
||||
// maxLevel: max_level,
|
||||
// heroEntry: mhero_entry,
|
||||
// wikiEntry: wiki_entry as Record<RecordI<Activatable>>,
|
||||
// selectOptions: fmapF (select_options)
|
||||
// (sortRecordsByName (staticData)),
|
||||
// isAutomatic: List.elem (AAL.id (wiki_entry))
|
||||
// (automatic_advantages),
|
||||
// })),
|
||||
// ap (modifyOtherOptions (staticData)
|
||||
// (hero)
|
||||
// (adventure_points)
|
||||
// (wiki_entry)
|
||||
// (mhero_entry)),
|
||||
// bindF (ensure (pipe (IAA.maxLevel, maybe (true) (notEquals (0)))))
|
||||
// )
|
||||
// }
|
||||
//
|
||||
// return Nothing
|
||||
/* */
|
||||
|
||||
let getInactive = (cache, staticData, hero, staticEntry, maybeHeroEntry) => {
|
||||
let maxLevel =
|
||||
Activatable_Inactive_Validation.getMaxLevel(
|
||||
staticData,
|
||||
hero,
|
||||
staticEntry,
|
||||
maybeHeroEntry,
|
||||
);
|
||||
|
||||
let isAdditionValid =
|
||||
Activatable_Inactive_Validation.isAdditionValid(
|
||||
cache,
|
||||
staticData,
|
||||
hero,
|
||||
maxLevel,
|
||||
staticEntry,
|
||||
maybeHeroEntry,
|
||||
);
|
||||
|
||||
if (isAdditionValid) {
|
||||
O.Monad.(
|
||||
Activatable_Inactive_SelectOptions.getAvailableSelectOptions(
|
||||
staticData,
|
||||
hero,
|
||||
cache.magicalTraditions,
|
||||
staticEntry,
|
||||
maybeHeroEntry,
|
||||
)
|
||||
<&> (
|
||||
selectOptions => {
|
||||
id: Activatable_Accessors.id'(staticEntry),
|
||||
name: Activatable_Accessors.name(staticEntry),
|
||||
apValue: Activatable_Accessors.apValue'(staticEntry),
|
||||
minLevel: None,
|
||||
maxLevel,
|
||||
selectOptions,
|
||||
heroEntry: maybeHeroEntry,
|
||||
staticEntry,
|
||||
customCostDisabled: true,
|
||||
isAutomatic:
|
||||
switch (staticEntry) {
|
||||
| Advantage({id, _}) => L.elem(id, cache.automaticAdvantages)
|
||||
| Disadvantage(_)
|
||||
| SpecialAbility(_) => false
|
||||
},
|
||||
}
|
||||
)
|
||||
>>= (
|
||||
base =>
|
||||
modifyOtherOptions(
|
||||
cache,
|
||||
staticData,
|
||||
hero,
|
||||
staticEntry,
|
||||
maybeHeroEntry,
|
||||
base,
|
||||
)
|
||||
)
|
||||
|> O.option(Invalid(staticEntry), base => Valid(base))
|
||||
);
|
||||
} else {
|
||||
Invalid(staticEntry);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
type valid = {
|
||||
id: int,
|
||||
name: string,
|
||||
apValue: option(OneOrMany.t(int)),
|
||||
minLevel: option(int),
|
||||
maxLevel: option(int),
|
||||
selectOptions: list(SelectOption.t),
|
||||
heroEntry: option(Hero.Activatable.t),
|
||||
staticEntry: Static.activatable,
|
||||
customCostDisabled: bool,
|
||||
isAutomatic: bool,
|
||||
};
|
||||
|
||||
type t =
|
||||
| Valid(valid)
|
||||
| Invalid(Static.activatable);
|
||||
|
||||
/**
|
||||
* `getInactive cache staticData hero staticEntry maybeHeroEntry` validates an
|
||||
* inactive entry, filters possible options and then either returns a valid
|
||||
* entry with additional and filtered options or an invalid entry.
|
||||
*
|
||||
* This can be used to display valid as well as invalid entries in a single
|
||||
* list.
|
||||
*/
|
||||
let getInactive:
|
||||
(
|
||||
Activatable_Inactive_Cache.t,
|
||||
Static.t,
|
||||
Hero.t,
|
||||
Static.activatable,
|
||||
option(Hero.Activatable.t)
|
||||
) =>
|
||||
t;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// Generated by BUCKLESCRIPT, PLEASE EDIT WITH CARE
|
||||
/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* A set of values to validate `Weg der Schreiberin`.
|
||||
*/
|
||||
type matchingLanguagesScripts = {
|
||||
isEntryActiveRequiringMatch: bool,
|
||||
languagesWithMatchingScripts: list(int),
|
||||
scriptsWithMatchingLanguages: list(int),
|
||||
};
|
||||
|
||||
/**
|
||||
* The cache of computed values to optimize performance of `isAdditionValid`.
|
||||
*/
|
||||
type t = {
|
||||
combatStyleCombination: option(Hero.Activatable.t),
|
||||
armedCombatStylesCount: int,
|
||||
unarmedCombatStylesCount: int,
|
||||
magicalStylesCount: int,
|
||||
isBlessedStyleActive: bool,
|
||||
isSkillStyleActive: bool,
|
||||
magicalStyleCombination: option(Hero.Activatable.t),
|
||||
dunklesAbbild: option(Hero.Activatable.t),
|
||||
activePactGiftsCount: int,
|
||||
matchingLanguagesScripts,
|
||||
validExtendedSpecialAbilities: list(int),
|
||||
requiredApplyToMagicalActions: bool,
|
||||
specialAbilityPairs:
|
||||
Ley_IntMap.t((SpecialAbility.t, option(Hero.Activatable.t))),
|
||||
combatTechniquePairs:
|
||||
Ley_IntMap.t((CombatTechnique.t, option(Hero.Skill.t))),
|
||||
adventurePoints: AdventurePoints.categories,
|
||||
magicalTraditions: list(Tradition.Magical.fullTradition),
|
||||
blessedTradition: option(Tradition.Blessed.fullTradition),
|
||||
automaticAdvantages: list(int),
|
||||
};
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
import * as Curry from "bs-platform/lib/es6/curry.js";
|
||||
import * as Id$OptolithClient from "../Misc/Id.bs.js";
|
||||
import * as Ley_Int$OptolithClient from "../Data/Ley_Int.bs.js";
|
||||
import * as Ley_List$OptolithClient from "../Data/Ley_List.bs.js";
|
||||
import * as Ley_IntMap$OptolithClient from "../Data/Ley_IntMap.bs.js";
|
||||
import * as Ley_Option$OptolithClient from "../Data/Ley_Option.bs.js";
|
||||
import * as EntryGroups$OptolithClient from "../Misc/EntryGroups.bs.js";
|
||||
import * as Dependencies$OptolithClient from "../Prerequisites/Dependencies.bs.js";
|
||||
import * as Ley_Function$OptolithClient from "../Data/Ley_Function.bs.js";
|
||||
import * as Prerequisites$OptolithClient from "../Prerequisites/Prerequisites.bs.js";
|
||||
import * as Activatable_Accessors$OptolithClient from "./Activatable_Accessors.bs.js";
|
||||
@@ -40,7 +43,9 @@ function getActivePactGiftsCount(specialAbilityPairs) {
|
||||
function isSpecialAbilitySpecificAdditionEnabled(rules, maybePact, param, specialAbility) {
|
||||
var matchingLanguagesScripts = param.matchingLanguagesScripts;
|
||||
var activePactGiftsCount = param.activePactGiftsCount;
|
||||
var specialAbilityPairs = param.specialAbilityPairs;
|
||||
var magicalStylesCount = param.magicalStylesCount;
|
||||
var unarmedCombatStylesCount = param.unarmedCombatStylesCount;
|
||||
var armedCombatStylesCount = param.armedCombatStylesCount;
|
||||
var match = Id$OptolithClient.SpecialAbility.fromInt(specialAbility.id);
|
||||
var match$1 = Curry._1(Id$OptolithClient.SpecialAbility.Group.fromInt, specialAbility.gr);
|
||||
var exit = 0;
|
||||
@@ -49,34 +54,31 @@ function isSpecialAbilitySpecificAdditionEnabled(rules, maybePact, param, specia
|
||||
if (typeof match$1 === "number") {
|
||||
if (match$1 >= 13) {
|
||||
if (match$1 === 24) {
|
||||
return !EntryGroups$OptolithClient.SpecialAbility.hasActiveFromGroup(match$1, specialAbilityPairs);
|
||||
return !param.isBlessedStyleActive;
|
||||
}
|
||||
if (match$1 === 32) {
|
||||
return !EntryGroups$OptolithClient.SpecialAbility.hasActiveFromGroup(match$1, specialAbilityPairs);
|
||||
return !param.isSkillStyleActive;
|
||||
}
|
||||
exit$2 = 4;
|
||||
} else if (match$1 >= 10) {
|
||||
if (match$1 >= 12) {
|
||||
var totalActive = EntryGroups$OptolithClient.SpecialAbility.countActiveFromGroup(/* MagicalStyles */12, specialAbilityPairs);
|
||||
return totalActive < (
|
||||
return magicalStylesCount < (
|
||||
Activatable_Accessors$OptolithClient.isActiveM(param.magicalStyleCombination) ? 2 : 1
|
||||
);
|
||||
}
|
||||
exit$2 = 4;
|
||||
} else {
|
||||
if (match$1 >= 8) {
|
||||
var equalTypeStylesActive = typeof match$1 === "number" ? (
|
||||
match$1 !== 8 ? (
|
||||
match$1 !== 9 ? 0 : unarmedCombatStylesCount
|
||||
) : armedCombatStylesCount
|
||||
) : 0;
|
||||
if (!Activatable_Accessors$OptolithClient.isActiveM(param.combatStyleCombination)) {
|
||||
return !EntryGroups$OptolithClient.SpecialAbility.hasActiveFromGroup(Curry._1(Id$OptolithClient.SpecialAbility.Group.fromInt, specialAbility.gr), specialAbilityPairs);
|
||||
return equalTypeStylesActive === 0;
|
||||
}
|
||||
var totalActive$1 = EntryGroups$OptolithClient.SpecialAbility.countActiveFromGroups({
|
||||
hd: /* CombatStylesArmed */8,
|
||||
tl: {
|
||||
hd: /* CombatStylesUnarmed */9,
|
||||
tl: /* [] */0
|
||||
}
|
||||
}, specialAbilityPairs);
|
||||
var equalTypeStylesActive = EntryGroups$OptolithClient.SpecialAbility.countActiveFromGroup(Curry._1(Id$OptolithClient.SpecialAbility.Group.fromInt, specialAbility.gr), specialAbilityPairs);
|
||||
if (totalActive$1 < 3) {
|
||||
var totalActive = armedCombatStylesCount + unarmedCombatStylesCount | 0;
|
||||
if (totalActive < 3) {
|
||||
return true;
|
||||
} else {
|
||||
return equalTypeStylesActive < 2;
|
||||
@@ -91,7 +93,7 @@ function isSpecialAbilitySpecificAdditionEnabled(rules, maybePact, param, specia
|
||||
if (typeof match === "number") {
|
||||
if (match >= 21) {
|
||||
if (match === 47) {
|
||||
return !EntryGroups$OptolithClient.SpecialAbility.hasActiveFromGroup(/* Paktgeschenke */29, specialAbilityPairs);
|
||||
return activePactGiftsCount === 0;
|
||||
}
|
||||
if (match === 84) {
|
||||
if (Ley_List$OptolithClient.Foldable.length(matchingLanguagesScripts.languagesWithMatchingScripts) >= 1) {
|
||||
@@ -103,16 +105,10 @@ function isSpecialAbilitySpecificAdditionEnabled(rules, maybePact, param, specia
|
||||
exit$1 = 3;
|
||||
} else {
|
||||
if (match === 15) {
|
||||
return !EntryGroups$OptolithClient.SpecialAbility.hasActiveFromGroups({
|
||||
hd: /* CombatStylesArmed */8,
|
||||
tl: {
|
||||
hd: /* CombatStylesUnarmed */9,
|
||||
tl: /* [] */0
|
||||
}
|
||||
}, specialAbilityPairs);
|
||||
return (armedCombatStylesCount + unarmedCombatStylesCount | 0) > 0;
|
||||
}
|
||||
if (match >= 20) {
|
||||
return !EntryGroups$OptolithClient.SpecialAbility.hasActiveFromGroup(/* MagicalStyles */12, specialAbilityPairs);
|
||||
return magicalStylesCount > 0;
|
||||
}
|
||||
exit$1 = 3;
|
||||
}
|
||||
@@ -154,17 +150,6 @@ function isSpecialAbilitySpecificAdditionEnabled(rules, maybePact, param, specia
|
||||
}
|
||||
}
|
||||
|
||||
function getFlatFirstPrerequisites(staticAdvantage) {
|
||||
switch (staticAdvantage.TAG | 0) {
|
||||
case /* Advantage */0 :
|
||||
case /* Disadvantage */1 :
|
||||
return Prerequisites$OptolithClient.Flatten.getFirstDisAdvLevelPrerequisites(staticAdvantage._0.prerequisites);
|
||||
case /* SpecialAbility */2 :
|
||||
return Prerequisites$OptolithClient.Flatten.getFirstLevelPrerequisites(staticAdvantage._0.prerequisites);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function isEntrySpecificAdditionEnabled(cache, staticData, hero, staticEntry) {
|
||||
var tmp;
|
||||
switch (staticEntry.TAG | 0) {
|
||||
@@ -178,7 +163,7 @@ function isEntrySpecificAdditionEnabled(cache, staticData, hero, staticEntry) {
|
||||
|
||||
}
|
||||
if (tmp) {
|
||||
return Prerequisites$OptolithClient.Validation.arePrerequisitesMet(staticData, hero, Id$OptolithClient.Activatable.generalize(Activatable_Accessors$OptolithClient.id(staticEntry)), getFlatFirstPrerequisites(staticEntry));
|
||||
return Prerequisites$OptolithClient.Validation.arePrerequisitesMet(staticData, hero, Id$OptolithClient.Activatable.generalize(Activatable_Accessors$OptolithClient.id(staticEntry)), Prerequisites$OptolithClient.Activatable.getFlatFirstPrerequisites(staticEntry));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -198,12 +183,11 @@ function hasNoGenerallyRestrictingDependency(param) {
|
||||
}
|
||||
}
|
||||
|
||||
function hasNotReachedMaximumEntries(staticEntry, maybeHeroEntry) {
|
||||
var match = Activatable_Accessors$OptolithClient.max(staticEntry);
|
||||
if (match !== undefined) {
|
||||
if (match !== 0) {
|
||||
function hasNotReachedMaximumEntries(maxLevel, maybeHeroEntry) {
|
||||
if (maxLevel !== undefined) {
|
||||
if (maxLevel !== 0) {
|
||||
if (maybeHeroEntry !== undefined) {
|
||||
return match > Ley_List$OptolithClient.Foldable.length(maybeHeroEntry.active);
|
||||
return maxLevel > Ley_List$OptolithClient.Foldable.length(maybeHeroEntry.active);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -243,8 +227,8 @@ function isValidExtendedSpecialAbility(param, staticEntry) {
|
||||
}
|
||||
}
|
||||
|
||||
function isAdditionValid(cache, staticData, hero, staticEntry, maybeHeroEntry) {
|
||||
if (isEntrySpecificAdditionEnabled(cache, staticData, hero, staticEntry) && hasNoGenerallyRestrictingDependency(maybeHeroEntry) && hasNotReachedMaximumEntries(staticEntry, maybeHeroEntry) && isValidExtendedSpecialAbility(cache, staticEntry)) {
|
||||
function isAdditionValid(cache, staticData, hero, maxLevel, staticEntry, maybeHeroEntry) {
|
||||
if (isEntrySpecificAdditionEnabled(cache, staticData, hero, staticEntry) && hasNoGenerallyRestrictingDependency(maybeHeroEntry) && hasNotReachedMaximumEntries(maxLevel, maybeHeroEntry) && isValidExtendedSpecialAbility(cache, staticEntry)) {
|
||||
switch (staticEntry.TAG | 0) {
|
||||
case /* Advantage */0 :
|
||||
case /* Disadvantage */1 :
|
||||
@@ -263,9 +247,28 @@ function isAdditionValid(cache, staticData, hero, staticEntry, maybeHeroEntry) {
|
||||
}
|
||||
}
|
||||
|
||||
function getMaxLevel(staticData, hero, staticEntry, maybeHeroEntry) {
|
||||
var computedMax = Dependencies$OptolithClient.getMaxLevel(staticData, hero, Id$OptolithClient.Activatable.generalize(Activatable_Accessors$OptolithClient.id(staticEntry)), Ley_Option$OptolithClient.option(/* [] */0, (function (param) {
|
||||
return param.dependencies;
|
||||
}), maybeHeroEntry), Prerequisites$OptolithClient.Activatable.getLevelPrerequisites(staticEntry));
|
||||
var match = Activatable_Accessors$OptolithClient.max(staticEntry);
|
||||
if (computedMax !== undefined) {
|
||||
if (match !== undefined) {
|
||||
return Ley_Int$OptolithClient.min(computedMax, match);
|
||||
} else {
|
||||
return computedMax;
|
||||
}
|
||||
} else if (match !== undefined) {
|
||||
return match;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
getActivePactGiftsCount ,
|
||||
isAdditionValid ,
|
||||
getMaxLevel ,
|
||||
|
||||
}
|
||||
/* Ley_IntMap-OptolithClient Not a pure module */
|
||||
|
||||
@@ -1,26 +1,10 @@
|
||||
module F = Ley_Function;
|
||||
module I = Ley_Int;
|
||||
module IM = Ley_IntMap;
|
||||
module L = Ley_List;
|
||||
module O = Ley_Option;
|
||||
|
||||
type matchingLanguagesScripts = {
|
||||
// `true` if an entry that requires to have matching languages and scripts
|
||||
// is active
|
||||
isEntryActiveRequiringMatch: bool,
|
||||
languagesWithMatchingScripts: list(int),
|
||||
scriptsWithMatchingLanguages: list(int),
|
||||
};
|
||||
|
||||
type inactiveValidationCache = {
|
||||
specialAbilityPairs:
|
||||
Ley_IntMap.t((SpecialAbility.t, option(Hero.Activatable.t))),
|
||||
combatStyleCombination: option(Hero.Activatable.t),
|
||||
magicalStyleCombination: option(Hero.Activatable.t),
|
||||
dunklesAbbild: option(Hero.Activatable.t),
|
||||
activePactGiftsCount: int,
|
||||
matchingLanguagesScripts,
|
||||
validExtendedSpecialAbilities: list(int),
|
||||
requiredApplyToMagicalActions: bool,
|
||||
};
|
||||
open Activatable_Inactive_Cache;
|
||||
|
||||
let getActivePactGiftsCount = specialAbilityPairs =>
|
||||
specialAbilityPairs
|
||||
@@ -64,9 +48,13 @@ let isSpecialAbilitySpecificAdditionEnabled =
|
||||
~rules: Hero.Rules.t,
|
||||
~maybePact,
|
||||
{
|
||||
specialAbilityPairs,
|
||||
combatStyleCombination,
|
||||
armedCombatStylesCount,
|
||||
unarmedCombatStylesCount,
|
||||
magicalStyleCombination,
|
||||
magicalStylesCount,
|
||||
isBlessedStyleActive,
|
||||
isSkillStyleActive,
|
||||
dunklesAbbild,
|
||||
activePactGiftsCount,
|
||||
matchingLanguagesScripts,
|
||||
@@ -77,69 +65,39 @@ let isSpecialAbilitySpecificAdditionEnabled =
|
||||
[@warning "-4"]
|
||||
Id.SpecialAbility.(
|
||||
switch (fromInt(specialAbility.id), Group.fromInt(specialAbility.gr)) {
|
||||
| (_, CombatStylesArmed | CombatStylesUnarmed) =>
|
||||
| (_, CombatStylesArmed as gr | CombatStylesUnarmed as gr) =>
|
||||
let equalTypeStylesActive =
|
||||
switch (gr) {
|
||||
| CombatStylesArmed => armedCombatStylesCount
|
||||
| CombatStylesUnarmed => unarmedCombatStylesCount
|
||||
| _ => 0
|
||||
};
|
||||
|
||||
// Combination-SA is active, which allows 3 styles to be active, but only a
|
||||
// maximum of 2 from one type (armed/unarmed).
|
||||
if (Activatable_Accessors.isActiveM(combatStyleCombination)) {
|
||||
let totalActive =
|
||||
EntryGroups.SpecialAbility.countActiveFromGroups(
|
||||
[CombatStylesArmed, CombatStylesUnarmed],
|
||||
specialAbilityPairs,
|
||||
);
|
||||
|
||||
let equalTypeStylesActive =
|
||||
EntryGroups.SpecialAbility.countActiveFromGroup(
|
||||
Id.SpecialAbility.Group.fromInt(specialAbility.gr),
|
||||
specialAbilityPairs,
|
||||
);
|
||||
let totalActive = armedCombatStylesCount + unarmedCombatStylesCount;
|
||||
|
||||
totalActive < 3 || equalTypeStylesActive < 2;
|
||||
} else {
|
||||
!
|
||||
EntryGroups.SpecialAbility.hasActiveFromGroup(
|
||||
Id.SpecialAbility.Group.fromInt(specialAbility.gr),
|
||||
specialAbilityPairs,
|
||||
);
|
||||
// Otherwise, only one of each type can be active.
|
||||
}
|
||||
// Otherwise, only one of each type can be active.
|
||||
equalTypeStylesActive === 0;
|
||||
};
|
||||
|
||||
| (_, MagicalStyles) =>
|
||||
let totalActive =
|
||||
EntryGroups.SpecialAbility.countActiveFromGroup(
|
||||
MagicalStyles,
|
||||
specialAbilityPairs,
|
||||
);
|
||||
magicalStylesCount
|
||||
< (Activatable_Accessors.isActiveM(magicalStyleCombination) ? 2 : 1)
|
||||
|
||||
totalActive
|
||||
< (Activatable_Accessors.isActiveM(magicalStyleCombination) ? 2 : 1);
|
||||
| (_, BlessedStyles) => !isBlessedStyleActive
|
||||
|
||||
| (_, BlessedStyles as group | SkillStyles as group) =>
|
||||
!
|
||||
EntryGroups.SpecialAbility.hasActiveFromGroup(
|
||||
group,
|
||||
specialAbilityPairs,
|
||||
)
|
||||
| (_, SkillStyles) => !isSkillStyleActive
|
||||
|
||||
| (CombatStyleCombination, _) =>
|
||||
!
|
||||
EntryGroups.SpecialAbility.hasActiveFromGroups(
|
||||
[CombatStylesArmed, CombatStylesUnarmed],
|
||||
specialAbilityPairs,
|
||||
)
|
||||
armedCombatStylesCount + unarmedCombatStylesCount > 0
|
||||
|
||||
| (MagicStyleCombination, _) =>
|
||||
!
|
||||
EntryGroups.SpecialAbility.hasActiveFromGroup(
|
||||
MagicalStyles,
|
||||
specialAbilityPairs,
|
||||
)
|
||||
| (MagicStyleCombination, _) => magicalStylesCount > 0
|
||||
|
||||
| (DunklesAbbildDerBuendnisgabe, _) =>
|
||||
!
|
||||
EntryGroups.SpecialAbility.hasActiveFromGroup(
|
||||
Paktgeschenke,
|
||||
specialAbilityPairs,
|
||||
)
|
||||
| (DunklesAbbildDerBuendnisgabe, _) => activePactGiftsCount === 0
|
||||
|
||||
| (WegDerSchreiberin, _) =>
|
||||
L.Foldable.length(matchingLanguagesScripts.languagesWithMatchingScripts)
|
||||
@@ -183,21 +141,6 @@ let isSpecialAbilitySpecificAdditionEnabled =
|
||||
}
|
||||
);
|
||||
|
||||
let getFlatFirstPrerequisites =
|
||||
fun
|
||||
| Static.Advantage(staticAdvantage) =>
|
||||
Prerequisites.Flatten.getFirstDisAdvLevelPrerequisites(
|
||||
staticAdvantage.prerequisites,
|
||||
)
|
||||
| Disadvantage(staticDisadvantage) =>
|
||||
Prerequisites.Flatten.getFirstDisAdvLevelPrerequisites(
|
||||
staticDisadvantage.prerequisites,
|
||||
)
|
||||
| SpecialAbility(staticSpecialAbility) =>
|
||||
Prerequisites.Flatten.getFirstLevelPrerequisites(
|
||||
staticSpecialAbility.prerequisites,
|
||||
);
|
||||
|
||||
let isEntrySpecificAdditionEnabled =
|
||||
(cache, staticData, hero: Hero.t, staticEntry) =>
|
||||
(
|
||||
@@ -217,7 +160,7 @@ let isEntrySpecificAdditionEnabled =
|
||||
staticData,
|
||||
hero,
|
||||
Id.Activatable.generalize(Activatable_Accessors.id(staticEntry)),
|
||||
getFlatFirstPrerequisites(staticEntry),
|
||||
Prerequisites.Activatable.getFlatFirstPrerequisites(staticEntry),
|
||||
);
|
||||
|
||||
let hasNoGenerallyRestrictingDependency =
|
||||
@@ -241,8 +184,8 @@ let hasNoGenerallyRestrictingDependency =
|
||||
)
|
||||
| _ => true;
|
||||
|
||||
let hasNotReachedMaximumEntries = (staticEntry, maybeHeroEntry) =>
|
||||
switch (Activatable_Accessors.max(staticEntry), maybeHeroEntry) {
|
||||
let hasNotReachedMaximumEntries = (maxLevel, maybeHeroEntry) =>
|
||||
switch (maxLevel, maybeHeroEntry) {
|
||||
// Impossible maximum level, thus no addition possible
|
||||
| (Some(0), _) => false
|
||||
| (Some(max), Some(({active, _}: Hero.Activatable.t))) =>
|
||||
@@ -282,9 +225,33 @@ let appliesToMagicalActionsIfRequired =
|
||||
| SpecialAbility(_) => true
|
||||
};
|
||||
|
||||
let isAdditionValid = (cache, staticData, hero, staticEntry, maybeHeroEntry) =>
|
||||
let isAdditionValid =
|
||||
(cache, staticData, hero, maxLevel, staticEntry, maybeHeroEntry) =>
|
||||
isEntrySpecificAdditionEnabled(cache, staticData, hero, staticEntry)
|
||||
&& hasNoGenerallyRestrictingDependency(maybeHeroEntry)
|
||||
&& hasNotReachedMaximumEntries(staticEntry, maybeHeroEntry)
|
||||
&& hasNotReachedMaximumEntries(maxLevel, maybeHeroEntry)
|
||||
&& isValidExtendedSpecialAbility(cache, staticEntry)
|
||||
&& appliesToMagicalActionsIfRequired(cache, staticEntry);
|
||||
|
||||
let getMaxLevel = (staticData, hero, staticEntry, maybeHeroEntry) =>
|
||||
staticEntry
|
||||
|> Prerequisites.Activatable.getLevelPrerequisites
|
||||
|> Dependencies.getMaxLevel(
|
||||
staticData,
|
||||
hero,
|
||||
Id.Activatable.generalize(Activatable_Accessors.id(staticEntry)),
|
||||
O.option(
|
||||
[],
|
||||
({Hero.Activatable.dependencies, _}) => dependencies,
|
||||
maybeHeroEntry,
|
||||
),
|
||||
)
|
||||
|> (
|
||||
computedMax =>
|
||||
switch (computedMax, Activatable_Accessors.max(staticEntry)) {
|
||||
| (Some(max1), Some(max2)) => Some(I.min(max1, max2))
|
||||
| (Some(max), None)
|
||||
| (None, Some(max)) => Some(max)
|
||||
| (None, None) => None
|
||||
}
|
||||
);
|
||||
|
||||
@@ -5,30 +5,6 @@
|
||||
* to be bought/added.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A set of values to validate `Weg der Schreiberin`.
|
||||
*/
|
||||
type matchingLanguagesScripts = {
|
||||
isEntryActiveRequiringMatch: bool,
|
||||
languagesWithMatchingScripts: list(int),
|
||||
scriptsWithMatchingLanguages: list(int),
|
||||
};
|
||||
|
||||
/**
|
||||
* The cache of computed values to optimize performance of `isAdditionValid`.
|
||||
*/
|
||||
type inactiveValidationCache = {
|
||||
specialAbilityPairs:
|
||||
Ley_IntMap.t((SpecialAbility.t, option(Hero.Activatable.t))),
|
||||
combatStyleCombination: option(Hero.Activatable.t),
|
||||
magicalStyleCombination: option(Hero.Activatable.t),
|
||||
dunklesAbbild: option(Hero.Activatable.t),
|
||||
activePactGiftsCount: int,
|
||||
matchingLanguagesScripts,
|
||||
validExtendedSpecialAbilities: list(int),
|
||||
requiredApplyToMagicalActions: bool,
|
||||
};
|
||||
|
||||
/**
|
||||
* `getActivePactGiftsCount pairs` returns the amount of active pact gifts based
|
||||
* on the given set of static/hero special ability entry pairs.
|
||||
@@ -37,17 +13,29 @@ let getActivePactGiftsCount:
|
||||
Ley_IntMap.t((SpecialAbility.t, option(Hero.Activatable.t))) => int;
|
||||
|
||||
/**
|
||||
* `isAdditionValid cache staticData hero staticEntry maybeHeroEntry` checks
|
||||
* whether an activatable entry can be added/bought. The `cache` contains
|
||||
* computed values that are used for multiple entries so they can be reused and
|
||||
* thus improve performance for long lists of entries.
|
||||
* `isAdditionValid cache staticData hero maybeMaxLevel staticEntry
|
||||
* maybeHeroEntry` checks whether an activatable entry can be added/bought. The
|
||||
* `cache` contains computed values that are used for multiple entries so they
|
||||
* can be reused and thus improve performance for long lists of entries.
|
||||
*/
|
||||
let isAdditionValid:
|
||||
(
|
||||
inactiveValidationCache,
|
||||
Activatable_Inactive_Cache.t,
|
||||
Static.t,
|
||||
Hero.t,
|
||||
option(int),
|
||||
Static.activatable,
|
||||
option(Hero.Activatable.t)
|
||||
) =>
|
||||
bool;
|
||||
|
||||
/**
|
||||
* `getMaxLevel staticData staticEntry maybeHeroEntry` returns the maximum level based on the level prerequisites (excluding first level prerequisites) where the key is the level and the value the prerequisites that need to be met for the respective level as well as based on the registered `dependencies` of the entry.
|
||||
*
|
||||
* The return value is based on prerequisites *and* entry dependencies. To get
|
||||
* the max level only based on prerequisites, use
|
||||
* `Prerequisites.Validation.getMaxLevel`.
|
||||
*/
|
||||
let getMaxLevel:
|
||||
(Static.t, Hero.t, Static.activatable, option(Hero.Activatable.t)) =>
|
||||
option(int);
|
||||
|
||||
@@ -17,7 +17,7 @@ function $less$amp$great(mx, f) {
|
||||
return $less$$great(f, mx);
|
||||
}
|
||||
|
||||
function $less$star$great(mf, mx) {
|
||||
function $less$star$great(mx, mf) {
|
||||
if (mf !== undefined) {
|
||||
return $less$$great(mf, mx);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ module Functor = {
|
||||
module Applicative = {
|
||||
open Functor;
|
||||
|
||||
let (<*>) = (mf, mx) =>
|
||||
let (<*>) = (mx, mf) =>
|
||||
switch (mf) {
|
||||
| Some(f) => f <$> mx
|
||||
| None => None
|
||||
|
||||
@@ -13,7 +13,7 @@ module Applicative: {
|
||||
/**
|
||||
* Apply a wrapped function to a wrapped value.
|
||||
*/
|
||||
let (<*>): (t('a => 'b), t('a)) => t('b);
|
||||
let (<*>): (t('a), t('a => 'b)) => t('b);
|
||||
};
|
||||
|
||||
module Alternative: {
|
||||
|
||||
@@ -5,12 +5,14 @@ import * as Caml_obj from "bs-platform/lib/es6/caml_obj.js";
|
||||
import * as Pervasives from "bs-platform/lib/es6/pervasives.js";
|
||||
import * as Id$OptolithClient from "../Misc/Id.bs.js";
|
||||
import * as Hero$OptolithClient from "../Misc/Hero.bs.js";
|
||||
import * as Ley_Int$OptolithClient from "../Data/Ley_Int.bs.js";
|
||||
import * as Ley_Bool$OptolithClient from "../Data/Ley_Bool.bs.js";
|
||||
import * as Ley_List$OptolithClient from "../Data/Ley_List.bs.js";
|
||||
import * as Tradition$OptolithClient from "../Misc/Tradition.bs.js";
|
||||
import * as Ley_IntMap$OptolithClient from "../Data/Ley_IntMap.bs.js";
|
||||
import * as Ley_Option$OptolithClient from "../Data/Ley_Option.bs.js";
|
||||
import * as Ley_Function$OptolithClient from "../Data/Ley_Function.bs.js";
|
||||
import * as Prerequisites$OptolithClient from "./Prerequisites.bs.js";
|
||||
import * as Activatable_Convert$OptolithClient from "../Activatable/Activatable_Convert.bs.js";
|
||||
|
||||
function flattenSkillDependencies(getValueForTargetId, id, dependencies) {
|
||||
@@ -990,6 +992,27 @@ function removeDependencies(param, param$1, param$2, param$3) {
|
||||
return modifyDependencies(/* Remove */1, param, param$1, param$2, param$3);
|
||||
}
|
||||
|
||||
function getMaxLevel(staticData, hero, sourceId, dependencies, prerequisites) {
|
||||
return Ley_Function$OptolithClient.flip((function (param, param$1) {
|
||||
return Ley_List$OptolithClient.Foldable.foldl((function (prevMax, param) {
|
||||
var level = param.level;
|
||||
if (param.active) {
|
||||
return prevMax;
|
||||
} else if (prevMax !== undefined) {
|
||||
if (level !== undefined) {
|
||||
return Ley_Int$OptolithClient.min(prevMax, level - 1 | 0);
|
||||
} else {
|
||||
return prevMax;
|
||||
}
|
||||
} else if (level !== undefined) {
|
||||
return level - 1 | 0;
|
||||
} else {
|
||||
return ;
|
||||
}
|
||||
}), param, param$1);
|
||||
}), dependencies, Prerequisites$OptolithClient.Validation.getMaxLevel(staticData, hero, sourceId, prerequisites));
|
||||
}
|
||||
|
||||
var TransferredUnfamiliar = {
|
||||
isUnfamiliarSpell: isUnfamiliarSpell,
|
||||
addTransferUnfamiliarDependencies: addTransferUnfamiliarDependencies,
|
||||
@@ -1001,6 +1024,7 @@ export {
|
||||
TransferredUnfamiliar ,
|
||||
addDependencies ,
|
||||
removeDependencies ,
|
||||
getMaxLevel ,
|
||||
|
||||
}
|
||||
/* Tradition-OptolithClient Not a pure module */
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
module F = Ley_Function;
|
||||
module I = Ley_Int;
|
||||
module L = Ley_List;
|
||||
module O = Ley_Option;
|
||||
open O.Monad;
|
||||
@@ -1142,3 +1144,35 @@ let addDependencies = modifyDependencies(Add);
|
||||
* Removes dependencies from all required entries to ensure rule validity.
|
||||
*/
|
||||
let removeDependencies = modifyDependencies(Remove);
|
||||
|
||||
/**
|
||||
* Return the max level based on prerequisites and dependencies.
|
||||
*/
|
||||
let getMaxLevel = (staticData, hero, sourceId, dependencies, prerequisites) =>
|
||||
Prerequisites.Validation.getMaxLevel(
|
||||
staticData,
|
||||
hero,
|
||||
sourceId,
|
||||
prerequisites,
|
||||
)
|
||||
|> F.flip(
|
||||
L.Foldable.foldl((prevMax, {Hero.Activatable.active, level, _}) =>
|
||||
switch (active, prevMax, level) {
|
||||
// active must be always false because it needs to *prohibit* a certain
|
||||
// level
|
||||
//
|
||||
// also, if there is both a previous max and an prohibited level in the
|
||||
// dependency, take the minimum value
|
||||
//
|
||||
// the prohibited level is reduced by 1 since this level should not be
|
||||
// reached, thus the maximum level must be lower
|
||||
| (false, Some(prev), Some(notAllowed)) =>
|
||||
Some(I.min(prev, notAllowed - 1))
|
||||
| (false, Some(prev), None) => Some(prev)
|
||||
| (false, None, Some(notAllowed)) => Some(notAllowed - 1)
|
||||
| (false, None, None) => None
|
||||
| (true, _, _) => prevMax
|
||||
}
|
||||
),
|
||||
dependencies,
|
||||
);
|
||||
|
||||
@@ -97,3 +97,24 @@ let removeDependencies:
|
||||
Hero.t
|
||||
) =>
|
||||
Hero.t;
|
||||
|
||||
/**
|
||||
* `getMaxLevel staticData hero sourceId dependencies levelPrerequisites`
|
||||
* returns the maximum level based on the map of prerequisites
|
||||
* `levelPrerequisites` where the key is the level and the value the
|
||||
* prerequisites that need to be met for the respective level as well as based
|
||||
* on the registered `dependencies` of the entry.
|
||||
*
|
||||
* The return value is based on prerequisites *and* entry dependencies. To get
|
||||
* the max level only based on prerequisites, use
|
||||
* `Prerequisites.Validation.getMaxLevel`.
|
||||
*/
|
||||
let getMaxLevel:
|
||||
(
|
||||
Static.t,
|
||||
Hero.t,
|
||||
Id.t,
|
||||
list(Hero.Activatable.dependency),
|
||||
Ley_IntMap.t(Prerequisite.t)
|
||||
) =>
|
||||
option(int);
|
||||
|
||||
@@ -912,6 +912,46 @@ function arePrerequisitesMet(staticData, hero, sourceId, prerequisites) {
|
||||
}), prerequisites);
|
||||
}
|
||||
|
||||
function getMaxLevel(staticData, hero, sourceId, prerequisites) {
|
||||
return Curry._3(Ley_IntMap$OptolithClient.foldlWithKey, (function (max, level, prerequisites) {
|
||||
if (max !== undefined && max <= level) {
|
||||
return max;
|
||||
}
|
||||
if (arePrerequisitesMet(staticData, hero, sourceId, flattenPrerequisites(prerequisites, /* [] */0))) {
|
||||
return max;
|
||||
} else {
|
||||
return level;
|
||||
}
|
||||
}), undefined, prerequisites);
|
||||
}
|
||||
|
||||
function getFlatFirstPrerequisites(staticAdvantage) {
|
||||
switch (staticAdvantage.TAG | 0) {
|
||||
case /* Advantage */0 :
|
||||
case /* Disadvantage */1 :
|
||||
return getFirstDisAdvLevelPrerequisites(staticAdvantage._0.prerequisites);
|
||||
case /* SpecialAbility */2 :
|
||||
return getFirstLevelPrerequisites(staticAdvantage._0.prerequisites);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function getLevelPrerequisites(staticAdvantage) {
|
||||
switch (staticAdvantage.TAG | 0) {
|
||||
case /* Advantage */0 :
|
||||
case /* Disadvantage */1 :
|
||||
return staticAdvantage._0.prerequisites.levels;
|
||||
case /* SpecialAbility */2 :
|
||||
return staticAdvantage._0.prerequisites.levels;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var Activatable = {
|
||||
getFlatFirstPrerequisites: getFlatFirstPrerequisites,
|
||||
getLevelPrerequisites: getLevelPrerequisites
|
||||
};
|
||||
|
||||
var Flatten = {
|
||||
flattenPrerequisites: flattenPrerequisites,
|
||||
getFirstLevelPrerequisites: getFirstLevelPrerequisites,
|
||||
@@ -925,13 +965,15 @@ var Dynamic = {
|
||||
|
||||
var Validation = {
|
||||
isPrerequisiteMet: isPrerequisiteMet,
|
||||
arePrerequisitesMet: arePrerequisitesMet
|
||||
arePrerequisitesMet: arePrerequisitesMet,
|
||||
getMaxLevel: getMaxLevel
|
||||
};
|
||||
|
||||
export {
|
||||
Flatten ,
|
||||
Dynamic ,
|
||||
Validation ,
|
||||
Activatable ,
|
||||
|
||||
}
|
||||
/* Tradition-OptolithClient Not a pure module */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
open Prerequisite;
|
||||
|
||||
module IM = Ley_IntMap;
|
||||
module O = Ley_Option;
|
||||
|
||||
type prerequisite =
|
||||
@@ -769,6 +770,20 @@ module Validation = {
|
||||
isPrerequisiteMet(staticData, hero, sourceId),
|
||||
prerequisites,
|
||||
);
|
||||
|
||||
let getMaxLevel = (staticData, hero, sourceId, prerequisites) =>
|
||||
IM.foldlWithKey(
|
||||
(max, level, prerequisites) =>
|
||||
switch (max) {
|
||||
| Some(max) when max <= level => Some(max)
|
||||
| max =>
|
||||
Flatten.flattenPrerequisites(prerequisites, [])
|
||||
|> arePrerequisitesMet(staticData, hero, sourceId)
|
||||
? max : Some(level)
|
||||
},
|
||||
None,
|
||||
prerequisites,
|
||||
);
|
||||
};
|
||||
|
||||
//
|
||||
@@ -786,84 +801,6 @@ module Validation = {
|
||||
// ? set (ri_id) (id) (req)
|
||||
// : req
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * Returns if the current index can be skipped because there is already a lower
|
||||
// * level which prerequisites are not met.
|
||||
// *
|
||||
// * This is for performance reasons to not check the prerequisites of higher levels.
|
||||
// */
|
||||
// const skipLevelCheck =
|
||||
// (current_req: Pair<number, List<AllRequirements>>) =>
|
||||
// (mmax: Maybe<number>) =>
|
||||
// isJust (mmax) && pipe_ (current_req, fst, gt (fromJust (mmax)))
|
||||
//
|
||||
// /**
|
||||
// * Get maximum valid level.
|
||||
// * @param state The current hero data.
|
||||
// * @param requirements A Map of tier prereqisite arrays.
|
||||
// * @param sourceId The id of the entry the requirement objects belong to.
|
||||
// */
|
||||
// export const validateLevel =
|
||||
// (wiki: StaticDataRecord) =>
|
||||
// (state: HeroModelRecord) =>
|
||||
// (requirements: OrderedMap<number, List<AllRequirements>>) =>
|
||||
// (dependencies: List<ActivatableDependency>) =>
|
||||
// (sourceId: string): Maybe<number> =>
|
||||
// pipe_ (
|
||||
// requirements,
|
||||
// toList,
|
||||
// sortBy (on (compare) (fst)),
|
||||
//
|
||||
// // first check the prerequisites:
|
||||
// foldl ((max: Maybe<number>) => (entry: Pair<number, List<AllRequirements>>) =>
|
||||
//
|
||||
// // if `max` is lower than the current level (from `entry`), just
|
||||
// // skip the prerequisite validation
|
||||
// !skipLevelCheck (entry) (max)
|
||||
//
|
||||
// // otherwise, validate them
|
||||
// && !validatePrerequisites (wiki) (state) (snd (entry)) (sourceId)
|
||||
//
|
||||
// // if *not* valid, set the max to be lower than the actual
|
||||
// // current level (because it must not be reached)
|
||||
// ? Just (fst (entry) - 1)
|
||||
//
|
||||
// // otherwise, just pass the previous max value
|
||||
// : max)
|
||||
// (Nothing),
|
||||
//
|
||||
// // then, check the dependencies
|
||||
// flip (foldl ((max: Maybe<number>) => (dep: ActivatableDependency) =>
|
||||
//
|
||||
// // If `dep` prohibits higher level:
|
||||
// // - it can only be contained in a record
|
||||
// Record.isRecord (dep)
|
||||
//
|
||||
// // - and it must be *prohibited*, so `active` must be `false`
|
||||
// && Maybe.elem (false) (DOA.active (dep))
|
||||
// ? pipe_ (
|
||||
// dep,
|
||||
//
|
||||
// // get the current prohibited level
|
||||
// DOA.tier,
|
||||
//
|
||||
// // - if its a Nothing, do nothing
|
||||
// maybe (max)
|
||||
//
|
||||
// // - otherwise decrease the level by one (the
|
||||
// // actual level must not be reached) and then
|
||||
// // take the lower one, if both the current and
|
||||
// // the previous are Justs, otherwise the
|
||||
// // current.
|
||||
// (pipe (dec, level => Just (maybe (level) (min (level)) (max))))
|
||||
// )
|
||||
//
|
||||
// // otherwise, dont do anything
|
||||
// : max))
|
||||
// (dependencies)
|
||||
// )
|
||||
//
|
||||
// /**
|
||||
// * Checks if all profession prerequisites are fulfilled.
|
||||
// * @param prerequisites An array of prerequisite objects.
|
||||
@@ -882,3 +819,25 @@ module Validation = {
|
||||
// ? isCultureValid (current_culture_id) (req)
|
||||
// : false)
|
||||
// (prerequisites)
|
||||
|
||||
module Activatable = {
|
||||
let getFlatFirstPrerequisites =
|
||||
fun
|
||||
| Static.Advantage(staticAdvantage) =>
|
||||
Flatten.getFirstDisAdvLevelPrerequisites(staticAdvantage.prerequisites)
|
||||
| Disadvantage(staticDisadvantage) =>
|
||||
Flatten.getFirstDisAdvLevelPrerequisites(
|
||||
staticDisadvantage.prerequisites,
|
||||
)
|
||||
| SpecialAbility(staticSpecialAbility) =>
|
||||
Flatten.getFirstLevelPrerequisites(staticSpecialAbility.prerequisites);
|
||||
|
||||
let getLevelPrerequisites =
|
||||
fun
|
||||
| Static.Advantage(staticAdvantage) =>
|
||||
staticAdvantage.prerequisites.levels
|
||||
| Disadvantage(staticDisadvantage) =>
|
||||
staticDisadvantage.prerequisites.levels
|
||||
| SpecialAbility(staticSpecialAbility) =>
|
||||
staticSpecialAbility.prerequisites.levels;
|
||||
};
|
||||
|
||||
@@ -80,4 +80,24 @@ module Validation: {
|
||||
*/
|
||||
let arePrerequisitesMet:
|
||||
(Static.t, Hero.t, Id.t, list(prerequisite)) => bool;
|
||||
|
||||
/**
|
||||
* `getMaxLevel staticData hero sourceId levelPrerequisites` returns the
|
||||
* maximum level based on the map of prerequisites `levelPrerequisites` where
|
||||
* the key is the level and the value the prerequisites that need to be met
|
||||
* for the respective level.
|
||||
*
|
||||
* The return value is purely based on prerequisites, entry dependencies are
|
||||
* not taken into account. To get the max level based on prerequisites *and*
|
||||
* dependencies, use `Dependencies.getMaxLevel`.
|
||||
*/
|
||||
let getMaxLevel:
|
||||
(Static.t, Hero.t, Id.t, Ley_IntMap.t(Prerequisite.t)) => option(int);
|
||||
};
|
||||
|
||||
module Activatable: {
|
||||
let getFlatFirstPrerequisites: Static.activatable => list(prerequisite);
|
||||
|
||||
let getLevelPrerequisites:
|
||||
Static.activatable => Ley_IntMap.t(Prerequisite.t);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user