@archivist-gg/dnd5e 0.3.1 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/SRD.md +25 -6
- package/dist/armor/armor.codec.js +4 -3
- package/dist/armor/armor.parser.js +3 -2
- package/dist/armor/armor.schema.d.ts +4 -0
- package/dist/armor/armor.schema.js +2 -1
- package/dist/armor/armor.types.d.ts +8 -0
- package/dist/background/background.codec.js +7 -6
- package/dist/background/background.parser.js +6 -5
- package/dist/background/background.schema.d.ts +26 -0
- package/dist/background/background.schema.js +5 -4
- package/dist/background/background.types.d.ts +22 -0
- package/dist/{chunk-4TIJKN6O.js → chunk-23LZLBJK.js} +1 -1
- package/dist/{chunk-AFKTJXRA.js → chunk-2DFENQIJ.js} +18 -0
- package/dist/chunk-2FRUSVZS.js +489 -0
- package/dist/chunk-2VDTW7QO.js +1580 -0
- package/dist/{chunk-ZZGEVJKX.js → chunk-3JOTQW7A.js} +1 -1
- package/dist/{chunk-5ZBE4CWV.js → chunk-3PZHBLFG.js} +1 -1
- package/dist/chunk-4U55VNC7.js +22 -0
- package/dist/{chunk-4JHOHWBI.js → chunk-4XTNPNQB.js} +1 -1
- package/dist/{chunk-HCP3GMHS.js → chunk-5N2GW72F.js} +15 -2
- package/dist/{chunk-42Y5IJKT.js → chunk-5RKLL2AD.js} +5 -1
- package/dist/{chunk-SE7AZDR3.js → chunk-63XQXPZL.js} +29 -3
- package/dist/{chunk-4F6AIZ36.js → chunk-6BFWZW6T.js} +1 -1
- package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
- package/dist/{chunk-66XXW2Z2.js → chunk-6PXTNCBP.js} +2 -2
- package/dist/chunk-6X2NV665.js +33 -0
- package/dist/{chunk-LV4SNWZQ.js → chunk-6X4KUDMU.js} +8 -1
- package/dist/{chunk-ZMR77DDL.js → chunk-AW3EHF3L.js} +1 -1
- package/dist/{chunk-TLYDBT5F.js → chunk-CGRLQ34U.js} +64 -7
- package/dist/chunk-CJYCVNW2.js +7 -0
- package/dist/{chunk-XLSVNUTK.js → chunk-CV5XDJKU.js} +1 -1
- package/dist/{chunk-RAWJTA45.js → chunk-DEEHHLAP.js} +1 -1
- package/dist/{chunk-6IRYTM5V.js → chunk-DPUJDOKV.js} +119 -28
- package/dist/{chunk-GE4TLPWM.js → chunk-EHDATXP7.js} +1 -1
- package/dist/chunk-EVMUJYUD.js +195 -0
- package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
- package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
- package/dist/{chunk-TN6ZLTNU.js → chunk-I2NDWFDD.js} +51 -4
- package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
- package/dist/chunk-IUAAXXNO.js +58 -0
- package/dist/{chunk-NXSWH3AE.js → chunk-IWRVOCT5.js} +1 -1
- package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
- package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
- package/dist/{chunk-XTIQWSFM.js → chunk-KADJZGZY.js} +1 -1
- package/dist/{chunk-L7E2UT5A.js → chunk-KK33PIDN.js} +5 -1
- package/dist/chunk-KPEJMNRD.js +302 -0
- package/dist/chunk-KU3YLF6D.js +106 -0
- package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
- package/dist/chunk-LVQLWRCU.js +15 -0
- package/dist/chunk-MI7P3NX3.js +161 -0
- package/dist/{chunk-PHQRGDRQ.js → chunk-N3A5ICBO.js} +5 -1
- package/dist/chunk-O4SRD3J5.js +165 -0
- package/dist/chunk-OAXWSVJB.js +81 -0
- package/dist/chunk-OZP6JFGT.js +162 -0
- package/dist/{chunk-NAEPSZAM.js → chunk-PDJSUH24.js} +24 -2
- package/dist/chunk-PP2UHLBA.js +50 -0
- package/dist/chunk-PVCEA4HZ.js +6 -0
- package/dist/{chunk-RSDRMH54.js → chunk-RF4TYCA2.js} +1 -1
- package/dist/chunk-RLGQ5PZZ.js +16 -0
- package/dist/chunk-RVXC6ZHY.js +89 -0
- package/dist/chunk-S7REMWW4.js +21 -0
- package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
- package/dist/chunk-TOM66P2P.js +38 -0
- package/dist/chunk-UA5KS2PL.js +26 -0
- package/dist/{chunk-N6N74K6X.js → chunk-UBBKSYBY.js} +1 -1
- package/dist/{chunk-353WXS6S.js → chunk-UIRMA5KM.js} +1 -1
- package/dist/{chunk-BIK4DFWK.js → chunk-ULCQ73LA.js} +1 -1
- package/dist/{chunk-2BWAID3Y.js → chunk-UMWIPLLM.js} +29 -3
- package/dist/chunk-UQ3ZFCWD.js +178 -0
- package/dist/chunk-UXPGW4TI.js +101 -0
- package/dist/chunk-V2MJE6NC.js +133 -0
- package/dist/{chunk-D3CLOBE3.js → chunk-V373TRJE.js} +48 -10
- package/dist/chunk-VQAXTIBW.js +100 -0
- package/dist/chunk-W74BCA7V.js +159 -0
- package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
- package/dist/{chunk-MDEJHMKK.js → chunk-WHVLNFTG.js} +26 -5
- package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
- package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
- package/dist/chunk-X3D6LXUU.js +185 -0
- package/dist/chunk-XJ2F2WO6.js +8 -0
- package/dist/{chunk-73HOFQQ5.js → chunk-Y4AGLCY6.js} +1 -1
- package/dist/chunk-YBLDE5CG.js +42 -0
- package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
- package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
- package/dist/class/class.codec.js +12 -9
- package/dist/class/class.parser.js +11 -8
- package/dist/class/class.schema.d.ts +55 -3
- package/dist/class/class.schema.js +9 -7
- package/dist/class/class.types.d.ts +48 -3
- package/dist/condition/condition.codec.d.ts +9 -0
- package/dist/condition/condition.entity-type.d.ts +2 -0
- package/dist/condition/condition.parser.d.ts +13 -0
- package/dist/condition/condition.parser.js +7 -0
- package/dist/condition/condition.schema.d.ts +29 -0
- package/dist/condition/condition.types.d.ts +15 -0
- package/dist/condition/condition.types.js +0 -0
- package/dist/dnd/constants.d.ts +22 -0
- package/dist/dnd/constants.js +9 -3
- package/dist/dnd/formula-tags.js +2 -2
- package/dist/dnd/math.d.ts +26 -0
- package/dist/dnd/math.js +12 -2
- package/dist/dnd/prose-tags.js +1 -1
- package/dist/dnd/resource-formula.d.ts +36 -10
- package/dist/dnd/resource-formula.js +10 -155
- package/dist/dnd/srd-tag-converter.js +3 -3
- package/dist/dnd/tag-grammar.js +1 -1
- package/dist/dnd/warn-once.d.ts +2 -0
- package/dist/dnd/warn-once.js +8 -0
- package/dist/entities/base-item-resolver.js +2 -2
- package/dist/entities/slug.d.ts +13 -0
- package/dist/entities/slug.js +5 -3
- package/dist/entities/wikilink-display.d.ts +3 -0
- package/dist/entities/wikilink-display.js +10 -0
- package/dist/feat/feat.category-codes.d.ts +32 -0
- package/dist/feat/feat.category-codes.js +14 -0
- package/dist/feat/feat.codec.js +7 -5
- package/dist/feat/feat.parser.js +6 -4
- package/dist/feat/feat.schema.d.ts +239 -0
- package/dist/feat/feat.schema.js +5 -3
- package/dist/feat/feat.types.d.ts +37 -1
- package/dist/index.js +2033 -6907
- package/dist/item/item.codec.js +4 -3
- package/dist/item/item.enrichment.js +4 -4
- package/dist/item/item.parser.js +3 -2
- package/dist/item/item.schema.d.ts +69 -3
- package/dist/item/item.schema.js +2 -1
- package/dist/item/item.types.d.ts +69 -3
- package/dist/monster/monster.codec.d.ts +7 -6
- package/dist/monster/monster.enrichment.js +4 -4
- package/dist/monster/monster.format.d.ts +135 -0
- package/dist/monster/monster.format.js +78 -0
- package/dist/monster/monster.parser.d.ts +6 -1
- package/dist/monster/monster.parser.js +10 -1
- package/dist/monster/monster.schema.d.ts +369 -0
- package/dist/monster/monster.schema.js +34 -0
- package/dist/monster/monster.types.d.ts +200 -14
- package/dist/optional-feature/optional-feature.codec.js +6 -5
- package/dist/optional-feature/optional-feature.parser.js +5 -4
- package/dist/optional-feature/optional-feature.schema.d.ts +185 -0
- package/dist/optional-feature/optional-feature.schema.js +4 -3
- package/dist/pack.d.ts +1 -1
- package/dist/pc/conditions.constants.d.ts +0 -1
- package/dist/pc/conditions.constants.js +1 -3
- package/dist/pc/decision-recognizer.js +1 -1
- package/dist/pc/pc.additional-spells.d.ts +47 -0
- package/dist/pc/pc.additional-spells.js +23 -0
- package/dist/pc/pc.asi-flatten.d.ts +18 -0
- package/dist/pc/pc.decision-engine.d.ts +105 -17
- package/dist/pc/pc.decision-engine.js +28 -12
- package/dist/pc/pc.defense-normalize.d.ts +11 -0
- package/dist/pc/pc.defense-normalize.js +6 -0
- package/dist/pc/pc.equipment.d.ts +31 -2
- package/dist/pc/pc.equipment.js +12 -8
- package/dist/pc/pc.feature-effects.d.ts +234 -11
- package/dist/pc/pc.feature-effects.js +21 -5
- package/dist/pc/pc.parser.js +2 -2
- package/dist/pc/pc.pools.d.ts +11 -3
- package/dist/pc/pc.pools.js +9 -13
- package/dist/pc/pc.proficiencies.d.ts +54 -29
- package/dist/pc/pc.proficiencies.js +74 -95
- package/dist/pc/pc.proficiency-grants.d.ts +58 -0
- package/dist/pc/pc.proficiency-normalize.d.ts +24 -0
- package/dist/pc/pc.proficiency-normalize.js +12 -0
- package/dist/pc/pc.proficiency-query.d.ts +13 -0
- package/dist/pc/pc.proficiency-query.js +1 -1
- package/dist/pc/pc.recalc.d.ts +69 -14
- package/dist/pc/pc.recalc.js +261 -122
- package/dist/pc/pc.resolver.d.ts +34 -8
- package/dist/pc/pc.resolver.js +27 -12
- package/dist/pc/pc.resource-seed.d.ts +3 -2
- package/dist/pc/pc.resource-seed.js +19 -17
- package/dist/pc/pc.resources.d.ts +87 -0
- package/dist/pc/pc.resources.js +21 -0
- package/dist/pc/pc.rest.d.ts +10 -1
- package/dist/pc/pc.rest.js +66 -12
- package/dist/pc/pc.schema.d.ts +139 -3
- package/dist/pc/pc.schema.js +4 -2
- package/dist/pc/pc.slotting.js +3 -3
- package/dist/pc/pc.spellcasting.d.ts +75 -6
- package/dist/pc/pc.spellcasting.js +16 -6
- package/dist/pc/pc.table-column.d.ts +23 -0
- package/dist/pc/pc.table-column.js +13 -3
- package/dist/pc/pc.types.d.ts +251 -12
- package/dist/pc/pool-layout.d.ts +47 -0
- package/dist/pc/pool-layout.js +16 -0
- package/dist/pc/roll-scope.d.ts +2 -0
- package/dist/pc/roll-scope.js +8 -0
- package/dist/pc/roll-tag-labels.d.ts +40 -0
- package/dist/pc/roll-tag-labels.js +17 -0
- package/dist/pc/spell-source.d.ts +21 -0
- package/dist/pc/spell-source.js +13 -0
- package/dist/race/race.codec.js +9 -7
- package/dist/race/race.parser.js +8 -6
- package/dist/race/race.schema.d.ts +51 -1
- package/dist/race/race.schema.js +8 -5
- package/dist/race/race.structural.d.ts +7 -0
- package/dist/race/race.structural.js +6 -0
- package/dist/race/race.types.d.ts +20 -0
- package/dist/schemas/attack-schema.d.ts +5 -0
- package/dist/schemas/caster-type-schema.d.ts +14 -0
- package/dist/schemas/caster-type-schema.js +6 -0
- package/dist/schemas/choice-schema.js +2 -2
- package/dist/schemas/entity-extras-schema.d.ts +53 -0
- package/dist/schemas/entity-extras-schema.js +10 -0
- package/dist/schemas/equipment-grant-schema.d.ts +2 -0
- package/dist/schemas/equipment-grant-schema.js +1 -1
- package/dist/schemas/feature-alias.d.ts +34 -0
- package/dist/schemas/feature-effect-schema.d.ts +133 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.d.ts +8 -0
- package/dist/schemas/feature-schema.js +6 -4
- package/dist/schemas/resource-schema.d.ts +43 -0
- package/dist/schemas/resource-schema.js +1 -1
- package/dist/schemas/selection-pool-schema.d.ts +2 -0
- package/dist/schemas/selection-pool-schema.js +1 -1
- package/dist/spell/spell.access.js +23 -3
- package/dist/spell/spell.codec.js +4 -3
- package/dist/spell/spell.enrichment.js +4 -4
- package/dist/spell/spell.parser.d.ts +30 -0
- package/dist/spell/spell.parser.js +9 -2
- package/dist/spell/spell.scaling.d.ts +27 -6
- package/dist/spell/spell.scaling.js +25 -6
- package/dist/spell/spell.schema.d.ts +44 -2
- package/dist/spell/spell.schema.js +2 -1
- package/dist/spell/spell.types.d.ts +14 -0
- package/dist/subclass/subclass.codec.d.ts +1 -1
- package/dist/subclass/subclass.codec.js +11 -8
- package/dist/subclass/subclass.parser.js +10 -7
- package/dist/subclass/subclass.schema.d.ts +54 -7
- package/dist/subclass/subclass.schema.js +8 -6
- package/dist/subclass/subclass.types.d.ts +20 -2
- package/dist/types/choice.d.ts +53 -2
- package/dist/types/choice.js +13 -1
- package/dist/types/equipment-grant.d.ts +8 -1
- package/dist/types/feature-effect.d.ts +85 -23
- package/dist/types/feature.d.ts +70 -1
- package/dist/types/optional-feature.types.d.ts +28 -0
- package/dist/types/resource.d.ts +21 -1
- package/dist/types/selection-pool.d.ts +17 -2
- package/dist/weapon/weapon.classify.js +2 -2
- package/dist/weapon/weapon.codec.js +4 -3
- package/dist/weapon/weapon.parser.js +3 -2
- package/dist/weapon/weapon.schema.d.ts +4 -0
- package/dist/weapon/weapon.schema.js +2 -1
- package/dist/weapon/weapon.types.d.ts +8 -0
- package/package.json +2 -2
- package/dist/chunk-5XUXXAQJ.js +0 -30
- package/dist/chunk-7P65Q426.js +0 -158
- package/dist/chunk-7TEK5KK7.js +0 -49
- package/dist/chunk-AIRFC5NQ.js +0 -143
- package/dist/chunk-CZPMTQOY.js +0 -68
- package/dist/chunk-N2JE7BWL.js +0 -81
- package/dist/chunk-NXR3BD2V.js +0 -90
- package/dist/chunk-O5EYMKFH.js +0 -6
- package/dist/chunk-Q5K6LWBZ.js +0 -45
- package/dist/chunk-TNUFPIXI.js +0 -1110
- package/dist/chunk-TZK36BU7.js +0 -38
- package/dist/chunk-W7HWMMBF.js +0 -46
- package/dist/chunk-Y4I74YEG.js +0 -33
package/dist/pc/pc.recalc.js
CHANGED
|
@@ -4,49 +4,88 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
collectChosenAbilityPoints,
|
|
6
6
|
collectChosenProficiencies
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import
|
|
7
|
+
} from "../chunk-2VDTW7QO.js";
|
|
8
|
+
import {
|
|
9
|
+
resourceLevelFor
|
|
10
|
+
} from "../chunk-UXPGW4TI.js";
|
|
9
11
|
import {
|
|
10
12
|
computeSpellLimits,
|
|
11
13
|
deriveSpellSlots,
|
|
12
14
|
effectiveSpellcastingAbility,
|
|
13
15
|
resolveSpellcasting
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-DPUJDOKV.js";
|
|
17
|
+
import "../chunk-O4SRD3J5.js";
|
|
18
|
+
import "../chunk-PP2UHLBA.js";
|
|
19
|
+
import {
|
|
20
|
+
diceColumnAt,
|
|
21
|
+
unarmedDieColumnFor
|
|
22
|
+
} from "../chunk-IUAAXXNO.js";
|
|
23
|
+
import "../chunk-YHYTW5QA.js";
|
|
24
|
+
import "../chunk-MI7P3NX3.js";
|
|
25
|
+
import "../chunk-PVCEA4HZ.js";
|
|
26
|
+
import {
|
|
27
|
+
toDefenseSlug
|
|
28
|
+
} from "../chunk-XJ2F2WO6.js";
|
|
17
29
|
import {
|
|
30
|
+
buildUnarmedRow,
|
|
18
31
|
computeAppliedBonuses,
|
|
19
32
|
computeSlotsAndAttacks,
|
|
20
33
|
emptyAppliedBonuses
|
|
21
|
-
} from "../chunk-
|
|
22
|
-
import "../chunk-
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-N6N74K6X.js";
|
|
34
|
+
} from "../chunk-V373TRJE.js";
|
|
35
|
+
import "../chunk-UIRMA5KM.js";
|
|
36
|
+
import "../chunk-UBBKSYBY.js";
|
|
25
37
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
assembleEffectFeatures,
|
|
39
|
+
computeFeatureEffects,
|
|
40
|
+
foldsNow,
|
|
41
|
+
selfEffectsOf
|
|
42
|
+
} from "../chunk-KPEJMNRD.js";
|
|
43
|
+
import "../chunk-TOM66P2P.js";
|
|
44
|
+
import "../chunk-KU3YLF6D.js";
|
|
45
|
+
import "../chunk-RLGQ5PZZ.js";
|
|
28
46
|
import "../chunk-LWFTHJIE.js";
|
|
29
47
|
import "../chunk-DNAJRMNN.js";
|
|
30
|
-
import "../chunk-
|
|
31
|
-
import "../chunk-
|
|
48
|
+
import "../chunk-LVQLWRCU.js";
|
|
49
|
+
import "../chunk-WXWPK3LI.js";
|
|
50
|
+
import "../chunk-6X4KUDMU.js";
|
|
51
|
+
import "../chunk-YBLDE5CG.js";
|
|
52
|
+
import {
|
|
53
|
+
evaluateMaxFormula,
|
|
54
|
+
isValidMaxFormula
|
|
55
|
+
} from "../chunk-EVMUJYUD.js";
|
|
32
56
|
import "../chunk-VTTA2ALZ.js";
|
|
57
|
+
import "../chunk-OZP6JFGT.js";
|
|
58
|
+
import "../chunk-VQAXTIBW.js";
|
|
33
59
|
import {
|
|
34
60
|
abilityModifier,
|
|
35
61
|
attackBonus,
|
|
62
|
+
isCanonicalDamageType,
|
|
63
|
+
isChosenDamageType,
|
|
36
64
|
passive,
|
|
37
65
|
passivePerception,
|
|
38
66
|
proficiencyFromLevel,
|
|
39
67
|
saveDC,
|
|
40
68
|
savingThrow,
|
|
41
69
|
skillBonus
|
|
42
|
-
} from "../chunk-
|
|
70
|
+
} from "../chunk-PDJSUH24.js";
|
|
43
71
|
import {
|
|
44
72
|
ABILITY_KEYS,
|
|
45
73
|
ALL_SKILLS,
|
|
46
74
|
SKILL_ABILITY
|
|
47
|
-
} from "../chunk-
|
|
75
|
+
} from "../chunk-WELIKLZF.js";
|
|
76
|
+
import "../chunk-4U55VNC7.js";
|
|
77
|
+
import "../chunk-UA5KS2PL.js";
|
|
48
78
|
|
|
49
79
|
// src/pc/pc.recalc.ts
|
|
80
|
+
var WEAPON_CATEGORY_WORDS = /* @__PURE__ */ new Set([
|
|
81
|
+
"simple",
|
|
82
|
+
"martial",
|
|
83
|
+
"simple-melee",
|
|
84
|
+
"simple-ranged",
|
|
85
|
+
"martial-melee",
|
|
86
|
+
"martial-ranged",
|
|
87
|
+
"natural"
|
|
88
|
+
]);
|
|
50
89
|
function phbAverageForDie(hitDieStr) {
|
|
51
90
|
const n = parseDieSize(hitDieStr);
|
|
52
91
|
if (n == null) return 4;
|
|
@@ -88,7 +127,9 @@ function collectClassAsiBranch(resolved) {
|
|
|
88
127
|
const out = {};
|
|
89
128
|
for (const c of resolved.classes) {
|
|
90
129
|
for (const [, choice] of Object.entries(c.choices)) {
|
|
91
|
-
const
|
|
130
|
+
const block = choice;
|
|
131
|
+
if (typeof (block == null ? void 0 : block.feat) === "string") continue;
|
|
132
|
+
const asi = block == null ? void 0 : block.asi;
|
|
92
133
|
if (!asi) continue;
|
|
93
134
|
for (const ab of ABILITY_KEYS) {
|
|
94
135
|
const v = asi[ab];
|
|
@@ -98,8 +139,8 @@ function collectClassAsiBranch(resolved) {
|
|
|
98
139
|
}
|
|
99
140
|
return out;
|
|
100
141
|
}
|
|
101
|
-
function abilityBonusBreakdown(resolved) {
|
|
102
|
-
var _a, _b, _c, _d, _e, _f;
|
|
142
|
+
function abilityBonusBreakdown(resolved, featureEffects) {
|
|
143
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
103
144
|
const race = flattenRaceAsi(resolved.race);
|
|
104
145
|
const origin = collectChosenAbilityPoints(resolved);
|
|
105
146
|
const sub = subraceAsi(resolved);
|
|
@@ -116,7 +157,7 @@ function abilityBonusBreakdown(resolved) {
|
|
|
116
157
|
const bonus = (_d = f.ability_bonuses) == null ? void 0 : _d[ab];
|
|
117
158
|
if (typeof bonus === "number") feat += bonus;
|
|
118
159
|
}
|
|
119
|
-
out[ab] = { species, background: (_e = origin.background[ab]) != null ? _e : 0, class: (_f = classAsi[ab]) != null ? _f : 0, feat };
|
|
160
|
+
out[ab] = { species, background: (_e = origin.background[ab]) != null ? _e : 0, class: ((_f = classAsi[ab]) != null ? _f : 0) + ((_g = featureEffects == null ? void 0 : featureEffects.ability_bonus[ab]) != null ? _g : 0), feat };
|
|
120
161
|
}
|
|
121
162
|
return out;
|
|
122
163
|
}
|
|
@@ -151,65 +192,123 @@ function hpLevelCount(classes) {
|
|
|
151
192
|
function multiclassMaxHP(classes, conMod) {
|
|
152
193
|
return Math.max(1, hitDiceAverageSum(classes) + conMod * hpLevelCount(classes));
|
|
153
194
|
}
|
|
195
|
+
function resolveRiderAmount(amount, bindings) {
|
|
196
|
+
if (!amount.includes("{")) return amount;
|
|
197
|
+
const formula = amount.replace(/\{prof_bonus\}/g, "{prof}");
|
|
198
|
+
if (!isValidMaxFormula(formula)) return amount;
|
|
199
|
+
return String(evaluateMaxFormula(formula, bindings));
|
|
200
|
+
}
|
|
201
|
+
function resolveDamageRider(rider, rowDamageType, bindings) {
|
|
202
|
+
const out = { ...rider, amount: resolveRiderAmount(rider.amount, bindings) };
|
|
203
|
+
if (rider.damage_type !== void 0 && !isChosenDamageType(rider.damage_type)) {
|
|
204
|
+
const resolved = isCanonicalDamageType(rider.damage_type) ? rider.damage_type : rowDamageType;
|
|
205
|
+
if (resolved) out.damage_type = resolved;
|
|
206
|
+
else delete out.damage_type;
|
|
207
|
+
}
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
154
210
|
function unarmoredAC(resolved, mods, warnings) {
|
|
155
211
|
return unarmoredACBreakdown(resolved, mods, warnings).total;
|
|
156
212
|
}
|
|
157
|
-
function unarmoredACBreakdown(resolved, mods, warnings) {
|
|
158
|
-
var _a, _b, _c, _d, _e
|
|
213
|
+
function unarmoredACBreakdown(resolved, mods, warnings, shieldBonus = 0) {
|
|
214
|
+
var _a, _b, _c, _d, _e;
|
|
159
215
|
const baseTerms = [
|
|
160
216
|
{ source: "Unarmored", amount: 10, kind: "unarmored" },
|
|
161
217
|
{ source: "DEX modifier", amount: mods.dex, kind: "dex" }
|
|
162
218
|
];
|
|
219
|
+
const { activeBuffs } = assembleEffectFeatures(resolved);
|
|
220
|
+
const candidates = [
|
|
221
|
+
{ total: 10 + mods.dex, terms: baseTerms, shieldAllowed: true }
|
|
222
|
+
];
|
|
163
223
|
for (const rf of resolved.features) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
];
|
|
171
|
-
let total = base + mods.dex;
|
|
224
|
+
if (!foldsNow(rf, activeBuffs)) continue;
|
|
225
|
+
for (const eff of selfEffectsOf(rf.feature)) {
|
|
226
|
+
if (eff.kind !== "unarmored-ac") continue;
|
|
227
|
+
const base = (_a = eff.base) != null ? _a : 10;
|
|
228
|
+
const terms = [{ source: "Unarmored", amount: base, kind: "unarmored" }];
|
|
229
|
+
let total = base;
|
|
172
230
|
for (const ab of eff.abilities) {
|
|
173
|
-
|
|
174
|
-
terms.push({ source: `${ab.toUpperCase()} modifier (${(_c = rf.feature.name) != null ? _c : "Unarmored"})`, amount: mods[ab], kind: "ability" });
|
|
231
|
+
terms.push(ab === "dex" ? { source: "DEX modifier", amount: mods.dex, kind: "dex" } : { source: `${ab.toUpperCase()} modifier (${(_b = rf.feature.name) != null ? _b : "Unarmored"})`, amount: mods[ab], kind: "ability" });
|
|
175
232
|
total += mods[ab];
|
|
176
233
|
}
|
|
177
|
-
|
|
234
|
+
candidates.push({ total, terms, shieldAllowed: eff.allow_shield === true });
|
|
178
235
|
}
|
|
179
236
|
}
|
|
237
|
+
if (candidates.length > 1) {
|
|
238
|
+
const applied = (c) => c.total + (c.shieldAllowed ? shieldBonus : 0);
|
|
239
|
+
let best = candidates[0];
|
|
240
|
+
for (const c of candidates) if (applied(c) > applied(best)) best = c;
|
|
241
|
+
return best;
|
|
242
|
+
}
|
|
180
243
|
for (const rf of resolved.features) {
|
|
181
244
|
const feat = rf.feature;
|
|
182
|
-
if ((
|
|
245
|
+
if ((_c = feat.unarmored_defense) == null ? void 0 : _c.ability) {
|
|
183
246
|
const ab = feat.unarmored_defense.ability;
|
|
184
|
-
const amt = (
|
|
247
|
+
const amt = (_d = mods[ab]) != null ? _d : 0;
|
|
185
248
|
const terms = [
|
|
186
249
|
...baseTerms,
|
|
187
250
|
{ source: `${ab.toUpperCase()} modifier (Unarmored Defense)`, amount: amt, kind: "ability" }
|
|
188
251
|
];
|
|
189
|
-
return { total: 10 + mods.dex + amt, terms };
|
|
252
|
+
return { total: 10 + mods.dex + amt, terms, shieldAllowed: true };
|
|
190
253
|
}
|
|
191
254
|
}
|
|
192
255
|
for (const rf of resolved.features) {
|
|
193
|
-
const name = ((
|
|
256
|
+
const name = ((_e = rf.feature.name) != null ? _e : "").toLowerCase();
|
|
194
257
|
if (!/unarmored\s*defense/.test(name)) continue;
|
|
195
258
|
if (rf.source.kind === "class" && rf.source.slug.includes("monk")) {
|
|
196
|
-
warnings.push(`Unarmored Defense detected by name on ${rf.source.slug}; populate unarmored_defense:{ability:wis} flag for accuracy.`);
|
|
197
259
|
const terms = [
|
|
198
260
|
...baseTerms,
|
|
199
261
|
{ source: "WIS modifier (Unarmored Defense)", amount: mods.wis, kind: "ability" }
|
|
200
262
|
];
|
|
201
|
-
return { total: 10 + mods.dex + mods.wis, terms };
|
|
263
|
+
return { total: 10 + mods.dex + mods.wis, terms, shieldAllowed: true };
|
|
202
264
|
}
|
|
203
265
|
if (rf.source.kind === "class" && rf.source.slug.includes("barbarian")) {
|
|
204
|
-
warnings.push(`Unarmored Defense detected by name on ${rf.source.slug}; populate unarmored_defense:{ability:con} flag for accuracy.`);
|
|
205
266
|
const terms = [
|
|
206
267
|
...baseTerms,
|
|
207
268
|
{ source: "CON modifier (Unarmored Defense)", amount: mods.con, kind: "ability" }
|
|
208
269
|
];
|
|
209
|
-
return { total: 10 + mods.dex + mods.con, terms };
|
|
270
|
+
return { total: 10 + mods.dex + mods.con, terms, shieldAllowed: true };
|
|
210
271
|
}
|
|
211
272
|
}
|
|
212
|
-
return { total: 10 + mods.dex, terms: baseTerms };
|
|
273
|
+
return { total: 10 + mods.dex, terms: baseTerms, shieldAllowed: true };
|
|
274
|
+
}
|
|
275
|
+
function resolveUnarmedStrike(resolved) {
|
|
276
|
+
var _a, _b, _c;
|
|
277
|
+
const dice = [];
|
|
278
|
+
const abilities = /* @__PURE__ */ new Set();
|
|
279
|
+
const classOf = (rf) => rf.source.kind === "class" ? resolved.classes.find((c) => {
|
|
280
|
+
var _a2;
|
|
281
|
+
return ((_a2 = c.entity) == null ? void 0 : _a2.slug) === rf.source.slug;
|
|
282
|
+
}) : void 0;
|
|
283
|
+
const readDie = (rf, d) => {
|
|
284
|
+
var _a2, _b2;
|
|
285
|
+
if (typeof d === "string") return d;
|
|
286
|
+
if (!d) return void 0;
|
|
287
|
+
const cls = classOf(rf);
|
|
288
|
+
return cls ? (_b2 = diceColumnAt((_a2 = cls.entity) == null ? void 0 : _a2.table, cls.level, d.column)) != null ? _b2 : void 0 : void 0;
|
|
289
|
+
};
|
|
290
|
+
for (const rf of resolved.features) {
|
|
291
|
+
const authored = selfEffectsOf(rf.feature).filter((e) => e.kind === "unarmed-strike");
|
|
292
|
+
for (const e of authored) {
|
|
293
|
+
const d2 = readDie(rf, e.dice);
|
|
294
|
+
if (d2) dice.push(d2);
|
|
295
|
+
for (const ab of (_a = e.abilities) != null ? _a : []) abilities.add(ab);
|
|
296
|
+
}
|
|
297
|
+
if (authored.length || rf.source.kind !== "class") continue;
|
|
298
|
+
const slug = ((_c = (_b = rf.feature.id) != null ? _b : rf.feature.name) != null ? _c : "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
299
|
+
const column = unarmedDieColumnFor(slug);
|
|
300
|
+
if (!column) continue;
|
|
301
|
+
const d = readDie(rf, { column });
|
|
302
|
+
if (!d) continue;
|
|
303
|
+
dice.push(d);
|
|
304
|
+
abilities.add("dex");
|
|
305
|
+
}
|
|
306
|
+
const avg = (d) => {
|
|
307
|
+
const m = /^(\d+)d(\d+)$/i.exec(d);
|
|
308
|
+
return m ? Number(m[1]) * (Number(m[2]) + 1) / 2 : 1;
|
|
309
|
+
};
|
|
310
|
+
const best = dice.sort((a, b) => avg(b) - avg(a))[0];
|
|
311
|
+
return { ...best ? { dice: best } : {}, ...abilities.size ? { abilities: [...abilities] } : {} };
|
|
213
312
|
}
|
|
214
313
|
function initiativeBonus(dexMod, feats, edition) {
|
|
215
314
|
let bonus = dexMod;
|
|
@@ -326,18 +425,51 @@ function mergeInto(target, source) {
|
|
|
326
425
|
for (const c of source.categories) if (!target.categories.includes(c)) target.categories.push(c);
|
|
327
426
|
for (const s of source.specific) if (!target.specific.includes(s)) target.specific.push(s);
|
|
328
427
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
428
|
+
var ORIGIN_RANK = { manual: 0, equipment: 1, grant: 2 };
|
|
429
|
+
function composeDefenseEntries(manual, equipment, grants) {
|
|
430
|
+
var _a;
|
|
431
|
+
const byValue = /* @__PURE__ */ new Map();
|
|
432
|
+
const consider = (list, origin) => {
|
|
433
|
+
for (const raw of list) {
|
|
434
|
+
const value = toDefenseSlug(raw);
|
|
435
|
+
if (!value) continue;
|
|
436
|
+
const existing = byValue.get(value);
|
|
437
|
+
if (!existing) {
|
|
438
|
+
byValue.set(value, { value, label: raw.trim(), origin });
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
if (ORIGIN_RANK[origin] > ORIGIN_RANK[existing.origin]) existing.origin = origin;
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
consider(manual, "manual");
|
|
445
|
+
consider(equipment, "equipment");
|
|
446
|
+
for (const g of grants) {
|
|
447
|
+
const value = toDefenseSlug(g.value);
|
|
448
|
+
if (!value) continue;
|
|
449
|
+
const existing = byValue.get(value);
|
|
450
|
+
if (!existing) {
|
|
451
|
+
byValue.set(value, {
|
|
452
|
+
value,
|
|
453
|
+
label: g.value.trim(),
|
|
454
|
+
origin: "grant",
|
|
455
|
+
sources: [...g.sources],
|
|
456
|
+
...g.condition ? { condition: g.condition } : {}
|
|
457
|
+
});
|
|
458
|
+
continue;
|
|
338
459
|
}
|
|
460
|
+
if (ORIGIN_RANK.grant > ORIGIN_RANK[existing.origin]) existing.origin = "grant";
|
|
461
|
+
const sources = (_a = existing.sources) != null ? _a : existing.sources = [];
|
|
462
|
+
for (const src of g.sources) if (!sources.includes(src)) sources.push(src);
|
|
463
|
+
if (!existing.condition && g.condition) existing.condition = g.condition;
|
|
339
464
|
}
|
|
340
|
-
return
|
|
465
|
+
return [...byValue.values()];
|
|
466
|
+
}
|
|
467
|
+
function suppress(resolved, bucket, entries) {
|
|
468
|
+
var _a, _b, _c, _d, _e;
|
|
469
|
+
const suppressed = new Set(
|
|
470
|
+
((_e = (_d = (_c = (_b = (_a = resolved.definition) == null ? void 0 : _a.overrides) == null ? void 0 : _b.defenses) == null ? void 0 : _c[bucket]) == null ? void 0 : _d.remove) != null ? _e : []).map(toDefenseSlug)
|
|
471
|
+
);
|
|
472
|
+
return entries.filter((e) => !suppressed.has(e.value));
|
|
341
473
|
}
|
|
342
474
|
function computeProficiencies(resolved) {
|
|
343
475
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -384,28 +516,12 @@ function computeProficiencies(resolved) {
|
|
|
384
516
|
};
|
|
385
517
|
}
|
|
386
518
|
function recalc(resolved, registry) {
|
|
387
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V
|
|
519
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V;
|
|
388
520
|
const warnings = [];
|
|
389
521
|
const overrides = (_a = resolved.definition.overrides) != null ? _a : {};
|
|
390
522
|
const chosenProfs = collectChosenProficiencies(resolved);
|
|
391
|
-
const
|
|
392
|
-
const
|
|
393
|
-
const pushBoon = (item, pool) => {
|
|
394
|
-
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
395
|
-
const e = item.entity;
|
|
396
|
-
if (!e || ((_b2 = (_a2 = e.effects) == null ? void 0 : _a2.length) != null ? _b2 : 0) === 0) return;
|
|
397
|
-
buffFeatures.push({
|
|
398
|
-
feature: { id: item.slug, name: e.name, activatable: (_c2 = e.activatable) != null ? _c2 : false, effects: e.effects },
|
|
399
|
-
// source is inert for the fold; attribute to the pool's owning class
|
|
400
|
-
// (never a hardcoded class) so the generic engine carries no homebrew name.
|
|
401
|
-
source: { kind: "class", slug: (_f2 = (_e2 = (_d2 = resolved.classes[pool.classIndex]) == null ? void 0 : _d2.entity) == null ? void 0 : _e2.slug) != null ? _f2 : pool.id, level: pool.anchorLevel }
|
|
402
|
-
});
|
|
403
|
-
};
|
|
404
|
-
for (const pool of (_c = resolved.pools) != null ? _c : []) {
|
|
405
|
-
for (const sel of (_d = pool.selected) != null ? _d : []) pushBoon(sel, pool);
|
|
406
|
-
for (const g of (_e = pool.grants) != null ? _e : []) pushBoon(g, pool);
|
|
407
|
-
}
|
|
408
|
-
const featureEffects = computeFeatureEffects([...resolved.features, ...buffFeatures], { activeBuffs });
|
|
523
|
+
const { features: effectFeatures, activeBuffs } = assembleEffectFeatures(resolved);
|
|
524
|
+
const featureEffects = computeFeatureEffects(effectFeatures, { activeBuffs, levelFor: (src) => resourceLevelFor(src, resolved) });
|
|
409
525
|
const profsForApply = computeProficiencies(resolved);
|
|
410
526
|
for (const t of chosenProfs.tools) {
|
|
411
527
|
if (!profsForApply.tools.specific.includes(t)) profsForApply.tools.specific.push(t);
|
|
@@ -413,6 +529,9 @@ function recalc(resolved, registry) {
|
|
|
413
529
|
for (const l of chosenProfs.languages) {
|
|
414
530
|
if (!profsForApply.languages.includes(l)) profsForApply.languages.push(l);
|
|
415
531
|
}
|
|
532
|
+
for (const w of chosenProfs.weapons) {
|
|
533
|
+
if (!profsForApply.weapons.specific.includes(w)) profsForApply.weapons.specific.push(w);
|
|
534
|
+
}
|
|
416
535
|
for (const t of featureEffects.proficiencies.tools) {
|
|
417
536
|
if (!profsForApply.tools.specific.includes(t)) profsForApply.tools.specific.push(t);
|
|
418
537
|
}
|
|
@@ -424,6 +543,9 @@ function recalc(resolved, registry) {
|
|
|
424
543
|
}
|
|
425
544
|
for (const w of featureEffects.proficiencies.weapons) {
|
|
426
545
|
if (!profsForApply.weapons.categories.includes(w)) profsForApply.weapons.categories.push(w);
|
|
546
|
+
if (!WEAPON_CATEGORY_WORDS.has(w) && !profsForApply.weapons.specific.includes(w)) {
|
|
547
|
+
profsForApply.weapons.specific.push(w);
|
|
548
|
+
}
|
|
427
549
|
}
|
|
428
550
|
profsForApply.languages.sort();
|
|
429
551
|
const applied = registry ? computeAppliedBonuses(resolved, profsForApply, registry, warnings) : emptyAppliedBonuses();
|
|
@@ -440,7 +562,7 @@ function recalc(resolved, registry) {
|
|
|
440
562
|
const scores = { ...baseScores };
|
|
441
563
|
for (const ab of ABILITY_KEYS) {
|
|
442
564
|
const bonus = applied.ability_bonuses[ab];
|
|
443
|
-
|
|
565
|
+
scores[ab] += (typeof bonus === "number" ? bonus : 0) + ((_b = featureEffects.ability_bonus[ab]) != null ? _b : 0);
|
|
444
566
|
}
|
|
445
567
|
for (const ab of ABILITY_KEYS) {
|
|
446
568
|
const stat = applied.ability_statics[ab];
|
|
@@ -467,31 +589,32 @@ function recalc(resolved, registry) {
|
|
|
467
589
|
resolved.definition.edition,
|
|
468
590
|
scores
|
|
469
591
|
);
|
|
470
|
-
const firstClass = (
|
|
471
|
-
const saveProfs = new Set((
|
|
592
|
+
const firstClass = (_d = (_c = resolved.classes[0]) == null ? void 0 : _c.entity) != null ? _d : null;
|
|
593
|
+
const saveProfs = new Set((_e = firstClass == null ? void 0 : firstClass.saving_throws) != null ? _e : []);
|
|
472
594
|
for (const ab of featureEffects.proficiencies.saves) saveProfs.add(ab);
|
|
595
|
+
for (const ab of chosenProfs.saves) saveProfs.add(ab);
|
|
473
596
|
const saves = {};
|
|
474
597
|
for (const ab of ABILITY_KEYS) {
|
|
475
|
-
const override = (
|
|
476
|
-
const prof = (
|
|
598
|
+
const override = (_f = overrides.saves) == null ? void 0 : _f[ab];
|
|
599
|
+
const prof = (_g = override == null ? void 0 : override.proficient) != null ? _g : saveProfs.has(ab);
|
|
477
600
|
const derivedBonus = savingThrow(scores[ab], prof, proficiencyBonus) + applied.save_bonus + conditionEffects.d20_test_penalty;
|
|
478
|
-
const bonus = (
|
|
601
|
+
const bonus = (_h = override == null ? void 0 : override.bonus) != null ? _h : derivedBonus;
|
|
479
602
|
saves[ab] = { bonus, proficient: prof };
|
|
480
603
|
}
|
|
481
604
|
const profSet = /* @__PURE__ */ new Set([
|
|
482
605
|
...resolved.definition.skills.proficient,
|
|
483
|
-
...(
|
|
606
|
+
...(_j = (_i = resolved.background) == null ? void 0 : _i.skill_proficiencies) != null ? _j : [],
|
|
484
607
|
...chosenProfs.skills,
|
|
485
608
|
...featureEffects.proficiencies.skills
|
|
486
609
|
]);
|
|
487
|
-
const expSet = /* @__PURE__ */ new Set([...resolved.definition.skills.expertise, ...chosenProfs.expertise]);
|
|
610
|
+
const expSet = /* @__PURE__ */ new Set([...resolved.definition.skills.expertise, ...chosenProfs.expertise, ...featureEffects.proficiencies.skillExpertise]);
|
|
488
611
|
const skills = {};
|
|
489
612
|
for (const skill of ALL_SKILLS) {
|
|
490
613
|
const skillKey = skillSlugFromDisplay(skill);
|
|
491
614
|
const ab = SKILL_ABILITY[skillSlugToAbilityLookup(skillKey)];
|
|
492
|
-
const override = (
|
|
493
|
-
const tri = (
|
|
494
|
-
const bonus = (
|
|
615
|
+
const override = (_k = overrides.skills) == null ? void 0 : _k[skillKey];
|
|
616
|
+
const tri = (_l = override == null ? void 0 : override.proficiency) != null ? _l : expSet.has(skillKey) ? "expertise" : profSet.has(skillKey) ? "proficient" : "none";
|
|
617
|
+
const bonus = (_m = override == null ? void 0 : override.bonus) != null ? _m : skillBonus(scores[ab], tri, proficiencyBonus) + conditionEffects.d20_test_penalty;
|
|
495
618
|
skills[skillKey] = {
|
|
496
619
|
bonus,
|
|
497
620
|
proficiency: tri,
|
|
@@ -502,12 +625,12 @@ function recalc(resolved, registry) {
|
|
|
502
625
|
const investigationTri = skills.investigation.proficiency;
|
|
503
626
|
const insightTri = skills.insight.proficiency;
|
|
504
627
|
const passives = {
|
|
505
|
-
perception: (
|
|
506
|
-
investigation: (
|
|
507
|
-
insight: (
|
|
628
|
+
perception: (_o = (_n = overrides.passives) == null ? void 0 : _n.perception) != null ? _o : passivePerception(scores.wis, perceptionTri, proficiencyBonus),
|
|
629
|
+
investigation: (_q = (_p = overrides.passives) == null ? void 0 : _p.investigation) != null ? _q : passive(scores.int, investigationTri, proficiencyBonus),
|
|
630
|
+
insight: (_s = (_r = overrides.passives) == null ? void 0 : _r.insight) != null ? _s : passive(scores.wis, insightTri, proficiencyBonus)
|
|
508
631
|
};
|
|
509
|
-
const hpRolled = (
|
|
510
|
-
const hpModifier = (
|
|
632
|
+
const hpRolled = (_u = (_t = overrides.hp) == null ? void 0 : _t.rolled) != null ? _u : null;
|
|
633
|
+
const hpModifier = (_w = (_v = overrides.hp) == null ? void 0 : _v.modifier) != null ? _w : null;
|
|
511
634
|
const averageDiceSum = hitDiceAverageSum(resolved.classes);
|
|
512
635
|
const conLevels = hpLevelCount(resolved.classes);
|
|
513
636
|
const diceSum = hpRolled != null ? hpRolled : averageDiceSum;
|
|
@@ -515,7 +638,7 @@ function recalc(resolved, registry) {
|
|
|
515
638
|
const diceConClamped = Math.max(1, diceConRaw);
|
|
516
639
|
const hpMaxDerived = diceConClamped + featureEffects.hp_per_level_bonus * totalLevel + (hpModifier != null ? hpModifier : 0);
|
|
517
640
|
const hpMaxAfterConditions = Math.max(0, Math.floor(hpMaxDerived * conditionEffects.hp_max_multiplier));
|
|
518
|
-
const hpMax = (
|
|
641
|
+
const hpMax = (_y = (_x = overrides.hp) == null ? void 0 : _x.max) != null ? _y : hpMaxAfterConditions;
|
|
519
642
|
const hpBreakdown = {
|
|
520
643
|
diceSum,
|
|
521
644
|
diceSource: hpRolled != null ? "rolled" : "average",
|
|
@@ -533,16 +656,13 @@ function recalc(resolved, registry) {
|
|
|
533
656
|
exhaustionMultiplier: conditionEffects.hp_max_multiplier,
|
|
534
657
|
exhaustionLevel: conditionEffects.exhaustion_level,
|
|
535
658
|
derivedMax: hpMaxAfterConditions,
|
|
536
|
-
override: (
|
|
659
|
+
override: (_A = (_z = overrides.hp) == null ? void 0 : _z.max) != null ? _A : null,
|
|
537
660
|
final: hpMax
|
|
538
661
|
};
|
|
539
|
-
const featureAcTermsFor = (hasArmor) => featureEffects.ac_terms.filter((t) => !t.requires_armor || hasArmor).map((t) => ({ source: t.label, amount: t.value, kind: "feature" }));
|
|
662
|
+
const featureAcTermsFor = (hasArmor) => featureEffects.ac_terms.filter((t) => !t.requires_armor || hasArmor).map((t) => ({ source: t.label, amount: t.value, kind: "feature", condition: t.condition }));
|
|
540
663
|
const sumTerms = (terms) => terms.reduce((s, t) => s + t.amount, 0);
|
|
541
664
|
const weaponAbilities = [...featureEffects.weaponAbilities];
|
|
542
|
-
const wantsSpellcasting = resolved.features.some((rf) =>
|
|
543
|
-
var _a2;
|
|
544
|
-
return ((_a2 = rf.feature.effects) != null ? _a2 : []).some((e) => e.kind === "weapon-ability" && e.ability === "spellcasting");
|
|
545
|
-
});
|
|
665
|
+
const wantsSpellcasting = resolved.features.some((rf) => selfEffectsOf(rf.feature).some((e) => e.kind === "weapon-ability" && e.ability === "spellcasting"));
|
|
546
666
|
if (wantsSpellcasting) {
|
|
547
667
|
let primaryCasterAbility = null;
|
|
548
668
|
for (const c of resolved.classes) {
|
|
@@ -560,16 +680,17 @@ function recalc(resolved, registry) {
|
|
|
560
680
|
let acBreakdownDerived = [];
|
|
561
681
|
let acInformationalDerived = [];
|
|
562
682
|
if (registry) {
|
|
563
|
-
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (
|
|
683
|
+
derivedEquipment = computeSlotsAndAttacks(resolved, mods, profsForApply, registry, warnings, proficiencyBonus, weaponAbilities, (_B = resolved.weaponMasteries) != null ? _B : [], featureEffects.attunement_set);
|
|
564
684
|
if (derivedEquipment.equippedSlots.armor) {
|
|
565
685
|
const featTerms = featureAcTermsFor(true);
|
|
566
686
|
acDerived = derivedEquipment.ac + sumTerms(featTerms);
|
|
567
687
|
acBreakdownDerived = [...derivedEquipment.acBreakdown, ...featTerms];
|
|
568
688
|
acInformationalDerived = derivedEquipment.acInformational;
|
|
569
689
|
} else {
|
|
570
|
-
const
|
|
690
|
+
const shieldBonus = derivedEquipment.acBreakdown.filter((b) => b.kind === "shield").reduce((sum, b) => sum + b.amount, 0);
|
|
691
|
+
const { total: unarmored, terms: unarmoredTerms, shieldAllowed } = unarmoredACBreakdown(resolved, mods, warnings, shieldBonus);
|
|
571
692
|
const additive = derivedEquipment.acBreakdown.filter(
|
|
572
|
-
(b) => b.kind === "item" || b.kind === "override" || b.kind === "shield"
|
|
693
|
+
(b) => b.kind === "item" || b.kind === "override" || b.kind === "shield" && shieldAllowed
|
|
573
694
|
);
|
|
574
695
|
const featTerms = featureAcTermsFor(false);
|
|
575
696
|
const additiveSum = additive.reduce((sum, b) => sum + b.amount, 0);
|
|
@@ -583,16 +704,16 @@ function recalc(resolved, registry) {
|
|
|
583
704
|
acDerived = total + sumTerms(featTerms);
|
|
584
705
|
acBreakdownDerived = [...terms, ...featTerms];
|
|
585
706
|
}
|
|
586
|
-
const ac = (
|
|
707
|
+
const ac = (_C = overrides.ac) != null ? _C : acDerived;
|
|
587
708
|
const additiveSpeed = speedFromRace(resolved) + applied.speed_bonuses.walk + featureEffects.speed_walk_bonus;
|
|
588
709
|
const baseSpeed = Math.max(featureEffects.speed_walk_set, additiveSpeed);
|
|
589
710
|
const adjustedSpeed = baseSpeed * conditionEffects.speed_multiplier - conditionEffects.speed_reduction_ft;
|
|
590
711
|
const conditionSpeed = conditionEffects.speed_floor_zero ? 0 : Math.max(0, Math.floor(adjustedSpeed));
|
|
591
|
-
const speed = (
|
|
712
|
+
const speed = (_D = overrides.speed) != null ? _D : conditionSpeed;
|
|
592
713
|
if (!resolved.race) warnings.push("No race resolved; speed defaulted to 30.");
|
|
593
|
-
const init = (
|
|
714
|
+
const init = (_E = overrides.initiative) != null ? _E : initiativeBonus(mods.dex, resolved.feats, resolved.definition.edition) + featureEffects.initiative_bonus;
|
|
594
715
|
const senses = {
|
|
595
|
-
darkvision: Math.max((
|
|
716
|
+
darkvision: Math.max((_H = (_G = (_F = resolved.race) == null ? void 0 : _F.vision) == null ? void 0 : _G.darkvision) != null ? _H : 0, featureEffects.senses.darkvision, applied.senses.darkvision),
|
|
596
717
|
blindsight: Math.max(featureEffects.senses.blindsight, applied.senses.blindsight),
|
|
597
718
|
tremorsense: Math.max(featureEffects.senses.tremorsense, applied.senses.tremorsense),
|
|
598
719
|
truesight: Math.max(featureEffects.senses.truesight, applied.senses.truesight)
|
|
@@ -615,7 +736,8 @@ function recalc(resolved, registry) {
|
|
|
615
736
|
saveDC: dc,
|
|
616
737
|
attackBonus: atk,
|
|
617
738
|
casterType: profile.casterType,
|
|
618
|
-
preparation: profile.preparation
|
|
739
|
+
preparation: profile.preparation,
|
|
740
|
+
spellList: profile.spellList
|
|
619
741
|
});
|
|
620
742
|
slotInputs.push({ casterType: profile.casterType, level: c.level });
|
|
621
743
|
limitInputs.push({ classSlug: c.entity.slug, level: c.level, profile, abilityScore: scores[ab] });
|
|
@@ -637,24 +759,39 @@ function recalc(resolved, registry) {
|
|
|
637
759
|
const derivedSlots = deriveSpellSlots(slotInputs);
|
|
638
760
|
const spellLimits = computeSpellLimits(limitInputs);
|
|
639
761
|
const defenses = {
|
|
640
|
-
resistances:
|
|
641
|
-
(
|
|
762
|
+
resistances: suppress(resolved, "resistances", composeDefenseEntries(
|
|
763
|
+
(_J = (_I = resolved.definition.defenses) == null ? void 0 : _I.resistances) != null ? _J : [],
|
|
642
764
|
applied.defenses.resistances,
|
|
643
765
|
featureEffects.resistances
|
|
644
|
-
|
|
645
|
-
immunities:
|
|
646
|
-
(
|
|
647
|
-
applied.defenses.immunities
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
766
|
+
)),
|
|
767
|
+
immunities: suppress(resolved, "immunities", composeDefenseEntries(
|
|
768
|
+
(_L = (_K = resolved.definition.defenses) == null ? void 0 : _K.immunities) != null ? _L : [],
|
|
769
|
+
applied.defenses.immunities,
|
|
770
|
+
featureEffects.immunities
|
|
771
|
+
)),
|
|
772
|
+
vulnerabilities: suppress(resolved, "vulnerabilities", composeDefenseEntries(
|
|
773
|
+
(_N = (_M = resolved.definition.defenses) == null ? void 0 : _M.vulnerabilities) != null ? _N : [],
|
|
774
|
+
applied.defenses.vulnerabilities,
|
|
775
|
+
featureEffects.vulnerabilities
|
|
776
|
+
)),
|
|
777
|
+
condition_immunities: suppress(resolved, "condition_immunities", composeDefenseEntries(
|
|
778
|
+
(_P = (_O = resolved.definition.defenses) == null ? void 0 : _O.condition_immunities) != null ? _P : [],
|
|
655
779
|
applied.defenses.condition_immunities,
|
|
656
780
|
featureEffects.condition_immunities
|
|
657
|
-
|
|
781
|
+
))
|
|
782
|
+
};
|
|
783
|
+
const attackRows = [...(_Q = derivedEquipment == null ? void 0 : derivedEquipment.attacks) != null ? _Q : [], buildUnarmedRow(mods, proficiencyBonus, resolveUnarmedStrike(resolved))];
|
|
784
|
+
const riderBindings = {
|
|
785
|
+
level: totalLevel,
|
|
786
|
+
class_level: totalLevel,
|
|
787
|
+
prof: proficiencyBonus,
|
|
788
|
+
str_mod: mods.str,
|
|
789
|
+
dex_mod: mods.dex,
|
|
790
|
+
con_mod: mods.con,
|
|
791
|
+
int_mod: mods.int,
|
|
792
|
+
wis_mod: mods.wis,
|
|
793
|
+
cha_mod: mods.cha,
|
|
794
|
+
columns: {}
|
|
658
795
|
};
|
|
659
796
|
return {
|
|
660
797
|
totalLevel,
|
|
@@ -695,9 +832,9 @@ function recalc(resolved, registry) {
|
|
|
695
832
|
// untouched rows keep `critRange`/`attackNotes` ABSENT (not 20 / not []).
|
|
696
833
|
// crit-range: folded weapon crit threshold, only when an effect lowered it.
|
|
697
834
|
// attackNotes: reroll-damage / attack-rule captions, only when non-empty.
|
|
698
|
-
attacks:
|
|
835
|
+
attacks: attackRows.map((a) => {
|
|
699
836
|
var _a2;
|
|
700
|
-
const riders = [...(_a2 = a.damageRiders) != null ? _a2 : [], ...featureEffects.damageBonuses];
|
|
837
|
+
const riders = [...(_a2 = a.damageRiders) != null ? _a2 : [], ...featureEffects.damageBonuses].map((r) => resolveDamageRider(r, a.damageType, riderBindings));
|
|
701
838
|
return {
|
|
702
839
|
...a,
|
|
703
840
|
toHit: a.toHit + conditionEffects.d20_test_penalty,
|
|
@@ -706,12 +843,13 @@ function recalc(resolved, registry) {
|
|
|
706
843
|
...riders.length ? { damageRiders: riders } : {}
|
|
707
844
|
};
|
|
708
845
|
}),
|
|
709
|
-
equippedSlots: (
|
|
710
|
-
carriedWeight: (
|
|
711
|
-
attunementUsed: (
|
|
712
|
-
attunementLimit: (
|
|
846
|
+
equippedSlots: (_R = derivedEquipment == null ? void 0 : derivedEquipment.equippedSlots) != null ? _R : {},
|
|
847
|
+
carriedWeight: (_S = derivedEquipment == null ? void 0 : derivedEquipment.carriedWeight) != null ? _S : 0,
|
|
848
|
+
attunementUsed: (_T = derivedEquipment == null ? void 0 : derivedEquipment.attunementUsed) != null ? _T : 0,
|
|
849
|
+
attunementLimit: (_V = derivedEquipment == null ? void 0 : derivedEquipment.attunementLimit) != null ? _V : (_U = overrides.attunement_limit) != null ? _U : Math.max(3, featureEffects.attunement_set),
|
|
713
850
|
conditionEffects,
|
|
714
|
-
rollModifiers: featureEffects.rollModifiers
|
|
851
|
+
rollModifiers: featureEffects.rollModifiers,
|
|
852
|
+
saveOutcomes: featureEffects.saveOutcomes
|
|
715
853
|
};
|
|
716
854
|
}
|
|
717
855
|
export {
|
|
@@ -728,6 +866,7 @@ export {
|
|
|
728
866
|
parseDieSize,
|
|
729
867
|
phbAverageForDie,
|
|
730
868
|
recalc,
|
|
869
|
+
resolveUnarmedStrike,
|
|
731
870
|
speedFromRace,
|
|
732
871
|
unarmoredAC,
|
|
733
872
|
unarmoredACBreakdown
|