@archivist-gg/dnd5e 0.3.1 → 0.3.4
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-4FWNK4FD.js +159 -0
- 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-5U5FFFA3.js} +5 -1
- package/dist/{chunk-4F6AIZ36.js → chunk-5XMQPTHD.js} +1 -1
- package/dist/{chunk-GJOI2GHP.js → chunk-6GNXYAYP.js} +1 -1
- package/dist/chunk-6PKV5V2H.js +178 -0
- 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-CJYCVNW2.js +7 -0
- package/dist/chunk-COEOOQX2.js +133 -0
- package/dist/{chunk-XTIQWSFM.js → chunk-D5U7GMPX.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-73HOFQQ5.js → chunk-ESS46GR4.js} +1 -1
- package/dist/chunk-EVMUJYUD.js +195 -0
- package/dist/{chunk-2BWAID3Y.js → chunk-FDBWYMZK.js} +29 -3
- package/dist/{chunk-K6Q5OUGK.js → chunk-GFZ7PITJ.js} +86 -10
- package/dist/chunk-H7KBLR4X.js +81 -0
- package/dist/{chunk-L7E2UT5A.js → chunk-HB7XZXDK.js} +5 -1
- package/dist/{chunk-BIK4DFWK.js → chunk-HJ5EEZ47.js} +1 -1
- package/dist/{chunk-6NK2MUD3.js → chunk-HZA7OE7N.js} +9 -2
- package/dist/{chunk-TN6ZLTNU.js → chunk-I2NDWFDD.js} +51 -4
- package/dist/{chunk-RSDRMH54.js → chunk-IMZFOOVL.js} +1 -1
- package/dist/{chunk-3DZ74AKK.js → chunk-IN4M4X7P.js} +8 -2
- package/dist/chunk-IUAAXXNO.js +58 -0
- package/dist/{chunk-XJNECUPT.js → chunk-JC5UNIVM.js} +19 -0
- package/dist/chunk-JJ46T5XX.js +297 -0
- package/dist/{chunk-SE7AZDR3.js → chunk-JRDPUDT5.js} +29 -3
- package/dist/{chunk-24GFQU7T.js → chunk-JSZ4H6AQ.js} +1 -1
- package/dist/chunk-KU3YLF6D.js +106 -0
- package/dist/{chunk-5INR4NSL.js → chunk-LDDCNPHD.js} +1 -1
- package/dist/{chunk-5ZBE4CWV.js → chunk-LMBAEIP6.js} +1 -1
- package/dist/chunk-LVQLWRCU.js +15 -0
- package/dist/chunk-MI7P3NX3.js +161 -0
- package/dist/chunk-O4SRD3J5.js +165 -0
- package/dist/{chunk-D3CLOBE3.js → chunk-OSQFPGLM.js} +44 -8
- 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-XLSVNUTK.js → chunk-R3VAKWKW.js} +1 -1
- package/dist/chunk-RIXI5D3R.js +89 -0
- package/dist/chunk-RLGQ5PZZ.js +16 -0
- package/dist/chunk-S7REMWW4.js +21 -0
- package/dist/{chunk-7VJ6BOA5.js → chunk-SMLXZUBH.js} +9 -1
- package/dist/{chunk-NXSWH3AE.js → chunk-T26ZVCL5.js} +1 -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-GE4TLPWM.js → chunk-US5IKYCW.js} +1 -1
- package/dist/chunk-UXPGW4TI.js +101 -0
- package/dist/chunk-VQAXTIBW.js +100 -0
- package/dist/{chunk-WP2CX2JO.js → chunk-WELIKLZF.js} +22 -1
- package/dist/chunk-WPWOHGPI.js +172 -0
- package/dist/{chunk-GZ46OVGZ.js → chunk-WSVMLNTO.js} +1 -1
- package/dist/{chunk-4LZJXJJS.js → chunk-WXWPK3LI.js} +6 -2
- package/dist/{chunk-ZZGEVJKX.js → chunk-XBQMCEI2.js} +1 -1
- package/dist/{chunk-PHQRGDRQ.js → chunk-XGOFP7AQ.js} +5 -1
- package/dist/chunk-XJ2F2WO6.js +8 -0
- package/dist/chunk-XQCSGNXE.js +1580 -0
- package/dist/chunk-YBLDE5CG.js +42 -0
- package/dist/{chunk-JEYQU3JT.js → chunk-YHYTW5QA.js} +2 -18
- package/dist/{chunk-TLYDBT5F.js → chunk-YJJTISBN.js} +64 -7
- package/dist/{chunk-PZOWBI3B.js → chunk-YLL2QXY2.js} +7 -2
- package/dist/{chunk-MDEJHMKK.js → chunk-ZONJ66NE.js} +26 -5
- 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 +230 -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 +176 -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 +30 -1
- package/dist/pc/pc.equipment.js +12 -8
- package/dist/pc/pc.feature-effects.d.ts +225 -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 +124 -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 +78 -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
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// src/types/choice.ts
|
|
2
|
+
var ALL_SKILL_SLUGS = [
|
|
3
|
+
"acrobatics",
|
|
4
|
+
"animal-handling",
|
|
5
|
+
"arcana",
|
|
6
|
+
"athletics",
|
|
7
|
+
"deception",
|
|
8
|
+
"history",
|
|
9
|
+
"insight",
|
|
10
|
+
"intimidation",
|
|
11
|
+
"investigation",
|
|
12
|
+
"medicine",
|
|
13
|
+
"nature",
|
|
14
|
+
"perception",
|
|
15
|
+
"performance",
|
|
16
|
+
"persuasion",
|
|
17
|
+
"religion",
|
|
18
|
+
"sleight-of-hand",
|
|
19
|
+
"stealth",
|
|
20
|
+
"survival"
|
|
21
|
+
];
|
|
22
|
+
var STANDARD_LANGUAGES = [
|
|
23
|
+
"common",
|
|
24
|
+
"dwarvish",
|
|
25
|
+
"elvish",
|
|
26
|
+
"giant",
|
|
27
|
+
"gnomish",
|
|
28
|
+
"goblin",
|
|
29
|
+
"halfling",
|
|
30
|
+
"orc"
|
|
31
|
+
];
|
|
32
|
+
var EXOTIC_LANGUAGES = [
|
|
33
|
+
"abyssal",
|
|
34
|
+
"celestial",
|
|
35
|
+
"deep-speech",
|
|
36
|
+
"draconic",
|
|
37
|
+
"infernal",
|
|
38
|
+
"primordial",
|
|
39
|
+
"sylvan",
|
|
40
|
+
"undercommon"
|
|
41
|
+
];
|
|
42
|
+
var SECRET_LANGUAGES = ["druidic", "thieves'-cant"];
|
|
43
|
+
var ALL_LANGUAGES = [
|
|
44
|
+
...STANDARD_LANGUAGES,
|
|
45
|
+
...EXOTIC_LANGUAGES,
|
|
46
|
+
...SECRET_LANGUAGES
|
|
47
|
+
];
|
|
48
|
+
var ARTISANS_TOOLS = [
|
|
49
|
+
"alchemist's-supplies",
|
|
50
|
+
"brewer's-supplies",
|
|
51
|
+
"calligrapher's-supplies",
|
|
52
|
+
"carpenter's-tools",
|
|
53
|
+
"cartographer's-tools",
|
|
54
|
+
"cobbler's-tools",
|
|
55
|
+
"cook's-utensils",
|
|
56
|
+
"glassblower's-tools",
|
|
57
|
+
"jeweler's-tools",
|
|
58
|
+
"leatherworker's-tools",
|
|
59
|
+
"mason's-tools",
|
|
60
|
+
"painter's-supplies",
|
|
61
|
+
"potter's-tools",
|
|
62
|
+
"smith's-tools",
|
|
63
|
+
"tinker's-tools",
|
|
64
|
+
"weaver's-tools",
|
|
65
|
+
"woodcarver's-tools"
|
|
66
|
+
];
|
|
67
|
+
var MUSICAL_INSTRUMENTS = [
|
|
68
|
+
"bagpipes",
|
|
69
|
+
"drum",
|
|
70
|
+
"dulcimer",
|
|
71
|
+
"flute",
|
|
72
|
+
"horn",
|
|
73
|
+
"lute",
|
|
74
|
+
"lyre",
|
|
75
|
+
"pan-flute",
|
|
76
|
+
"shawm",
|
|
77
|
+
"viol"
|
|
78
|
+
];
|
|
79
|
+
var GAMING_SETS = ["dice-set", "playing-cards"];
|
|
80
|
+
var OTHER_TOOLS = [
|
|
81
|
+
"disguise-kit",
|
|
82
|
+
"forgery-kit",
|
|
83
|
+
"herbalism-kit",
|
|
84
|
+
"navigator's-tools",
|
|
85
|
+
"poisoner's-kit",
|
|
86
|
+
"thieves'-tools"
|
|
87
|
+
];
|
|
88
|
+
var ALL_TOOLS = [
|
|
89
|
+
...ARTISANS_TOOLS,
|
|
90
|
+
...MUSICAL_INSTRUMENTS,
|
|
91
|
+
...GAMING_SETS,
|
|
92
|
+
...OTHER_TOOLS
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
ALL_SKILL_SLUGS,
|
|
97
|
+
STANDARD_LANGUAGES,
|
|
98
|
+
EXOTIC_LANGUAGES,
|
|
99
|
+
SECRET_LANGUAGES,
|
|
100
|
+
ALL_LANGUAGES,
|
|
101
|
+
ARTISANS_TOOLS,
|
|
102
|
+
MUSICAL_INSTRUMENTS,
|
|
103
|
+
GAMING_SETS,
|
|
104
|
+
OTHER_TOOLS,
|
|
105
|
+
ALL_TOOLS
|
|
106
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/dnd/warn-once.ts
|
|
2
|
+
var seen = /* @__PURE__ */ new Set();
|
|
3
|
+
function warnOnce(key, msg) {
|
|
4
|
+
if (seen.has(key)) return;
|
|
5
|
+
seen.add(key);
|
|
6
|
+
console.warn(msg);
|
|
7
|
+
}
|
|
8
|
+
function __resetWarnOnceForTests() {
|
|
9
|
+
seen.clear();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
warnOnce,
|
|
14
|
+
__resetWarnOnceForTests
|
|
15
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RACE_STRUCTURAL_PSEUDO
|
|
3
|
+
} from "./chunk-PVCEA4HZ.js";
|
|
4
|
+
import {
|
|
5
|
+
warnOnce
|
|
6
|
+
} from "./chunk-LVQLWRCU.js";
|
|
7
|
+
import {
|
|
8
|
+
slugify
|
|
9
|
+
} from "./chunk-6X4KUDMU.js";
|
|
10
|
+
import {
|
|
11
|
+
mirrorSpellShapes
|
|
12
|
+
} from "./chunk-OZP6JFGT.js";
|
|
13
|
+
import {
|
|
14
|
+
ABILITY_KEYS
|
|
15
|
+
} from "./chunk-WELIKLZF.js";
|
|
16
|
+
|
|
17
|
+
// src/pc/pc.additional-spells.ts
|
|
18
|
+
var entriesOf = (a) => Array.isArray(a) ? a : a && typeof a === "object" ? [a] : [];
|
|
19
|
+
var editionOf = (x) => {
|
|
20
|
+
const e = x == null ? void 0 : x.edition;
|
|
21
|
+
return typeof e === "string" ? e : void 0;
|
|
22
|
+
};
|
|
23
|
+
var prefixOf = (slug) => {
|
|
24
|
+
var _a;
|
|
25
|
+
return (_a = slug.split("_")[0]) != null ? _a : slug;
|
|
26
|
+
};
|
|
27
|
+
function normalizeSpellRef(ref) {
|
|
28
|
+
var _a, _b, _c;
|
|
29
|
+
if (typeof ref !== "string") return null;
|
|
30
|
+
let s = ref.trim();
|
|
31
|
+
const wl = /^\[\[(.+)\]\]$/.exec(s);
|
|
32
|
+
if (wl) {
|
|
33
|
+
const target = (_a = wl[1].split("|")[0]) != null ? _a : "";
|
|
34
|
+
const tail = (_b = target.split("/").pop()) != null ? _b : target;
|
|
35
|
+
const w = slugify(tail.replace(/#.*$/, "").trim());
|
|
36
|
+
return w.length > 0 ? w : null;
|
|
37
|
+
}
|
|
38
|
+
s = s.replace(/#.*$/, "");
|
|
39
|
+
s = (_c = s.split("|")[0]) != null ? _c : "";
|
|
40
|
+
const out = slugify(s.trim());
|
|
41
|
+
return out.length > 0 ? out : null;
|
|
42
|
+
}
|
|
43
|
+
function buildSpellNameIndex(entities) {
|
|
44
|
+
var _a;
|
|
45
|
+
const byName = /* @__PURE__ */ new Map();
|
|
46
|
+
for (const e of entities.search("", "spell", Number.POSITIVE_INFINITY)) {
|
|
47
|
+
const raw = e.data.name;
|
|
48
|
+
const key = slugify(typeof raw === "string" ? raw : e.name);
|
|
49
|
+
const list = (_a = byName.get(key)) != null ? _a : [];
|
|
50
|
+
list.push(e);
|
|
51
|
+
byName.set(key, list);
|
|
52
|
+
}
|
|
53
|
+
return { byName };
|
|
54
|
+
}
|
|
55
|
+
function resolveSpellByName(opts) {
|
|
56
|
+
var _a;
|
|
57
|
+
const { entities, index, nameSlug, carrierSlug, carrierEdition, alreadyCollected } = opts;
|
|
58
|
+
const own = alreadyCollected.find((s) => {
|
|
59
|
+
var _a2;
|
|
60
|
+
return slugify(String((_a2 = s.entity.name) != null ? _a2 : "")) === nameSlug;
|
|
61
|
+
});
|
|
62
|
+
if (own) return { entity: own.entity, slug: own.slug };
|
|
63
|
+
const exact = entities.getByTypeAndSlug("spell", `${prefixOf(carrierSlug)}_spell_${nameSlug}`);
|
|
64
|
+
if (exact) return { entity: mirrorSpellShapes(exact.data), slug: exact.slug };
|
|
65
|
+
const cands = (_a = index.byName.get(nameSlug)) != null ? _a : [];
|
|
66
|
+
if (cands.length === 0) {
|
|
67
|
+
warnOnce(`addspells:miss:${nameSlug}`, `archivist: additional_spells ref "${nameSlug}" matches no spell in the compendium`);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const prefix = prefixOf(carrierSlug);
|
|
71
|
+
let pool = cands.filter((e) => prefixOf(e.slug) === prefix);
|
|
72
|
+
if (pool.length === 0) pool = cands;
|
|
73
|
+
if (carrierEdition !== void 0) {
|
|
74
|
+
const same = pool.filter((e) => editionOf(e.data) === carrierEdition);
|
|
75
|
+
if (same.length > 0) pool = same;
|
|
76
|
+
}
|
|
77
|
+
pool = [...pool].sort((a, b) => a.slug < b.slug ? -1 : a.slug > b.slug ? 1 : 0);
|
|
78
|
+
if (pool.length > 1) warnOnce(`addspells:multi:${nameSlug}`, `archivist: additional_spells ref "${nameSlug}" matches ${cands.length} spells; using "${pool[0].slug}"`);
|
|
79
|
+
return { entity: mirrorSpellShapes(pool[0].data), slug: pool[0].slug };
|
|
80
|
+
}
|
|
81
|
+
var hasContentSelectInline = (choices) => Array.isArray(choices) && choices.some((c) => (c == null ? void 0 : c.kind) === "select-inline" && typeof c.id === "string" && !RACE_STRUCTURAL_PSEUDO.has(c.id) || Array.isArray(c == null ? void 0 : c.options) && c.options.some((o) => hasContentSelectInline(o == null ? void 0 : o.choices)));
|
|
82
|
+
function raceIsUngated(race) {
|
|
83
|
+
var _a;
|
|
84
|
+
const r = race;
|
|
85
|
+
if (hasContentSelectInline(r.choices)) return false;
|
|
86
|
+
return !((_a = r.traits) != null ? _a : []).some((t) => hasContentSelectInline(t == null ? void 0 : t.choices));
|
|
87
|
+
}
|
|
88
|
+
var readAbility = (v, own) => {
|
|
89
|
+
if (v && typeof v === "object" && "choose" in v) return "choose";
|
|
90
|
+
if (typeof v !== "string") return void 0;
|
|
91
|
+
if (v === "inherit") return own != null ? own : void 0;
|
|
92
|
+
return ABILITY_KEYS.includes(v) ? v : void 0;
|
|
93
|
+
};
|
|
94
|
+
var entryHasInSliceLeaf = (e, comparand, own) => readAbility(e.ability, own) !== "choose" && ["known", "prepared"].some((b) => {
|
|
95
|
+
const lv = e[b];
|
|
96
|
+
return !!lv && typeof lv === "object" && !Array.isArray(lv) && Object.entries(lv).some(([k, v]) => (k === "_" || Number(k) <= comparand) && Array.isArray(v) && v.some((x) => typeof x === "string"));
|
|
97
|
+
});
|
|
98
|
+
function collectAdditionalSpells(args) {
|
|
99
|
+
const { race, feats, classes, totalLevel, ownAbility, alreadyCollected, entities, warnings } = args;
|
|
100
|
+
let index = null;
|
|
101
|
+
const indexOf = () => index != null ? index : index = buildSpellNameIndex(entities);
|
|
102
|
+
const out = [];
|
|
103
|
+
const carriers = [];
|
|
104
|
+
const asRaw = (x) => x == null ? void 0 : x.additional_spells;
|
|
105
|
+
if (race && raceIsUngated(race)) carriers.push({ root: "race", slug: race.slug, edition: editionOf(race), entries: entriesOf(asRaw(race)), comparand: totalLevel, classSlug: null });
|
|
106
|
+
for (const f of feats) carriers.push({ root: "feat", slug: f.slug, edition: editionOf(f), entries: entriesOf(asRaw(f)), comparand: totalLevel, classSlug: null });
|
|
107
|
+
for (const c of classes) {
|
|
108
|
+
if (!c.entity) continue;
|
|
109
|
+
carriers.push({ root: "class", slug: c.entity.slug, edition: editionOf(c.entity), entries: entriesOf(asRaw(c.entity)), comparand: c.level, classSlug: c.entity.slug });
|
|
110
|
+
if (c.subclass) carriers.push({ root: "subclass", slug: c.subclass.slug, edition: editionOf(c.subclass), entries: entriesOf(asRaw(c.subclass)), comparand: c.level, classSlug: c.entity.slug });
|
|
111
|
+
}
|
|
112
|
+
for (const car of carriers) {
|
|
113
|
+
if (car.entries.length === 0) continue;
|
|
114
|
+
if (car.entries.length > 1) {
|
|
115
|
+
if (car.entries.some((e) => entryHasInSliceLeaf(e, car.comparand, ownAbility))) warnOnce(`addspells:siblings:${car.slug}`, `archivist: additional_spells on "${car.slug}" has ${car.entries.length} sibling entries (a choose-one grant); skipped`);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const entry = car.entries[0];
|
|
119
|
+
const ability = readAbility(entry.ability, ownAbility);
|
|
120
|
+
if (ability === "choose") continue;
|
|
121
|
+
for (const bucket of ["known", "prepared"]) {
|
|
122
|
+
const levels = entry[bucket];
|
|
123
|
+
if (!levels || typeof levels !== "object" || Array.isArray(levels)) continue;
|
|
124
|
+
for (const [k, v] of Object.entries(levels)) {
|
|
125
|
+
if (!(k === "_" || Number(k) <= car.comparand)) continue;
|
|
126
|
+
if (!Array.isArray(v)) {
|
|
127
|
+
warnOnce(`addspells:usage:${car.slug}:${bucket}:${k}`, `archivist: additional_spells on "${car.slug}" ${bucket}.${k} is a usage economy (skipped; G8)`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
for (const leaf of v) {
|
|
131
|
+
const nameSlug = normalizeSpellRef(leaf);
|
|
132
|
+
if (!nameSlug) continue;
|
|
133
|
+
const hit = resolveSpellByName({ entities, index: indexOf(), nameSlug, carrierSlug: car.slug, carrierEdition: car.edition, alreadyCollected: [...alreadyCollected, ...out] });
|
|
134
|
+
if (!hit) {
|
|
135
|
+
warnings.push(`additional_spells ref "${String(leaf)}" on ${car.slug} not found in compendium.`);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
out.push({
|
|
139
|
+
entity: hit.entity,
|
|
140
|
+
slug: hit.slug,
|
|
141
|
+
classSlug: car.classSlug,
|
|
142
|
+
source: car.root === "race" ? "race" : car.root === "feat" ? "feat" : "class",
|
|
143
|
+
prepared: true,
|
|
144
|
+
alwaysPrepared: true,
|
|
145
|
+
...ability ? { ability } : {}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return out;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
prefixOf,
|
|
156
|
+
normalizeSpellRef,
|
|
157
|
+
buildSpellNameIndex,
|
|
158
|
+
resolveSpellByName,
|
|
159
|
+
raceIsUngated,
|
|
160
|
+
collectAdditionalSpells
|
|
161
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import {
|
|
2
|
+
derivePoolLayout
|
|
3
|
+
} from "./chunk-PP2UHLBA.js";
|
|
4
|
+
import {
|
|
5
|
+
readTableColumn
|
|
6
|
+
} from "./chunk-IUAAXXNO.js";
|
|
7
|
+
import {
|
|
8
|
+
warnOnce
|
|
9
|
+
} from "./chunk-LVQLWRCU.js";
|
|
10
|
+
import {
|
|
11
|
+
bareEntitySlug,
|
|
12
|
+
wikilinkTailSlug
|
|
13
|
+
} from "./chunk-6X4KUDMU.js";
|
|
14
|
+
|
|
15
|
+
// src/pc/pc.pools.ts
|
|
16
|
+
function levelPrereqMax(d) {
|
|
17
|
+
var _a;
|
|
18
|
+
return ((_a = d.prerequisites) != null ? _a : []).filter((p) => p.kind === "level").reduce((m, p) => Math.max(m, p.min), 0);
|
|
19
|
+
}
|
|
20
|
+
function resolvePool(rc, classIndex, pool, registry, index) {
|
|
21
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
22
|
+
const entity = rc.entity;
|
|
23
|
+
const level = rc.level;
|
|
24
|
+
const ownerBare = bareEntitySlug(entity.slug);
|
|
25
|
+
const ownerPrefix = entity.slug.split("_")[0];
|
|
26
|
+
const col = pool.count.column;
|
|
27
|
+
const count = (_a = readTableColumn(entity.table, level, [col])) != null ? _a : 0;
|
|
28
|
+
let anchorLevel = 1;
|
|
29
|
+
let columnSeen = false;
|
|
30
|
+
for (let l = 1; l <= 20; l++) {
|
|
31
|
+
const c = readTableColumn(entity.table, l, [col]);
|
|
32
|
+
if (c != null) columnSeen = true;
|
|
33
|
+
if (c != null && c >= 1) {
|
|
34
|
+
anchorLevel = l;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (!columnSeen) {
|
|
39
|
+
warnOnce(
|
|
40
|
+
`pool-column:${pool.id}`,
|
|
41
|
+
`Archivist: pool "${pool.id}" declares count column "${col}", which "${entity.slug}"'s class table carries at no level; the pool resolves count 0 at anchor level 1`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const ft = pool.source.where.feature_type;
|
|
45
|
+
const all = registry.search("", "optional-feature", Number.POSITIVE_INFINITY).slice().sort((a, b) => a.name.localeCompare(b.name) || a.slug.localeCompare(b.slug));
|
|
46
|
+
const byBare = /* @__PURE__ */ new Map();
|
|
47
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
48
|
+
for (const e of all) {
|
|
49
|
+
const d = e.data;
|
|
50
|
+
const entry = { slug: e.slug, entity: d, ...e.compendium ? { compendium: e.compendium } : {} };
|
|
51
|
+
const bare = bareEntitySlug(e.slug);
|
|
52
|
+
byBare.set(bare, entry);
|
|
53
|
+
if (d.feature_type !== ft) continue;
|
|
54
|
+
if (!((_b = d.available_to) != null ? _b : []).some((l) => wikilinkTailSlug(l) === ownerBare)) continue;
|
|
55
|
+
if (levelPrereqMax(d) > level) continue;
|
|
56
|
+
const group = candidates.get(bare);
|
|
57
|
+
if (group) group.push(entry);
|
|
58
|
+
else candidates.set(bare, [entry]);
|
|
59
|
+
}
|
|
60
|
+
const available = [];
|
|
61
|
+
for (const [bare, group] of candidates) {
|
|
62
|
+
if (group.length === 1) {
|
|
63
|
+
available.push(group[0]);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const owned = group.find((e) => e.slug.split("_")[0] === ownerPrefix);
|
|
67
|
+
if (!owned) {
|
|
68
|
+
warnOnce(
|
|
69
|
+
`pool-collapse:${bare}`,
|
|
70
|
+
`Archivist: pool "${pool.id}" holds ${group.length} cross-edition entries for "${bare}" and none shares the owner's compendium prefix "${ownerPrefix}"; keeping "${group[0].slug}"`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
available.push(owned != null ? owned : group[0]);
|
|
74
|
+
}
|
|
75
|
+
const grantDecls = [
|
|
76
|
+
...(_d = (_c = rc.entity) == null ? void 0 : _c.pool_grants) != null ? _d : [],
|
|
77
|
+
...(_f = (_e = rc.subclass) == null ? void 0 : _e.pool_grants) != null ? _f : []
|
|
78
|
+
];
|
|
79
|
+
const grantsRaw = grantDecls.filter((g) => g.pool === pool.id).flatMap((g) => g.grants).filter((g) => g.at_level <= level).map((g) => byBare.get(wikilinkTailSlug(g.feature))).filter((e) => e != null);
|
|
80
|
+
const grantedBare = /* @__PURE__ */ new Set();
|
|
81
|
+
const grants = grantsRaw.filter((e) => {
|
|
82
|
+
const key = bareEntitySlug(e.slug);
|
|
83
|
+
if (grantedBare.has(key)) return false;
|
|
84
|
+
grantedBare.add(key);
|
|
85
|
+
return true;
|
|
86
|
+
});
|
|
87
|
+
const bySlugAvailable = new Map(available.map((e) => [e.slug, e]));
|
|
88
|
+
const byBareAvailable = new Map(available.map((e) => [bareEntitySlug(e.slug), e]));
|
|
89
|
+
const resolveStored = (s) => {
|
|
90
|
+
const exact = bySlugAvailable.get(s);
|
|
91
|
+
if (exact) return exact;
|
|
92
|
+
const survivor = byBareAvailable.get(bareEntitySlug(s));
|
|
93
|
+
if (survivor) return survivor;
|
|
94
|
+
const full = registry.getByTypeAndSlug("optional-feature", s);
|
|
95
|
+
if (full) {
|
|
96
|
+
const d = full.data;
|
|
97
|
+
return { slug: full.slug, entity: d, ...full.compendium ? { compendium: full.compendium } : {} };
|
|
98
|
+
}
|
|
99
|
+
return byBare.get(bareEntitySlug(s));
|
|
100
|
+
};
|
|
101
|
+
const raw = (_g = rc.choices[anchorLevel]) == null ? void 0 : _g[pool.id];
|
|
102
|
+
const selectedSlugs = Array.isArray(raw) ? raw : typeof raw === "string" ? [raw] : [];
|
|
103
|
+
const selected = [];
|
|
104
|
+
const seenBare = /* @__PURE__ */ new Set();
|
|
105
|
+
for (const s of selectedSlugs) {
|
|
106
|
+
const entry = resolveStored(s);
|
|
107
|
+
if (!entry) continue;
|
|
108
|
+
const bare = bareEntitySlug(entry.slug);
|
|
109
|
+
if (grantedBare.has(bare) || seenBare.has(bare)) continue;
|
|
110
|
+
seenBare.add(bare);
|
|
111
|
+
selected.push(entry);
|
|
112
|
+
}
|
|
113
|
+
const members = [...available, ...grants];
|
|
114
|
+
const layout = derivePoolLayout(members);
|
|
115
|
+
const votes = /* @__PURE__ */ new Map();
|
|
116
|
+
for (const e of members) {
|
|
117
|
+
const id = (_h = e.entity.consumes) == null ? void 0 : _h.resource;
|
|
118
|
+
if (!id || !index.has(id)) continue;
|
|
119
|
+
votes.set(id, ((_i = votes.get(id)) != null ? _i : 0) + 1);
|
|
120
|
+
}
|
|
121
|
+
let resource;
|
|
122
|
+
let bestN = 0;
|
|
123
|
+
for (const [id, n] of votes) if (n > bestN) {
|
|
124
|
+
resource = id;
|
|
125
|
+
bestN = n;
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
id: pool.id,
|
|
129
|
+
label: pool.label,
|
|
130
|
+
classIndex,
|
|
131
|
+
count,
|
|
132
|
+
anchorLevel,
|
|
133
|
+
selected,
|
|
134
|
+
available,
|
|
135
|
+
grants,
|
|
136
|
+
...layout ? { layout } : {},
|
|
137
|
+
...resource ? { resource } : {}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function resolveAllPools(resolved, registry, index) {
|
|
141
|
+
const out = [];
|
|
142
|
+
resolved.classes.forEach((rc, classIndex) => {
|
|
143
|
+
var _a, _b, _c;
|
|
144
|
+
if (!rc.entity) return;
|
|
145
|
+
const decls = [...(_a = rc.entity.selection_pools) != null ? _a : [], ...(_c = (_b = rc.subclass) == null ? void 0 : _b.selection_pools) != null ? _c : []];
|
|
146
|
+
const seen = /* @__PURE__ */ new Set();
|
|
147
|
+
for (const pool of decls) {
|
|
148
|
+
if (seen.has(pool.id)) continue;
|
|
149
|
+
seen.add(pool.id);
|
|
150
|
+
out.push(resolvePool(rc, classIndex, pool, registry, index));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
function strandedPicks(pool) {
|
|
156
|
+
const inAvailable = new Set(pool.available.map((e) => e.slug));
|
|
157
|
+
return pool.selected.filter((e) => !inAvailable.has(e.slug));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export {
|
|
161
|
+
levelPrereqMax,
|
|
162
|
+
resolvePool,
|
|
163
|
+
resolveAllPools,
|
|
164
|
+
strandedPicks
|
|
165
|
+
};
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
classifyWeaponRange
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import {
|
|
5
|
-
normKey
|
|
6
|
-
} from "./chunk-O5EYMKFH.js";
|
|
3
|
+
} from "./chunk-UIRMA5KM.js";
|
|
7
4
|
import {
|
|
8
5
|
defaultSlotForType,
|
|
9
6
|
effectiveArmor,
|
|
10
7
|
isItemEntity,
|
|
11
8
|
isWeaponEntity,
|
|
12
9
|
resolveEntityForEntry
|
|
13
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UBBKSYBY.js";
|
|
11
|
+
import {
|
|
12
|
+
normKey
|
|
13
|
+
} from "./chunk-RLGQ5PZZ.js";
|
|
14
14
|
import {
|
|
15
15
|
readNumericBonus
|
|
16
16
|
} from "./chunk-LWFTHJIE.js";
|
|
17
17
|
import {
|
|
18
18
|
resolveBaseItem
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-WXWPK3LI.js";
|
|
20
20
|
import {
|
|
21
21
|
bareEntitySlug
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-6X4KUDMU.js";
|
|
23
23
|
|
|
24
24
|
// src/weapon/weapon-mastery.ts
|
|
25
25
|
var MASTERY = {
|
|
@@ -405,7 +405,7 @@ function magicBonusesForWeaponEntry(entry, registry, ctx) {
|
|
|
405
405
|
itemRiders = Array.isArray(entity.damage_riders) ? entity.damage_riders.filter((r) => {
|
|
406
406
|
var _a2;
|
|
407
407
|
return ((_a2 = r.applies_to) != null ? _a2 : "weapon") !== "spell";
|
|
408
|
-
}).map((r) => ({ amount: r.amount, damage_type: r.damage_type, source: entity.name })) : [];
|
|
408
|
+
}).map((r) => ({ amount: r.amount, damage_type: r.damage_type, source: entity.name, ...r.condition ? { condition: r.condition } : {} })) : [];
|
|
409
409
|
}
|
|
410
410
|
return {
|
|
411
411
|
atk: itemAttack + entryAttack,
|
|
@@ -482,6 +482,40 @@ function buildAttackRow(args) {
|
|
|
482
482
|
}
|
|
483
483
|
return row;
|
|
484
484
|
}
|
|
485
|
+
function buildUnarmedRow(mods, proficiencyBonus, spec) {
|
|
486
|
+
var _a;
|
|
487
|
+
const candidates = ["str", ...(_a = spec == null ? void 0 : spec.abilities) != null ? _a : []];
|
|
488
|
+
let ability = "str";
|
|
489
|
+
for (const ab of candidates) if (mods[ab] >= mods[ability]) ability = ab;
|
|
490
|
+
const abilityMod = mods[ability];
|
|
491
|
+
const toHit = abilityMod + proficiencyBonus;
|
|
492
|
+
const flat = `${abilityMod >= 0 ? "+" : ""}${abilityMod}`.replace(/^\+0$/, "");
|
|
493
|
+
const damageDice = (spec == null ? void 0 : spec.dice) ? `${spec.dice}${flat}` : String(Math.max(0, 1 + abilityMod));
|
|
494
|
+
const label = `${ability.toUpperCase()} modifier`;
|
|
495
|
+
return {
|
|
496
|
+
id: "unarmed-strike",
|
|
497
|
+
name: "Unarmed Strike",
|
|
498
|
+
unarmed: true,
|
|
499
|
+
range: "5 ft",
|
|
500
|
+
toHit,
|
|
501
|
+
damageDice,
|
|
502
|
+
damageType: "bludgeoning",
|
|
503
|
+
properties: [],
|
|
504
|
+
proficient: true,
|
|
505
|
+
breakdown: {
|
|
506
|
+
toHit: [
|
|
507
|
+
{ source: label, amount: abilityMod, kind: "ability" },
|
|
508
|
+
{ source: "Proficiency bonus", amount: proficiencyBonus, kind: "ability" }
|
|
509
|
+
],
|
|
510
|
+
damage: [
|
|
511
|
+
{ source: "Base damage", amount: 0, kind: "ability" },
|
|
512
|
+
{ source: label, amount: abilityMod, kind: "ability" }
|
|
513
|
+
]
|
|
514
|
+
},
|
|
515
|
+
subLabel: "Unarmed",
|
|
516
|
+
actionCost: "action"
|
|
517
|
+
};
|
|
518
|
+
}
|
|
485
519
|
function humanizeWeaponToken(s) {
|
|
486
520
|
return s.replace(/[-_]/g, " ").replace(/(^|[\s(])\w/g, (c) => c.toUpperCase());
|
|
487
521
|
}
|
|
@@ -594,5 +628,7 @@ function computeSlotsAndAttacks(resolved, mods, profs, registry, warnings, profi
|
|
|
594
628
|
export {
|
|
595
629
|
emptyAppliedBonuses,
|
|
596
630
|
computeAppliedBonuses,
|
|
631
|
+
isWeaponSlugProficient,
|
|
632
|
+
buildUnarmedRow,
|
|
597
633
|
computeSlotsAndAttacks
|
|
598
634
|
};
|