Skip to content

Commit

Permalink
fix: primary attribute prerequisites may not have been added as depen…
Browse files Browse the repository at this point in the history
…dencies

The previous implementation relied on the tradition being added to the hero
object before the entry having the prerequisite was added, since the dependency
has been added statically, depending on the then-known traditions. But there are
situations where this is not the case, resulting in no prerequisite being added.
The new implementation does not bind the dependencies to a specific attribute,
but instead dynamically infers which is the primary attribute to then apply the
registered primary dependencies. This makes the dependencies independent of
the presence of tradition entries in the initialization phase.

Fixes #1260
  • Loading branch information
elyukai committed Feb 1, 2022
1 parent 8b5eede commit ac0cdc3
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 27 deletions.
8 changes: 8 additions & 0 deletions src/App/Models/Hero/HeroModel.ts
Expand Up @@ -72,6 +72,10 @@ export interface HeroModel {
skillStyleDependencies: List<Record<StyleDependency>>
socialStatusDependencies: List<SocialStatusId>
transferredUnfamiliarSpells: List<Record<TransferUnfamiliar>>
blessedPrimaryAttributeDependencies:
readonly Readonly<{ sourceIdentifier: string; minValue: number }>[]
magicalPrimaryAttributeDependencies:
readonly Readonly<{ sourceIdentifier: string; minValue: number }>[]
skillCheckAttributeCache: SkillCheckAttributeCache
}

Expand Down Expand Up @@ -127,6 +131,8 @@ export const HeroModel: RecordCreator<HeroModel> =
skillStyleDependencies: List (),
socialStatusDependencies: List (),
transferredUnfamiliarSpells: List (),
blessedPrimaryAttributeDependencies: [],
magicalPrimaryAttributeDependencies: [],
skillCheckAttributeCache: OrderedMap.empty,
})

Expand Down Expand Up @@ -186,5 +192,7 @@ export const getInitialHeroObject =
skillStyleDependencies: Nothing,
socialStatusDependencies: Nothing,
transferredUnfamiliarSpells: Nothing,
blessedPrimaryAttributeDependencies: [],
magicalPrimaryAttributeDependencies: [],
skillCheckAttributeCache: Nothing,
})
31 changes: 20 additions & 11 deletions src/App/Selectors/attributeSelectors.ts
Expand Up @@ -116,19 +116,27 @@ const getAttributeMinimum =
(added: Tuple<[number, number, number]>) =>
(mblessed_primary_attr: Maybe<Record<AttributeCombined>>) =>
(mhighest_magical_primary_attr: Maybe<Record<AttributeCombined>>) =>
(hero_entry: Record<AttributeDependent>): number =>
maximum (List<number> (
(hero_entry: Record<AttributeDependent>): number => {
const isConstitution = AtDA.id (hero_entry) === AttrId.Constitution

const isHighestMagicalPrimaryAttribute =
Maybe.elem (AtDA.id (hero_entry)) (fmap (ACA_.id) (mhighest_magical_primary_attr))

const isBlessedPrimaryAttribute =
Maybe.elem (AtDA.id (hero_entry)) (fmap (ACA_.id) (mblessed_primary_attr))

const blessedPrimaryAttributeDependencies = HA.blessedPrimaryAttributeDependencies (hero)

const magicalPrimaryAttributeDependencies = HA.magicalPrimaryAttributeDependencies (hero)

return maximum (List<number> (
...flattenDependencies (wiki) (hero) (AtDA.dependencies (hero_entry)),
...(
AtDA.id (hero_entry) === AttrId.Constitution
? List (sel1 (added))
: List<number> ()
),
...(Maybe.elem (AtDA.id (hero_entry)) (fmap (ACA_.id) (mhighest_magical_primary_attr))
? List (sel2 (added))
...(isConstitution ? List (sel1 (added)) : List<number> ()),
...(isHighestMagicalPrimaryAttribute
? List (sel2 (added), ...magicalPrimaryAttributeDependencies.map (x => x.minValue))
: List<number> ()),
...(Maybe.elem (AtDA.id (hero_entry)) (fmap (ACA_.id) (mblessed_primary_attr))
? List (sel3 (added))
...(isBlessedPrimaryAttribute
? List (sel3 (added), ...blessedPrimaryAttributeDependencies.map (x => x.minValue))
: List<number> ()),
fromMaybe (8)
(getSkillCheckAttributeMinimum (
Expand All @@ -143,6 +151,7 @@ const getAttributeMinimum =
AtDA.id (hero_entry),
))
))
}

const getAddedEnergies = createMaybeSelector (
getHeroProp,
Expand Down
40 changes: 24 additions & 16 deletions src/App/Utilities/Dependencies/dependencyUtils.ts
@@ -1,9 +1,8 @@
import { notEquals } from "../../../Data/Eq"
import { flip, ident, join, thrush } from "../../../Data/Function"
import { fmap } from "../../../Data/Functor"
import { over } from "../../../Data/Lens"
import { consF, foldr, isList, sdelete } from "../../../Data/List"
import { elemF, fromMaybe, isNothing, Just, Nothing } from "../../../Data/Maybe"
import { elemF, isNothing, Just, Nothing } from "../../../Data/Maybe"
import { Record } from "../../../Data/Record"
import { Category } from "../../Constants/Categories"
import { DependencyObject } from "../../Models/ActiveEntries/DependencyObject"
Expand All @@ -12,16 +11,14 @@ import { ActivatableDependency, ExtendedSkillDependency, SkillDependency } from
import { SkillOptionalDependency } from "../../Models/Hero/SkillOptionalDependency"
import { RequireActivatable } from "../../Models/Wiki/prerequisites/ActivatableRequirement"
import { RequireIncreasable } from "../../Models/Wiki/prerequisites/IncreasableRequirement"
import { RequirePrimaryAttribute } from "../../Models/Wiki/prerequisites/PrimaryAttributeRequirement"
import { PrimaryAttributeType, RequirePrimaryAttribute } from "../../Models/Wiki/prerequisites/PrimaryAttributeRequirement"
import { SocialPrerequisite } from "../../Models/Wiki/prerequisites/SocialPrerequisite"
import { AllRequirements } from "../../Models/Wiki/wikiTypeHelpers"
import { getCategoryById } from "../IDUtils"
import { pipe } from "../pipe"
import { getPrimaryAttributeId } from "../primaryAttributeUtils"
import { addActivatableDependency, addActivatableSkillDependency, addAttributeDependency, addSkillDependency } from "./addDependencyUtils"
import { removeActivatableDependency, removeActivatableSkillDependency, removeAttributeDependency, removeSkillDependency } from "./removeDependencyUtils"

const HA = HeroModel.A
const HL = HeroModelL
const RAA = RequireActivatable.A
const RPAA = RequirePrimaryAttribute.A
Expand Down Expand Up @@ -87,15 +84,6 @@ const putActivatableDependency =
(id)
}

const putPrimaryAttributeDependency =
(f: ModifyAttributeDependency) =>
(req: Record<RequirePrimaryAttribute>) =>
(state: HeroModelRecord): HeroModelRecord =>
fromMaybe (state)
(fmap ((x: string) => f (RPAA.value (req)) (x) (state))
(getPrimaryAttributeId (HA.specialAbilities (state))
(RPAA.type (req))))

const getMatchingIncreasableModifier =
(f: ModifyAttributeDependency) =>
(g: ModifySkillDependency) =>
Expand Down Expand Up @@ -154,6 +142,27 @@ const modifySocialDependency: (isToAdd: boolean) =>
isToAdd => x => over (HL.socialStatusDependencies)
((isToAdd ? consF : sdelete) (SocialPrerequisite.A.value (x)))

const modifyPrimaryAttributeDependency = (
isToAdd: boolean,
sourceId: string,
d: Record<RequirePrimaryAttribute>,
state: HeroModelRecord
) =>
over (RPAA.type (d) === PrimaryAttributeType.Blessed
? HL.blessedPrimaryAttributeDependencies
: HL.magicalPrimaryAttributeDependencies)
(isToAdd
? old_ds => [ ...old_ds, { sourceIdentifier: sourceId, minValue: RPAA.value (d) } ]
: old_ds => {
const index = old_ds.findIndex (
({ sourceIdentifier, minValue }) =>
sourceIdentifier === sourceId && minValue === RPAA.value (d)
)

return [ ...old_ds.slice (0, index), ...old_ds.slice (index + 1) ]
})
(state)

const modifyDependencies =
(isToAdd: boolean) =>
(modifyAttributeDependency: ModifyAttributeDependency) =>
Expand All @@ -163,8 +172,7 @@ const modifyDependencies =
(sourceId: string) =>
flip (foldr ((x: AllRequirements): ident<Record<HeroModel>> => {
if (RequirePrimaryAttribute.is (x)) {
return putPrimaryAttributeDependency (modifyAttributeDependency)
(x)
return state => modifyPrimaryAttributeDependency (isToAdd, sourceId, x, state)
}
else if (RequireIncreasable.is (x)) {
return putIncreasableDependency (modifyAttributeDependency)
Expand Down
2 changes: 2 additions & 0 deletions src/App/Utilities/Raw/JSON/Hero/HeroFromJSON.ts
Expand Up @@ -301,6 +301,8 @@ const createHeroObject = (staticData: StaticDataRecord) => (hero: Raw.RawHero):
skillStyleDependencies: Nothing,
socialStatusDependencies: Nothing,
transferredUnfamiliarSpells: Nothing,
blessedPrimaryAttributeDependencies: [],
magicalPrimaryAttributeDependencies: [],
skillCheckAttributeCache: Nothing,
})

Expand Down

0 comments on commit ac0cdc3

Please sign in to comment.