@archivist-gg/dnd5e 0.3.26 → 0.3.28
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 +6 -13
- package/README.md +1 -1
- package/dist/background/background.codec.js +1 -1
- package/dist/background/background.parser.js +1 -1
- package/dist/background/background.schema.js +1 -1
- package/dist/chunk-2GZM7FCD.js +1 -0
- package/dist/{chunk-KEXSF3CH.js → chunk-2OVDSMPY.js} +1 -1
- package/dist/chunk-4AJYEWFQ.js +1 -0
- package/dist/chunk-4FTTUZXM.js +1 -0
- package/dist/{chunk-CCAVZANF.js → chunk-53SHSS4M.js} +1 -1
- package/dist/{chunk-HX7WBOKR.js → chunk-5QDSAZG6.js} +1 -1
- package/dist/chunk-6IPWTOLU.js +1 -0
- package/dist/{chunk-XPF53K54.js → chunk-7HOOPNF5.js} +1 -1
- package/dist/{chunk-DTB7YBMZ.js → chunk-ADX7435T.js} +1 -1
- package/dist/{chunk-GIQLIBC7.js → chunk-AFEWQFQZ.js} +1 -1
- package/dist/{chunk-EPA24PVZ.js → chunk-C4T6BUSP.js} +1 -1
- package/dist/chunk-CLZRWPWT.js +1 -0
- package/dist/{chunk-E7KFJLDR.js → chunk-CYYVM6H3.js} +1 -1
- package/dist/{chunk-4SYAKWY4.js → chunk-D2BXAFOL.js} +1 -1
- package/dist/{chunk-PKIMOVQG.js → chunk-E4E6YEN6.js} +1 -1
- package/dist/{chunk-OTRH62HY.js → chunk-EBFLUJIW.js} +1 -1
- package/dist/{chunk-ZVL5FXXO.js → chunk-EON7T2SN.js} +1 -1
- package/dist/{chunk-NU2Z7MTS.js → chunk-GKNOCYDT.js} +1 -1
- package/dist/{chunk-VVJXZZ4Z.js → chunk-IR5BA2DZ.js} +1 -1
- package/dist/{chunk-WAUNLUFQ.js → chunk-J27N3KUE.js} +1 -1
- package/dist/{chunk-ETDMOGFO.js → chunk-J6FIBUI4.js} +1 -1
- package/dist/{chunk-CNMHADNV.js → chunk-KGZXAAFN.js} +1 -1
- package/dist/chunk-KZFTTAFN.js +1 -0
- package/dist/chunk-M2UA2FAK.js +1 -0
- package/dist/{chunk-J3RP5C7L.js → chunk-MMDUUEFA.js} +1 -1
- package/dist/{chunk-RHIEOYDX.js → chunk-NB4QWMF5.js} +1 -1
- package/dist/{chunk-ONCXJMJM.js → chunk-NU6WP4P5.js} +1 -1
- package/dist/{chunk-SFK57JAA.js → chunk-OV4FG4KO.js} +1 -1
- package/dist/{chunk-GGQDQSIF.js → chunk-R2YRQM7G.js} +1 -1
- package/dist/{chunk-CEHL7PPC.js → chunk-RR26E7LH.js} +1 -1
- package/dist/{chunk-NYPH7RQN.js → chunk-U7BPRRY5.js} +1 -1
- package/dist/{chunk-LHH5XSEA.js → chunk-VHIE2KYQ.js} +1 -1
- package/dist/{chunk-ZS5BMNXC.js → chunk-VY5ZEOLG.js} +1 -1
- package/dist/{chunk-NYTR6NJS.js → chunk-WXL7ABDO.js} +1 -1
- package/dist/{chunk-6R46KYGU.js → chunk-XCF5R5XX.js} +1 -1
- package/dist/{chunk-L2DXF7YS.js → chunk-XFFFTR6O.js} +1 -1
- package/dist/class/class.codec.js +1 -1
- package/dist/class/class.parser.js +1 -1
- package/dist/class/class.schema.js +1 -1
- package/dist/feat/feat.codec.js +1 -1
- package/dist/feat/feat.parser.js +1 -1
- package/dist/feat/feat.schema.d.ts +31 -0
- package/dist/feat/feat.schema.js +1 -1
- package/dist/index.js +8 -8
- package/dist/item/item.icon.js +1 -1
- package/dist/monster/monster.parser.js +1 -1
- package/dist/monster/monster.schema.js +1 -1
- package/dist/optional-feature/optional-feature.codec.js +1 -1
- package/dist/optional-feature/optional-feature.parser.js +1 -1
- package/dist/optional-feature/optional-feature.schema.d.ts +31 -0
- package/dist/optional-feature/optional-feature.schema.js +1 -1
- package/dist/pc/pc.additional-spells.js +1 -1
- package/dist/pc/pc.amount-bindings.js +1 -1
- package/dist/pc/pc.decision-engine.d.ts +2 -0
- package/dist/pc/pc.decision-engine.js +1 -1
- package/dist/pc/pc.entry-overrides.js +1 -1
- package/dist/pc/pc.equipment.d.ts +5 -1
- package/dist/pc/pc.equipment.js +1 -1
- package/dist/pc/pc.feature-effects.d.ts +9 -1
- package/dist/pc/pc.feature-effects.js +1 -1
- package/dist/pc/pc.infusions.js +1 -1
- package/dist/pc/pc.item-effects.js +1 -1
- package/dist/pc/pc.member-choices.js +1 -1
- package/dist/pc/pc.parser.js +1 -1
- package/dist/pc/pc.pools.js +1 -1
- package/dist/pc/pc.proficiencies.js +1 -1
- package/dist/pc/pc.proficiency-replacements.d.ts +22 -0
- package/dist/pc/pc.proficiency-replacements.js +1 -0
- package/dist/pc/pc.recalc.d.ts +3 -1
- package/dist/pc/pc.recalc.js +1 -1
- package/dist/pc/pc.resolver.js +1 -1
- package/dist/pc/pc.resource-seed.js +1 -1
- package/dist/pc/pc.resources.js +1 -1
- package/dist/pc/pc.rest.js +1 -1
- package/dist/pc/pc.schema.d.ts +8 -0
- package/dist/pc/pc.schema.js +1 -1
- package/dist/pc/pc.species-increases.d.ts +12 -0
- package/dist/pc/pc.species-increases.js +1 -0
- package/dist/pc/pc.types.d.ts +46 -0
- package/dist/race/race.codec.js +1 -1
- package/dist/race/race.parser.js +1 -1
- package/dist/race/race.schema.js +1 -1
- package/dist/race/race.subspecies.d.ts +12 -0
- package/dist/race/race.subspecies.js +1 -0
- package/dist/schemas/attack-schema.d.ts +1 -0
- package/dist/schemas/choice-schema.js +1 -1
- package/dist/schemas/feature-effect-schema.d.ts +31 -0
- package/dist/schemas/feature-effect-schema.js +1 -1
- package/dist/schemas/feature-schema.js +1 -1
- package/dist/subclass/subclass.codec.js +1 -1
- package/dist/subclass/subclass.parser.js +1 -1
- package/dist/subclass/subclass.schema.js +1 -1
- package/dist/types/attack.d.ts +1 -0
- package/dist/types/feature-effect.d.ts +8 -0
- package/package.json +1 -1
- package/dist/chunk-E3MS4M3N.js +0 -1
- package/dist/chunk-GD7WRCNH.js +0 -1
- package/dist/chunk-J5GL6FLP.js +0 -1
- package/dist/chunk-NIWLD33X.js +0 -1
package/dist/pc/pc.resolver.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PCResolver,collectAdditionalFeatures,collectChosenGrantedFeatures,collectChosenWeaponMasteries,collectFeatChoiceGrants,collectFeatGrantedSpells,collectFeatPicks,collectItemGrantedSpells,collectResolvedFeatures,dedupeResolvedSpells,resolveOriginFeat,stripSlug}from"../chunk-
|
|
1
|
+
import{PCResolver,collectAdditionalFeatures,collectChosenGrantedFeatures,collectChosenWeaponMasteries,collectFeatChoiceGrants,collectFeatGrantedSpells,collectFeatPicks,collectItemGrantedSpells,collectResolvedFeatures,dedupeResolvedSpells,resolveOriginFeat,stripSlug}from"../chunk-2GZM7FCD.js";import"../chunk-2EOGK6R6.js";import"../chunk-4AJYEWFQ.js";import"../chunk-RQZCGXUZ.js";import"../chunk-CLZRWPWT.js";import"../chunk-4FTTUZXM.js";import"../chunk-FOLHTMSC.js";import"../chunk-4JEF3CET.js";import"../chunk-VTQ4RWEG.js";import"../chunk-MMDUUEFA.js";import"../chunk-J27N3KUE.js";import"../chunk-RR26E7LH.js";import"../chunk-UBUKCRZ3.js";import"../chunk-2OVDSMPY.js";import"../chunk-PFQPP77Q.js";import"../chunk-QVWT67WA.js";import"../chunk-E4E6YEN6.js";import"../chunk-CMIEZQL4.js";import"../chunk-O776WL7O.js";import"../chunk-CSTAQQGX.js";import"../chunk-3LWOVRLA.js";import"../chunk-DVUXUIPV.js";import"../chunk-YGH7S5ZF.js";import"../chunk-4IAMSRHD.js";import"../chunk-3QQOATV3.js";import"../chunk-DZITM5AG.js";import"../chunk-PZ4L2EEG.js";import"../chunk-QMEKQTUT.js";import"../chunk-EAARMPCW.js";import"../chunk-CAPYNIGK.js";import"../chunk-63YJPWTM.js";import"../chunk-4KVVAENP.js";import"../chunk-7EL3GWWJ.js";import"../chunk-BREHZNTL.js";import"../chunk-7FPQJDFD.js";import"../chunk-EVT7MGAC.js";import"../chunk-S5UCI27C.js";import"../chunk-EON7T2SN.js";import"../chunk-I26FHSI6.js";export{PCResolver,collectAdditionalFeatures,collectChosenGrantedFeatures,collectChosenWeaponMasteries,collectFeatChoiceGrants,collectFeatGrantedSpells,collectFeatPicks,collectItemGrantedSpells,collectResolvedFeatures,dedupeResolvedSpells,resolveOriginFeat,stripSlug};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resourceLevelFor}from"../chunk-
|
|
1
|
+
import{resourceLevelFor}from"../chunk-2OVDSMPY.js";import"../chunk-PFQPP77Q.js";import"../chunk-E4E6YEN6.js";import"../chunk-CMIEZQL4.js";import"../chunk-O776WL7O.js";import{numericColumnsAt}from"../chunk-CSTAQQGX.js";import"../chunk-DVUXUIPV.js";import"../chunk-YGH7S5ZF.js";import"../chunk-4IAMSRHD.js";import"../chunk-DZITM5AG.js";import"../chunk-PZ4L2EEG.js";import"../chunk-QMEKQTUT.js";import"../chunk-EAARMPCW.js";import"../chunk-CAPYNIGK.js";import"../chunk-63YJPWTM.js";import"../chunk-BREHZNTL.js";import"../chunk-7FPQJDFD.js";import"../chunk-EVT7MGAC.js";function resourceBindings(resolved,derived,source){var _a,_b,_c,_d;const classLevel=resourceLevelFor(source,resolved);let table;if(source.kind==="class")table=(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_a.entity)==null?void 0:_b.table;else if(source.kind==="subclass")table=(_d=(_c=resolved.classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_c.subclass)==null?void 0:_d.table;return{level:resolved.totalLevel,class_level:classLevel,prof:derived.proficiencyBonus,str_mod:derived.mods.str,dex_mod:derived.mods.dex,con_mod:derived.mods.con,int_mod:derived.mods.int,wis_mod:derived.mods.wis,cha_mod:derived.mods.cha,columns:numericColumnsAt(table,classLevel)}}export{resourceBindings};
|
package/dist/pc/pc.resources.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pickResourceId,poolSaveDC,resolveFeatureResources,resolveRecovery,resolveResourceIndex,resourceLevelFor}from"../chunk-
|
|
1
|
+
import{pickResourceId,poolSaveDC,resolveFeatureResources,resolveRecovery,resolveResourceIndex,resourceLevelFor}from"../chunk-2OVDSMPY.js";import"../chunk-PFQPP77Q.js";import"../chunk-E4E6YEN6.js";import"../chunk-CMIEZQL4.js";import"../chunk-O776WL7O.js";import"../chunk-CSTAQQGX.js";import"../chunk-DVUXUIPV.js";import"../chunk-YGH7S5ZF.js";import"../chunk-4IAMSRHD.js";import"../chunk-DZITM5AG.js";import"../chunk-PZ4L2EEG.js";import"../chunk-QMEKQTUT.js";import"../chunk-EAARMPCW.js";import"../chunk-CAPYNIGK.js";import"../chunk-63YJPWTM.js";import"../chunk-BREHZNTL.js";import"../chunk-7FPQJDFD.js";import"../chunk-EVT7MGAC.js";export{pickResourceId,poolSaveDC,resolveFeatureResources,resolveRecovery,resolveResourceIndex,resourceLevelFor};
|
package/dist/pc/pc.rest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveResourceIndex}from"../chunk-
|
|
1
|
+
import{resolveResourceIndex}from"../chunk-2OVDSMPY.js";import"../chunk-PFQPP77Q.js";import{effectiveItemCharges,effectiveItemRecovery}from"../chunk-E4E6YEN6.js";import"../chunk-CMIEZQL4.js";import"../chunk-O776WL7O.js";import"../chunk-CSTAQQGX.js";import"../chunk-DVUXUIPV.js";import"../chunk-YGH7S5ZF.js";import"../chunk-4IAMSRHD.js";import"../chunk-DZITM5AG.js";import"../chunk-PZ4L2EEG.js";import"../chunk-QMEKQTUT.js";import"../chunk-EAARMPCW.js";import"../chunk-CAPYNIGK.js";import"../chunk-63YJPWTM.js";import"../chunk-BREHZNTL.js";import"../chunk-7FPQJDFD.js";import"../chunk-EVT7MGAC.js";function resolveItemName(entry,registry){var _a;if(!registry)return void 0;const ref=entry.item.match(/^\[\[(.+?)\]\]$/);const slug=ref?ref[1]:entry.item;return(_a=registry.getBySlug(slug))==null?void 0:_a.name}var RESTORED_BY={"short-rest":"short",either:"short",short:"short","long-rest":"long",long:"long",dawn:"long",dusk:"long",turn:null,round:null,custom:null,special:null};var REST_SPAN={short:1,long:2};function earliestRestoringRest(reset){return Object.prototype.hasOwnProperty.call(RESTORED_BY,reset)?RESTORED_BY[reset]:null}function restRestores(type,reset){const earliest=earliestRestoringRest(reset);return earliest!==null&&REST_SPAN[earliest]<=REST_SPAN[type]}function pushPartialRecoveries(cats,character,index,type){var _a,_b;for(const[key,fu]of Object.entries((_a=character.state.feature_uses)!=null?_a:{})){if(fu.used<=0)continue;const res=index.get(key);if(!((_b=res==null?void 0:res.recovery)==null?void 0:_b.length))continue;if(restRestores(type,res.reset))continue;const entry=res.recovery.find(r=>r.kind==="uses"&&r.flavour==="rest"&&restRestores(type,r.entry.reset));if(!entry)continue;const amount=entry.entry.amount;const restore=amount==="all"?"all":typeof amount==="number"?amount:Number(amount);if(restore!=="all"&&!Number.isFinite(restore))continue;const n=restore==="all"?fu.used:Math.min(fu.used,restore);cats.push({id:`feature:${key}`,label:res.name,preview:`${n} of ${fu.used} used restored`,restore})}}function pushBuffEnds(cats,character,resolved){var _a,_b,_c,_d,_e,_f,_g;const structured=d=>!!d&&typeof d==="object";for(const key of(_a=character.state.active_buffs)!=null?_a:[]){let found=false;let name=key;for(const rf of(_b=resolved.features)!=null?_b:[]){if(rf.feature.id===key&&structured(rf.feature.duration)){found=true;name=(_c=rf.feature.name)!=null?_c:key;break}}if(!found){for(const pool of(_d=resolved.pools)!=null?_d:[]){const entry=[...(_e=pool.selected)!=null?_e:[],...(_f=pool.grants)!=null?_f:[]].find(e=>e.slug===key);if(entry&&structured(entry.entity.duration)){found=true;name=(_g=entry.entity.name)!=null?_g:key;break}}}if(!found)continue;cats.push({id:`buff:${key}`,label:`End ${name}`,preview:"active \u2192 ended"})}}function computeRestPlan(character,resolved,derived,registry,type){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n;const cats=[];let hdRegainDist;const index=resolveResourceIndex(resolved);const pact=character.state.spell_slots_pact;if(pact&&pact.used>0){cats.push({id:"pact-slots",label:"Pact Magic Slots",preview:"all reset"})}if(type==="long"){if(character.state.hp.current<derived.hp.max){cats.push({id:"hp-to-max",label:"Hit Points",preview:`${character.state.hp.current} \u2192 ${derived.hp.max}`})}if(character.state.exhaustion>0){cats.push({id:"exhaustion",label:"Exhaustion",preview:`${character.state.exhaustion} \u2192 ${character.state.exhaustion-1}`})}const hpModifier=(_b=(_a=character.overrides)==null?void 0:_a.hp)==null?void 0:_b.modifier;if(hpModifier!==void 0){const signed=hpModifier>0?`+${hpModifier}`:`${hpModifier}`;cats.push({id:"hp-modifier-reset",label:"Max HP Modifier",preview:`${signed} \u2192 cleared`})}const slotsUsed=Object.values((_c=character.state.spell_slots)!=null?_c:{}).reduce((s,slot)=>{var _a2;return s+((_a2=slot.used)!=null?_a2:0)},0);if(slotsUsed>0){cats.push({id:"spell-slots",label:"Spell Slots",preview:"all reset"})}const totalLevel=(_d=resolved.totalLevel)!=null?_d:0;const regainBudget=Math.max(1,Math.floor(totalLevel/2));const pools=Object.entries((_e=character.state.hit_dice)!=null?_e:{}).map(([die,hd])=>({die,used:hd.used,total:hd.total})).filter(p=>p.used>0).sort((a,b)=>b.used-a.used);if(pools.length>0){let left=regainBudget;const dist=[];for(const p of pools){if(left===0)break;const give=Math.min(p.used,left);if(give>0)dist.push({die:p.die,give,targetUsed:p.used-give});left-=give}const totalGive=dist.reduce((s,d)=>s+d.give,0);if(totalGive>0){const detail=dist.map(d=>`${d.die}: +${d.give}`).join(", ");cats.push({id:"hd-regain",label:"Hit Dice",preview:`+${totalGive} (${detail})`});hdRegainDist=dist.map(d=>({die:d.die,targetUsed:d.targetUsed}))}}for(const[key,fu]of Object.entries((_f=character.state.feature_uses)!=null?_f:{})){const banked=(_g=character.state.feature_rolls)==null?void 0:_g[key];const bankedRolls=banked?banked.filter(v=>v>0).length:0;if(fu.used<=0&&bankedRolls<=0)continue;const res=index.get(key);if(!restRestores("long",(_h=res==null?void 0:res.reset)!=null?_h:"long-rest"))continue;const rollsNote=bankedRolls>0?` \xB7 ${bankedRolls} roll${bankedRolls===1?"":"s"} cleared`:"";cats.push({id:`feature:${key}`,label:(_i=res==null?void 0:res.name)!=null?_i:key,preview:`${fu.used}/${fu.max} restored${rollsNote}`})}pushPartialRecoveries(cats,character,index,"long");character.equipment.forEach((entry,idx)=>{var _a2,_b2,_c2,_d2,_e2;const view=(_b2=(_a2=resolved.infusions)==null?void 0:_a2.views.get(idx))!=null?_b2:null;const rec=effectiveItemRecovery(entry,registry,view);const charges=effectiveItemCharges(entry,registry,view);if(!rec||!charges)return;if(charges.current>=charges.max)return;if(!restRestores("long",rec.reset))return;const label=(_e2=(_d2=(_c2=entry.overrides)==null?void 0:_c2.name)!=null?_d2:resolveItemName(entry,registry))!=null?_e2:entry.item;cats.push({id:`item:${idx}`,label,preview:`${charges.current} \u2192 ${charges.max}`,recharge:{amount:rec.amount,current:charges.current,max:charges.max}})})}if(type==="short"){for(const[key,fu]of Object.entries((_j=character.state.feature_uses)!=null?_j:{})){const banked=(_k=character.state.feature_rolls)==null?void 0:_k[key];const bankedRolls=banked?banked.filter(v=>v>0).length:0;if(fu.used<=0&&bankedRolls<=0)continue;const res=index.get(key);if(!restRestores("short",(_l=res==null?void 0:res.reset)!=null?_l:"long-rest"))continue;const rollsNote=bankedRolls>0?` \xB7 ${bankedRolls} roll${bankedRolls===1?"":"s"} cleared`:"";cats.push({id:`feature:${key}`,label:(_m=res==null?void 0:res.name)!=null?_m:key,preview:`${fu.used}/${fu.max} restored${rollsNote}`})}pushPartialRecoveries(cats,character,index,"short");character.equipment.forEach((entry,idx)=>{var _a2,_b2,_c2,_d2,_e2;const view=(_b2=(_a2=resolved.infusions)==null?void 0:_a2.views.get(idx))!=null?_b2:null;const rec=effectiveItemRecovery(entry,registry,view);const charges=effectiveItemCharges(entry,registry,view);if(!rec||!charges)return;if(charges.current>=charges.max)return;if(!restRestores("short",rec.reset))return;const label=(_e2=(_d2=(_c2=entry.overrides)==null?void 0:_c2.name)!=null?_d2:resolveItemName(entry,registry))!=null?_e2:entry.item;cats.push({id:`item:${idx}`,label,preview:`${charges.current} \u2192 ${charges.max}`,recharge:{amount:rec.amount,current:charges.current,max:charges.max}})})}pushBuffEnds(cats,character,resolved);const hdAvailable=type==="short"?Object.entries((_n=character.state.hit_dice)!=null?_n:{}).filter(([,hd])=>hd.used<hd.total).map(([die,hd])=>({die,remaining:hd.total-hd.used})):[];return{type,categories:cats,hdAvailable,hdRegainDist}}export{computeRestPlan,earliestRestoringRest,restRestores};
|
package/dist/pc/pc.schema.d.ts
CHANGED
|
@@ -148,6 +148,7 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
148
148
|
"archivist-point-buy": "archivist-point-buy";
|
|
149
149
|
manual: "manual";
|
|
150
150
|
}>;
|
|
151
|
+
keep_species_ability_increases: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
|
|
151
152
|
builder_rolls: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
152
153
|
builder_equipment_mode: z.ZodOptional<z.ZodEnum<{
|
|
153
154
|
gold: "gold";
|
|
@@ -455,6 +456,13 @@ export declare const characterSchema: z.ZodObject<{
|
|
|
455
456
|
}>>>;
|
|
456
457
|
}, z.core.$strip>>;
|
|
457
458
|
favorites: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
459
|
+
rolls: z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodTransform<{
|
|
460
|
+
name: string;
|
|
461
|
+
on: string;
|
|
462
|
+
hit?: "advantage" | "disadvantage" | "normal" | undefined;
|
|
463
|
+
damage?: string[] | undefined;
|
|
464
|
+
extra?: string | undefined;
|
|
465
|
+
}[], unknown[]>>>;
|
|
458
466
|
filters: z.ZodOptional<z.ZodObject<{
|
|
459
467
|
actions: z.ZodOptional<z.ZodObject<{
|
|
460
468
|
show: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
package/dist/pc/pc.schema.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{characterOverridesShape,characterSchema}from"../chunk-
|
|
1
|
+
import{characterOverridesShape,characterSchema}from"../chunk-CYYVM6H3.js";import"../chunk-KM75CC6Q.js";export{characterOverridesShape,characterSchema};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { BackgroundEntity } from "@archivist-gg/dnd5e/background/background.types";
|
|
2
|
+
import type { RaceEntity } from "@archivist-gg/dnd5e/race/race.types";
|
|
3
|
+
import type { ResolvedCharacter } from "./pc.types.js";
|
|
4
|
+
export declare function backgroundGrantsAbilityIncreases(bg: BackgroundEntity | null | undefined): boolean;
|
|
5
|
+
export declare function speciesGrantsAbilityIncreases(race: RaceEntity | null | undefined): boolean;
|
|
6
|
+
export declare function isOlderSpecies(race: RaceEntity | null | undefined): boolean;
|
|
7
|
+
export interface SpeciesIncreaseRule {
|
|
8
|
+
applies: boolean;
|
|
9
|
+
kept: boolean;
|
|
10
|
+
suppressed: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function speciesIncreaseRule(resolved: Pick<ResolvedCharacter, "race" | "background" | "definition">): SpeciesIncreaseRule;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{backgroundGrantsAbilityIncreases,isOlderSpecies,speciesGrantsAbilityIncreases,speciesIncreaseRule}from"../chunk-6IPWTOLU.js";export{backgroundGrantsAbilityIncreases,isOlderSpecies,speciesGrantsAbilityIncreases,speciesIncreaseRule};
|
package/dist/pc/pc.types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Ability, EntityFilter } from "../types/choice.js";
|
|
2
|
+
import type { ProficiencyReplacement } from "./pc.proficiency-replacements.js";
|
|
2
3
|
import type { ArmorEntity } from "../armor/armor.types.js";
|
|
3
4
|
import type { WeaponEntity } from "../weapon/weapon.types.js";
|
|
4
5
|
import type { SpellScope, WeaponScope } from "../types/feature-effect.js";
|
|
@@ -217,12 +218,20 @@ export interface SheetPoolView {
|
|
|
217
218
|
off?: Record<string, string[]>;
|
|
218
219
|
folded?: string[];
|
|
219
220
|
}
|
|
221
|
+
export interface SavedRoll {
|
|
222
|
+
name: string;
|
|
223
|
+
on: string;
|
|
224
|
+
hit?: "normal" | "advantage" | "disadvantage";
|
|
225
|
+
damage?: string[];
|
|
226
|
+
extra?: string;
|
|
227
|
+
}
|
|
220
228
|
export interface CharacterSheetState {
|
|
221
229
|
layout?: {
|
|
222
230
|
saves?: "section";
|
|
223
231
|
body?: "wide";
|
|
224
232
|
};
|
|
225
233
|
favorites?: string[];
|
|
234
|
+
rolls?: SavedRoll[];
|
|
226
235
|
filters?: {
|
|
227
236
|
actions?: SheetViewFilter;
|
|
228
237
|
passive?: SheetViewFilter;
|
|
@@ -242,6 +251,7 @@ export interface Character {
|
|
|
242
251
|
origin_choices?: Record<string, ChoiceValue>;
|
|
243
252
|
abilities: Record<Ability, number>;
|
|
244
253
|
ability_method: AbilityMethod;
|
|
254
|
+
keep_species_ability_increases?: boolean;
|
|
245
255
|
builder_rolls?: number[];
|
|
246
256
|
builder_equipment_mode?: "starting" | "gold" | "empty";
|
|
247
257
|
skills: {
|
|
@@ -387,6 +397,7 @@ export interface ResolvedCharacter {
|
|
|
387
397
|
background: BackgroundEntity | null;
|
|
388
398
|
feats: FeatEntity[];
|
|
389
399
|
originFeatSlug?: string;
|
|
400
|
+
proficiencyReplacements?: ProficiencyReplacement[];
|
|
390
401
|
totalLevel: number;
|
|
391
402
|
features: ResolvedFeature[];
|
|
392
403
|
spells: ResolvedSpell[];
|
|
@@ -459,6 +470,14 @@ export interface DamageRider {
|
|
|
459
470
|
scope?: WeaponScope[];
|
|
460
471
|
owner?: FeatureSource;
|
|
461
472
|
}
|
|
473
|
+
export interface DamageRollOption {
|
|
474
|
+
mode: import("../types/feature-effect.js").DamageRollMode;
|
|
475
|
+
value?: number;
|
|
476
|
+
twoHanded?: true;
|
|
477
|
+
oncePerTurn?: true;
|
|
478
|
+
condition?: string;
|
|
479
|
+
source: string;
|
|
480
|
+
}
|
|
462
481
|
export interface ConditionalCrit {
|
|
463
482
|
minRoll: number;
|
|
464
483
|
condition: string;
|
|
@@ -506,6 +525,7 @@ export interface AttackRow {
|
|
|
506
525
|
};
|
|
507
526
|
critRange?: number;
|
|
508
527
|
conditionalCrits?: ConditionalCrit[];
|
|
528
|
+
damageRollOptions?: DamageRollOption[];
|
|
509
529
|
attackNotes?: string[];
|
|
510
530
|
mastery?: {
|
|
511
531
|
slug: string;
|
|
@@ -519,10 +539,35 @@ export interface AttackRow {
|
|
|
519
539
|
};
|
|
520
540
|
grantedBy?: string;
|
|
521
541
|
pactWeapon?: true;
|
|
542
|
+
naturalWeapon?: true;
|
|
543
|
+
}
|
|
544
|
+
export interface AbilityScoreTerm {
|
|
545
|
+
source: string;
|
|
546
|
+
amount: number;
|
|
547
|
+
notUsed?: true;
|
|
548
|
+
}
|
|
549
|
+
export interface AbilityScoreBreakdown {
|
|
550
|
+
total: number;
|
|
551
|
+
terms: AbilityScoreTerm[];
|
|
552
|
+
set?: {
|
|
553
|
+
source: string;
|
|
554
|
+
value: number;
|
|
555
|
+
};
|
|
556
|
+
override?: number;
|
|
522
557
|
}
|
|
523
558
|
export interface AppliedBonuses {
|
|
524
559
|
ability_bonuses: Partial<Record<Ability, number>>;
|
|
525
560
|
ability_statics: Partial<Record<Ability, number>>;
|
|
561
|
+
ability_terms?: {
|
|
562
|
+
ability: Ability;
|
|
563
|
+
source: string;
|
|
564
|
+
amount: number;
|
|
565
|
+
}[];
|
|
566
|
+
ability_static_terms?: {
|
|
567
|
+
ability: Ability;
|
|
568
|
+
source: string;
|
|
569
|
+
value: number;
|
|
570
|
+
}[];
|
|
526
571
|
save_bonus: number;
|
|
527
572
|
save_terms: {
|
|
528
573
|
source: string;
|
|
@@ -636,6 +681,7 @@ export interface DerivedStats {
|
|
|
636
681
|
source: string;
|
|
637
682
|
amount: number;
|
|
638
683
|
}[];
|
|
684
|
+
abilities?: Record<Ability, AbilityScoreBreakdown>;
|
|
639
685
|
};
|
|
640
686
|
passives: {
|
|
641
687
|
perception: number;
|
package/dist/race/race.codec.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{raceCodec}from"../chunk-
|
|
1
|
+
import{raceCodec}from"../chunk-XCF5R5XX.js";import"../chunk-KGZXAAFN.js";import"../chunk-D2BXAFOL.js";import"../chunk-S5UCI27C.js";import"../chunk-M2UA2FAK.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";import"../chunk-I26FHSI6.js";export{raceCodec};
|
package/dist/race/race.parser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseRace}from"../chunk-
|
|
1
|
+
import{parseRace}from"../chunk-KGZXAAFN.js";import"../chunk-D2BXAFOL.js";import"../chunk-S5UCI27C.js";import"../chunk-M2UA2FAK.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";import"../chunk-I26FHSI6.js";export{parseRace};
|
package/dist/race/race.schema.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fixedAsiSchema,raceEntitySchema}from"../chunk-
|
|
1
|
+
import{fixedAsiSchema,raceEntitySchema}from"../chunk-D2BXAFOL.js";import"../chunk-M2UA2FAK.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";import"../chunk-I26FHSI6.js";export{fixedAsiSchema,raceEntitySchema};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RegisteredEntity } from "@archivist-gg/core";
|
|
2
|
+
import type { RaceEntity } from "./race.types.js";
|
|
3
|
+
export interface SubspeciesRegistry {
|
|
4
|
+
getByTypeAndSlug(entityType: string, slug: string): RegisteredEntity | undefined;
|
|
5
|
+
search(query: string, entityType: string, limit: number): RegisteredEntity[];
|
|
6
|
+
}
|
|
7
|
+
export declare function findSubspeciesParent(registry: SubspeciesRegistry, child: {
|
|
8
|
+
slug: string;
|
|
9
|
+
subspecies_of?: string | null;
|
|
10
|
+
}): RegisteredEntity | undefined;
|
|
11
|
+
export declare function mergeSubspecies(child: RaceEntity, parent: RaceEntity): RaceEntity;
|
|
12
|
+
export declare function withSubspeciesParent<T extends RaceEntity | null>(race: T, registry: SubspeciesRegistry): T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{findSubspeciesParent,mergeSubspecies,withSubspeciesParent}from"../chunk-4AJYEWFQ.js";import"../chunk-63YJPWTM.js";export{findSubspeciesParent,mergeSubspecies,withSubspeciesParent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{choiceSchema}from"../chunk-
|
|
1
|
+
import{choiceSchema}from"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";export{choiceSchema};
|
|
@@ -304,6 +304,37 @@ export declare const featureEffectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
304
304
|
}>;
|
|
305
305
|
condition: z.ZodOptional<z.ZodString>;
|
|
306
306
|
subject: z.ZodOptional<z.ZodString>;
|
|
307
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
308
|
+
kind: z.ZodLiteral<"damage-roll-option">;
|
|
309
|
+
mode: z.ZodEnum<{
|
|
310
|
+
"reroll-weapon-dice-keep-higher": "reroll-weapon-dice-keep-higher";
|
|
311
|
+
"min-die-face": "min-die-face";
|
|
312
|
+
"reroll-below": "reroll-below";
|
|
313
|
+
}>;
|
|
314
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
315
|
+
applies_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
|
|
316
|
+
weapon: "weapon";
|
|
317
|
+
melee: "melee";
|
|
318
|
+
ranged: "ranged";
|
|
319
|
+
unarmed: "unarmed";
|
|
320
|
+
finesse: "finesse";
|
|
321
|
+
thrown: "thrown";
|
|
322
|
+
heavy: "heavy";
|
|
323
|
+
"pact-weapon": "pact-weapon";
|
|
324
|
+
}>, z.ZodArray<z.ZodEnum<{
|
|
325
|
+
weapon: "weapon";
|
|
326
|
+
melee: "melee";
|
|
327
|
+
ranged: "ranged";
|
|
328
|
+
unarmed: "unarmed";
|
|
329
|
+
finesse: "finesse";
|
|
330
|
+
thrown: "thrown";
|
|
331
|
+
heavy: "heavy";
|
|
332
|
+
"pact-weapon": "pact-weapon";
|
|
333
|
+
}>>]>>;
|
|
334
|
+
two_handed: z.ZodOptional<z.ZodBoolean>;
|
|
335
|
+
once_per_turn: z.ZodOptional<z.ZodBoolean>;
|
|
336
|
+
condition: z.ZodOptional<z.ZodString>;
|
|
337
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
307
338
|
}, z.core.$strip>, z.ZodObject<{
|
|
308
339
|
kind: z.ZodLiteral<"immunity">;
|
|
309
340
|
damage_type: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{featureEffectSchema}from"../chunk-
|
|
1
|
+
import{featureEffectSchema}from"../chunk-EON7T2SN.js";export{featureEffectSchema};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{featureObjectSchema,featureSchema}from"../chunk-
|
|
1
|
+
import{featureObjectSchema,featureSchema}from"../chunk-M2UA2FAK.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";export{featureObjectSchema,featureSchema};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{subclassCodec}from"../chunk-
|
|
1
|
+
import{subclassCodec}from"../chunk-NB4QWMF5.js";import"../chunk-J6FIBUI4.js";import"../chunk-NU6WP4P5.js";import"../chunk-S5UCI27C.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-M2UA2FAK.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";import"../chunk-I26FHSI6.js";export{subclassCodec};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{parseSubclass}from"../chunk-
|
|
1
|
+
import{parseSubclass}from"../chunk-J6FIBUI4.js";import"../chunk-NU6WP4P5.js";import"../chunk-S5UCI27C.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-M2UA2FAK.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";import"../chunk-I26FHSI6.js";export{parseSubclass};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{subclassEntitySchema}from"../chunk-
|
|
1
|
+
import{subclassEntitySchema}from"../chunk-NU6WP4P5.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-M2UA2FAK.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-VHIE2KYQ.js";import"../chunk-EON7T2SN.js";import"../chunk-I26FHSI6.js";export{subclassEntitySchema};
|
package/dist/types/attack.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Ability } from "./choice.js";
|
|
|
2
2
|
export type SenseType = "darkvision" | "blindsight" | "tremorsense" | "truesight";
|
|
3
3
|
export type WeaponScope = "weapon" | "melee" | "ranged" | "unarmed" | "finesse" | "thrown" | "heavy" | "pact-weapon";
|
|
4
4
|
export type SpeedGateWord = "heavy-armor" | "armor" | "shield";
|
|
5
|
+
export type DamageRollMode = "reroll-weapon-dice-keep-higher" | "min-die-face" | "reroll-below";
|
|
5
6
|
export interface SpellScope {
|
|
6
7
|
list?: string;
|
|
7
8
|
level?: number;
|
|
@@ -135,6 +136,13 @@ export type FeatureEffect = ({
|
|
|
135
136
|
} & Qualified) | ({
|
|
136
137
|
kind: "attack-rule";
|
|
137
138
|
flag: "no-ranged-in-melee-disadvantage";
|
|
139
|
+
} & Qualified) | ({
|
|
140
|
+
kind: "damage-roll-option";
|
|
141
|
+
mode: DamageRollMode;
|
|
142
|
+
value?: number;
|
|
143
|
+
applies_to?: WeaponScope | WeaponScope[];
|
|
144
|
+
two_handed?: boolean;
|
|
145
|
+
once_per_turn?: boolean;
|
|
138
146
|
} & Qualified) | ({
|
|
139
147
|
kind: "immunity";
|
|
140
148
|
damage_type: string;
|
package/package.json
CHANGED
package/dist/chunk-E3MS4M3N.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{qualifiedGrantCovers}from"./chunk-T55DELVL.js";import{classifyWeaponRange}from"./chunk-SEOASDO4.js";import{resolveContainment}from"./chunk-4E2GIWJE.js";import{pushDefenseGrant}from"./chunk-GD7WRCNH.js";import{normKey}from"./chunk-VTQ4RWEG.js";import{itemBenefitsActive,itemLabel,itemRowEffects}from"./chunk-J3RP5C7L.js";import{WEAPON_DEFAULT_ACTION_COST,resolveEntryEntity}from"./chunk-PKIMOVQG.js";import{isActivatedSpeedItem}from"./chunk-DVUXUIPV.js";import{readNumericBonus}from"./chunk-NEMX7QGG.js";import{defaultSlotForType,effectiveArmor,effectiveWeapon,isItemEntity,isShieldArmor,isTwoHandedWeapon,slotAcTerms}from"./chunk-4IAMSRHD.js";import{resolveBaseItem}from"./chunk-PZ4L2EEG.js";import{bareEntitySlug}from"./chunk-63YJPWTM.js";var MASTERY={cleave:{label:"Cleave",description:"If you hit a creature with a melee attack roll using this weapon, you can make an attack roll with the weapon against a second creature within 5 feet of the first that is also within your reach. On a hit, the second creature takes the weapon's damage, but don't add your ability modifier to that damage unless it is negative. You can make this extra attack only once per turn.",gist:"hit a 2nd creature in reach"},graze:{label:"Graze",description:"If your attack roll with this weapon misses a creature, you can deal damage to that creature equal to the ability modifier you used to make the attack roll. This damage is the same type dealt by the weapon, and the damage can be increased only by increasing the ability modifier.",gist:"on miss: ability-mod damage"},nick:{label:"Nick",description:"When you make the extra attack of the Light property, you can make it as part of the Attack action instead of as a Bonus Action. You can make this extra attack only once per turn.",gist:"extra Light attack (no Bonus Action)"},push:{label:"Push",description:"If you hit a creature with this weapon, you can push the creature up to 10 feet straight away from yourself if it is Large or smaller.",gist:"on hit: pushed 10 ft."},sap:{label:"Sap",description:"If you hit a creature with this weapon, that creature has Disadvantage on its next attack roll before the start of your next turn.",gist:"on hit: target Disadvantage"},slow:{label:"Slow",description:"If you hit a creature with this weapon and deal damage, you can reduce its Speed by 10 feet until the start of your next turn. If the creature is hit more than once by weapons that have this property, the Speed reduction doesn't exceed 10 feet.",gist:"on hit: -10 ft. Speed"},topple:{label:"Topple",description:"If you hit a creature with this weapon, you can force the creature to make a Constitution saving throw (DC 8 plus the ability modifier used to make the attack roll and your Proficiency Bonus). On a failed save, the creature has the Prone condition.",gist:"on fail: Prone"},vex:{label:"Vex",description:"If you hit a creature with this weapon and deal damage, you have Advantage on your next attack roll against that creature before the end of your next turn.",gist:"on hit: you gain Advantage next"}};function masteryGist(slug){var _a;return(_a=MASTERY[slug])==null?void 0:_a.gist}function masteryDerived(slug,abilityMod,proficiencyBonus){if(slug==="topple")return{label:"Save DC",value:8+proficiencyBonus+abilityMod};if(slug==="graze")return{label:"On miss",value:abilityMod};return void 0}var ABILITY_KEYS=["str","dex","con","int","wis","cha"];function isAbilityKey(k){return ABILITY_KEYS.includes(k)}function emptyAppliedBonuses(){return{ability_bonuses:{},ability_statics:{},save_bonus:0,save_terms:[],speed_bonuses:{walk:0,fly:null,swim:0,climb:0},speed_walk_set:0,speed_walk_set_terms:[],speed_terms:[],spell_attack:0,spell_save_dc:0,defenses:{resistances:[],immunities:[],vulnerabilities:[],condition_immunities:[]},informational:[],senses:{darkvision:0,blindsight:0,tremorsense:0,truesight:0}}}function unwrapSlug(item){const m=item.match(/^\[\[(.+)\]\]$/);return m?m[1]:null}function unwrapClassSlug(maybeWiki){if(!maybeWiki)return"";const m=/^\[\[([^\]]+)\]\]$/.exec(maybeWiki);return(m?m[1]:maybeWiki).toLowerCase()}function buildConditionContext(resolved,equippedSlots,registry){var _a,_b;return{derived:{equippedSlots},classList:(_a=resolved.definition.class)!=null?_a:[],race:resolved.definition.race,subclasses:((_b=resolved.definition.class)!=null?_b:[]).map(c=>c.subclass).filter(s=>typeof s==="string"&&s.length>0).map(unwrapClassSlug),registry}}function pushApply(outcome,field,source,pool,onApply){if(!outcome)return;if(outcome.kind==="applied")onApply(outcome.value);else if(outcome.kind==="informational"){pool.push({field,source,value:outcome.value,conditions:outcome.conditions})}}function isOtherSpeedMode(mode){return mode==="fly"||mode==="swim"||mode==="climb"||mode==="burrow"}function computeAppliedBonuses(resolved,_profs,registry,warnings){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p,_q,_r,_s,_t;const out=emptyAppliedBonuses();const equipment=(_a=resolved.definition.equipment)!=null?_a:[];const ctx=buildConditionContext(resolved,{},registry);for(let index=0;index<equipment.length;index++){const entry=equipment[index];const{entity,entityType}=resolveEntryEntity(entry,index,registry,resolved.infusions);if(!entity){const slug=unwrapSlug(entry.item);if(slug&&entry.equipped&&!((_b=resolved.infusions)==null?void 0:_b.views.has(index)))warnings.push(`Equipped item [[${slug}]] not found in compendium.`);continue}if(!itemBenefitsActive(entry,entity,registry,(_c=resolved.infusions)==null?void 0:_c.views.get(index)))continue;if(entityType!=="item")continue;const item=entity;const label=itemLabel(entry,item);const grant=(bucket,values)=>{for(const v of values!=null?values:[])if(typeof v==="string")pushDefenseGrant(out.defenses[bucket],v,label,void 0,{index,name:label})};grant("resistances",item.resist);grant("immunities",item.immune);grant("vulnerabilities",item.vulnerable);grant("condition_immunities",item.condition_immune);grant("resistances",(_d=entry.overrides)==null?void 0:_d.resist);grant("immunities",(_e=entry.overrides)==null?void 0:_e.immune);grant("vulnerabilities",(_f=entry.overrides)==null?void 0:_f.vulnerable);grant("condition_immunities",(_g=entry.overrides)==null?void 0:_g.condition_immune);const gs=(_h=item.grants)==null?void 0:_h.senses;if(gs){if(typeof gs.darkvision==="number")out.senses.darkvision=Math.max(out.senses.darkvision,gs.darkvision);if(typeof gs.blindsight==="number")out.senses.blindsight=Math.max(out.senses.blindsight,gs.blindsight);if(typeof gs.tremorsense==="number")out.senses.tremorsense=Math.max(out.senses.tremorsense,gs.tremorsense);if(typeof gs.truesight==="number")out.senses.truesight=Math.max(out.senses.truesight,gs.truesight)}const floor=(_j=(_i=item.modify_speed)==null?void 0:_i.static)==null?void 0:_j.walk;if(typeof floor==="number"&&floor>0){out.speed_walk_set=Math.max(out.speed_walk_set,floor);out.speed_walk_set_terms.push({source:label,amount:floor})}const activatedSpeed=isActivatedSpeedItem(String((_k=item.slug)!=null?_k:"")||((_l=unwrapSlug(entry.item))!=null?_l:entry.item),item);const itemSpeed=(mode,kind,amount)=>{if(!activatedSpeed&&isOtherSpeedMode(mode))out.speed_terms.push({mode,kind,source:label,amount})};for(const[mode,n]of Object.entries((_n=(_m=item.modify_speed)==null?void 0:_m.static)!=null?_n:{}))if(typeof n==="number"&&n>0)itemSpeed(mode,"grant",n);for(const[mode,to]of Object.entries((_p=(_o=item.modify_speed)==null?void 0:_o.equal)!=null?_p:{}))if(to==="walk")itemSpeed(mode,"walk",0);const b=item.bonuses;if(!b)continue;const saveSource=(_r=(_q=entry.overrides)==null?void 0:_q.name)!=null?_r:item.name;pushApply(readNumericBonus(b.saving_throws,ctx),"saving_throws",saveSource,out.informational,v=>{out.save_bonus+=v;out.save_terms.push({source:saveSource,amount:v})});pushApply(readNumericBonus(b.spell_attack,ctx),"spell_attack",item.name,out.informational,v=>{out.spell_attack+=v});pushApply(readNumericBonus(b.spell_save_dc,ctx),"spell_save_dc",item.name,out.informational,v=>{out.spell_save_dc+=v});if((_s=b.ability_scores)==null?void 0:_s.bonus){for(const[k,v]of Object.entries(b.ability_scores.bonus)){if(!isAbilityKey(k))continue;pushApply(readNumericBonus(v,ctx),`ability_scores.bonus.${k}`,item.name,out.informational,val=>{var _a2;out.ability_bonuses[k]=((_a2=out.ability_bonuses[k])!=null?_a2:0)+val})}}if((_t=b.ability_scores)==null?void 0:_t.static){for(const[k,n]of Object.entries(b.ability_scores.static)){if(!isAbilityKey(k)||typeof n!=="number")continue;const prev=out.ability_statics[k];if(prev===void 0){out.ability_statics[k]=n}else{if(n!==prev){warnings.push(`Multiple static ${k.toUpperCase()} bonuses on equipped+attuned items; using highest (${Math.max(prev,n)}).`)}out.ability_statics[k]=Math.max(prev,n)}}}if(b.speed){pushApply(readNumericBonus(b.speed.walk,ctx),"speed.walk",item.name,out.informational,v=>{out.speed_bonuses.walk+=v;out.speed_terms.push({mode:"walk",kind:"bonus",source:label,amount:v})});if(b.speed.fly==="walk"){out.speed_bonuses.fly="walk";itemSpeed("fly","walk",0)}else{pushApply(readNumericBonus(b.speed.fly,ctx),"speed.fly",item.name,out.informational,v=>{const cur=out.speed_bonuses.fly;out.speed_bonuses.fly=(typeof cur==="number"?cur:0)+v;itemSpeed("fly","grant",v)})}pushApply(readNumericBonus(b.speed.swim,ctx),"speed.swim",item.name,out.informational,v=>{out.speed_bonuses.swim+=v;itemSpeed("swim","grant",v)});pushApply(readNumericBonus(b.speed.climb,ctx),"speed.climb",item.name,out.informational,v=>{out.speed_bonuses.climb+=v;itemSpeed("climb","grant",v)})}}return out}function assignSlots(resolved,registry,warnings){var _a;const slots={};const eq=(_a=resolved.definition.equipment)!=null?_a:[];for(let i=0;i<eq.length;i++){const entry=eq[i];if(!entry.equipped||!entry.slot)continue;const{entity,entityType}=resolveEntryEntity(entry,i,registry,resolved.infusions);if(slots[entry.slot])continue;const placed={index:i,entity,entityType,entry};slots[entry.slot]=placed}for(let i=0;i<eq.length;i++){const entry=eq[i];if(!entry.equipped||entry.slot)continue;const{entity,entityType}=resolveEntryEntity(entry,i,registry,resolved.infusions);if(!entity||!entityType)continue;const defaultSlot=defaultSlotForType(entityType,entity,registry);if(!defaultSlot){if(isItemEntity(entity)&&typeof entity.base_item==="string"&&entity.base_item.length>0){warnings.push(`Magic item "${entity.name}" base_item ${entity.base_item} did not resolve to a base weapon or armor; not slotted (AC/attack not applied).`)}continue}const placed={index:i,entity,entityType,entry};if(defaultSlot==="mainhand"){if(!slots.mainhand)slots.mainhand=placed;else if(!slots.offhand)slots.offhand=placed}else if(!slots[defaultSlot]){slots[defaultSlot]=placed}}return slots}function pickShield(equippedSlots,equipment,registry,infusions){const slotted=equippedSlots.shield;const slottedArmor=effectiveArmor(slotted==null?void 0:slotted.entity,registry);if(slotted&&slottedArmor&&isShieldArmor(slottedArmor)){return{index:slotted.index,shield:slottedArmor,entity:slotted.entity,entry:slotted.entry}}for(let i=0;i<equipment.length;i++){const entry=equipment[i];if(!entry.equipped)continue;const{entity}=resolveEntryEntity(entry,i,registry,infusions);const armor=effectiveArmor(entity,registry);if(armor&&isShieldArmor(armor))return{index:i,shield:armor,entity,entry}}return null}function twoHandedShieldWarnings(equipment,registry,warnings,infusions){const equipped=equipment.flatMap((entry,i)=>{if(!entry.equipped)return[];const{entity}=resolveEntryEntity(entry,i,registry,infusions);return[{entry,entity}]});const isShield=e=>{const armor=effectiveArmor(e.entity,registry);return!!armor&&isShieldArmor(armor)};for(const e of equipped){if(!e.entity||!isTwoHandedWeapon(e.entity,registry))continue;if(!equipped.some(other=>other!==e&&isShield(other)))continue;warnings.push(`${e.entity.name} is two-handed and a Shield is also equipped.`)}}function computeAC(equippedSlots,resolved,mods,registry,warnings){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j;const breakdown=[];const armorSlot=equippedSlots.armor;const armorEntity=(_a=armorSlot==null?void 0:armorSlot.entity)!=null?_a:null;const armor=effectiveArmor(armorEntity,registry);if(isItemEntity(armorEntity)&&typeof armorEntity.base_item==="string"&&!armor){warnings.push(`Magic armor "${armorEntity.name}" base_item ${armorEntity.base_item} did not resolve to a base armor; AC not applied.`)}const acCtx=buildConditionContext(resolved,equippedSlots,registry);const skip=new Set;const slotBonus=slot=>{var _a2,_b2;const view=slot?(_a2=resolved.infusions)==null?void 0:_a2.views.get(slot.index):void 0;if(!slot||!(view==null?void 0:view.entity)||!isItemEntity(view.entity)||!itemBenefitsActive(slot.entry,view.entity,registry,view))return 0;const out=readNumericBonus((_b2=view.entity.bonuses)==null?void 0:_b2.ac,acCtx);if((out==null?void 0:out.kind)!=="applied")return 0;skip.add(slot.index);return out.value};const armorTerms=slotAcTerms(armor,armorSlot==null?void 0:armorSlot.entry);let ac=10;if(armor&&armorTerms.armor!==null){const armorBase=armorTerms.armor+slotBonus(armorSlot);ac=armorBase;breakdown.push({source:(_b=armorEntity==null?void 0:armorEntity.name)!=null?_b:armor.name,amount:armorBase,kind:"armor"});if(armor.ac.add_dex){const dexCap=(_c=armor.ac.dex_max)!=null?_c:Number.POSITIVE_INFINITY;const dexAdd=Math.min(mods.dex,dexCap);ac+=dexAdd;const capped=mods.dex>dexCap;breakdown.push({source:`DEX modifier${capped?" (capped)":""}`,amount:dexAdd,kind:"dex"})}}else{ac=10+mods.dex;breakdown.push({source:"Base",amount:10,kind:"unarmored"});breakdown.push({source:"DEX modifier",amount:mods.dex,kind:"dex"})}const acBonus=armorTerms.override;if(acBonus!==0){ac+=acBonus;breakdown.push({source:`${(_d=armorEntity==null?void 0:armorEntity.name)!=null?_d:"Armor"} (override)`,amount:acBonus,kind:"override"})}const picked=pickShield(equippedSlots,(_e=resolved.definition.equipment)!=null?_e:[],registry,resolved.infusions);if(picked){const{shield,entity:shieldEntity}=picked;const shieldTerms=slotAcTerms(shield,picked.entry);const n=shieldTerms.armor+slotBonus(picked);ac+=n;breakdown.push({source:(_f=shieldEntity==null?void 0:shieldEntity.name)!=null?_f:shield.name,amount:n,kind:"shield"});const shieldAcBonus=shieldTerms.override;if(shieldAcBonus!==0){ac+=shieldAcBonus;breakdown.push({source:`${(_g=shieldEntity==null?void 0:shieldEntity.name)!=null?_g:shield.name} (override)`,amount:shieldAcBonus,kind:"shield"})}}const acInformational=[];const acEquipment=(_h=resolved.definition.equipment)!=null?_h:[];for(let index=0;index<acEquipment.length;index++){if(skip.has(index))continue;const entry=acEquipment[index];const{entity,entityType}=resolveEntryEntity(entry,index,registry,resolved.infusions);if(!entity||entityType!=="item")continue;if(!itemBenefitsActive(entry,entity,registry,(_i=resolved.infusions)==null?void 0:_i.views.get(index)))continue;const item=entity;const out=readNumericBonus((_j=item.bonuses)==null?void 0:_j.ac,acCtx);if(!out)continue;if(out.kind==="applied"){ac+=out.value;breakdown.push({source:item.name,amount:out.value,kind:"item"})}else if(out.kind==="informational"){acInformational.push({field:"ac",source:item.name,value:out.value,conditions:out.conditions})}}return{ac,breakdown,informational:acInformational}}function hasProperty(weapon,prop){return weapon.properties.some(p=>p===prop)}function attackAbility(weapon,mods,weaponAbilities){const modes=classifyWeaponRange(weapon);const finesse=hasProperty(weapon,"finesse");if(modes.melee){const scoped=weaponAbilities.find(o2=>{var _a;return(_a=o2.weaponSlugs)==null?void 0:_a.includes(bareEntitySlug(weapon.slug))});const glob=weaponAbilities.find(o2=>!o2.weaponSlugs);const o=scoped!=null?scoped:glob;if(o)return o.ability;if(finesse)return mods.dex>=mods.str?"dex":"str";return"str"}return finesse&&mods.str>mods.dex?"str":"dex"}function pactScopedAbilities(overrides,pactPicked,isPact){if(!overrides.some(o=>o.pactWeapon))return overrides;return overrides.flatMap(o=>{if(!o.pactWeapon)return[o];return!pactPicked||isPact?[{ability:o.ability}]:[]})}function pactWeaponIndexes(resolved,registry){var _a;const pick=resolved.pactWeapon;if(!pick)return null;const out=new Set;const bare=bareEntitySlug(pick);((_a=resolved.definition.equipment)!=null?_a:[]).forEach((entry,i)=>{var _a2;if(typeof entry.item!=="string")return;const slugs=[unwrapSlug(entry.item),registry?(_a2=resolveBaseItem(entry.item,registry))==null?void 0:_a2.slug:void 0];if(slugs.some(s=>!!s&&(s===pick||bareEntitySlug(s)===bare)))out.add(i)});return out.size?out:null}function isWeaponSlugProficient(weapon,weaponSlug,profs){const wp=profs.weapons;if(wp.specific.some(e=>e===weaponSlug||normKey(e)===normKey(weapon.name)))return true;if(wp.specific.some(e=>qualifiedGrantCovers(e,weapon)))return true;const cat=weapon.category;if(typeof cat==="string"){if(/^simple\b/.test(cat)&&wp.categories.includes("simple"))return true;if(/^martial\b/.test(cat)&&wp.categories.includes("martial"))return true;if(wp.categories.includes(cat))return true}return false}function magicBonusesForWeaponEntry(entry,registry,ctx,index,infusions){var _a,_b,_c,_d;const{entity}=resolveEntryEntity(entry,index,registry,infusions);const ovr=(_a=entry.overrides)!=null?_a:{};const entryAttack=typeof ovr.bonus==="number"?ovr.bonus:0;const entryDamage=typeof ovr.damage_bonus==="number"?ovr.damage_bonus:0;const extra=typeof ovr.extra_damage==="string"?ovr.extra_damage:void 0;let itemAttack=0;let itemDamage=0;let sourceName;let itemName;let damageTypeOverride;let propertiesOverride;const informational=[];let itemRiders=[];let critRange;const conditionalCrits=[];if(entity&&isItemEntity(entity)){sourceName=entity.name;itemName=entity.name;damageTypeOverride=typeof entity.damage_type==="string"&&entity.damage_type.length>0?entity.damage_type:void 0;propertiesOverride=Array.isArray(entity.properties)&&entity.properties.length>0?entity.properties:void 0}if(entity&&isItemEntity(entity)&&itemBenefitsActive(entry,entity,registry,infusions==null?void 0:infusions.views.get(index))){const b=entity.bonuses;const atkOut=readNumericBonus(b==null?void 0:b.weapon_attack,ctx);const dmgOut=readNumericBonus(b==null?void 0:b.weapon_damage,ctx);if((atkOut==null?void 0:atkOut.kind)==="applied")itemAttack=atkOut.value;else if((atkOut==null?void 0:atkOut.kind)==="informational")informational.push({field:"weapon_attack",source:entity.name,value:atkOut.value,conditions:atkOut.conditions});if((dmgOut==null?void 0:dmgOut.kind)==="applied")itemDamage=dmgOut.value;else if((dmgOut==null?void 0:dmgOut.kind)==="informational")informational.push({field:"weapon_damage",source:entity.name,value:dmgOut.value,conditions:dmgOut.conditions});itemRiders=Array.isArray(entity.damage_riders)?entity.damage_riders.filter(r=>{var _a2;return((_a2=r.applies_to)!=null?_a2:"weapon")!=="spell"}).map(r=>({amount:r.amount,damage_type:r.damage_type,source:entity.name,...r.condition?{condition:r.condition}:{}})):[];for(const eff of itemRowEffects(entity)){if(eff.kind==="damage-bonus"&&((_b=eff.applies_to)!=null?_b:"weapon")!=="spell"){itemRiders.push({amount:eff.amount,damage_type:eff.damage_type,source:entity.name,...eff.condition?{condition:eff.condition}:{}})}else if(eff.kind==="crit-range"&&((_c=eff.applies_to)!=null?_c:"weapon")!=="spell"){if((_d=eff.condition)==null?void 0:_d.trim())conditionalCrits.push({minRoll:eff.min_roll,condition:eff.condition.trim(),source:entity.name});else critRange=Math.min(critRange!=null?critRange:20,eff.min_roll)}}}return{...critRange!==void 0&&critRange<20?{critRange}:{},...conditionalCrits.length?{conditionalCrits}:{},atk:itemAttack+entryAttack,dmg:itemDamage+entryDamage,extra,sourceName,itemName,damageTypeOverride,propertiesOverride,informational,riders:itemRiders}}function buildAttackRow(args){var _a,_b,_c,_d;const{id,name,weapon,baseDice,ability,mods,proficient,proficiencyBonus,magic,weaponMasteries}=args;const abilityMod=mods[ability];const pb=proficient?proficiencyBonus:0;const toHit=abilityMod+pb+magic.atk;const dmgFlat=abilityMod+magic.dmg;const formatDice=dice=>`${dice}${dmgFlat>=0?"+":""}${dmgFlat}`.replace(/\+0$/,"");const damageDice=formatDice(baseDice);const magicSource=magic.sourceName?`${magic.sourceName} bonus`:"Magic weapon";const toHitBreakdown=[{source:`${ability.toUpperCase()} modifier`,amount:abilityMod,kind:"ability"},{source:"Proficiency bonus",amount:proficient?proficiencyBonus:0,kind:"ability"},{source:magicSource,amount:magic.atk,kind:"item"}];const damageBreakdown=[{source:"Base damage",amount:0,kind:"ability"},{source:`${ability.toUpperCase()} modifier`,amount:abilityMod,kind:"ability"},{source:magicSource,amount:magic.dmg,kind:"item"}];const modes=classifyWeaponRange(weapon);const fmtRanged=r=>r.long>r.normal?`${r.normal}/${r.long} ft.`:`${r.normal} ft.`;const range=modes.melee?`${modes.melee.reach} ft.`:modes.ranged?fmtRanged(modes.ranged):void 0;const thrownRange=modes.melee&&modes.ranged?fmtRanged(modes.ranged):void 0;const stringProps=weapon.properties.filter(p=>typeof p==="string");const finalProps=(_a=magic.propertiesOverride)!=null?_a:stringProps;const row={id,name,...range!==void 0?{range}:{},...thrownRange!==void 0?{thrownRange}:{},toHit,damageDice,damageType:(_b=magic.damageTypeOverride)!=null?_b:weapon.damage.type,...(()=>{const riders=[...magic.riders,...magic.extra?[{amount:magic.extra}]:[]];return riders.length?{damageRiders:riders}:{}})(),weaponCategory:modes.melee?"melee":"ranged",properties:finalProps,proficient,breakdown:{toHit:toHitBreakdown,damage:damageBreakdown},informational:args.magic.informational.length>0?args.magic.informational:void 0,slotKey:args.slotKey,subLabel:formatWeaponSubLabel(weapon,finalProps,modes),actionCost:args.actionCost,versatile:args.versatileDice?{damageDice:formatDice(args.versatileDice)}:void 0,...magic.critRange!==void 0?{critRange:magic.critRange}:{},...((_c=magic.conditionalCrits)==null?void 0:_c.length)?{conditionalCrits:magic.conditionalCrits}:{}};const mSlug=(_d=weapon.mastery)==null?void 0:_d[0];if(mSlug&&proficient&&weaponMasteries.includes(bareEntitySlug(weapon.slug))){const g=MASTERY[mSlug];if(g){const derived=masteryDerived(mSlug,mods[ability],proficiencyBonus);row.mastery={slug:mSlug,label:g.label,description:g.description,gist:masteryGist(mSlug),...derived?{derived}:{}}}}return row}function buildUnarmedRow(mods,proficiencyBonus,spec){var _a;const candidates=["str",...(_a=spec==null?void 0:spec.abilities)!=null?_a:[]];let ability="str";for(const ab of candidates)if(mods[ab]>=mods[ability])ability=ab;const abilityMod=mods[ability];const toHit=abilityMod+proficiencyBonus;const flat=`${abilityMod>=0?"+":""}${abilityMod}`.replace(/^\+0$/,"");const damageDice=(spec==null?void 0:spec.dice)?`${spec.dice}${flat}`:String(Math.max(0,1+abilityMod));const label=`${ability.toUpperCase()} modifier`;return{id:"unarmed-strike",name:"Unarmed Strike",unarmed:true,range:"5 ft.",toHit,damageDice,damageType:"bludgeoning",properties:[],proficient:true,breakdown:{toHit:[{source:label,amount:abilityMod,kind:"ability"},{source:"Proficiency bonus",amount:proficiencyBonus,kind:"ability"}],damage:[{source:"Base damage",amount:(spec==null?void 0:spec.dice)?0:1,kind:"ability"},{source:label,amount:abilityMod,kind:"ability"}]},subLabel:"Unarmed",actionCost:"action"}}function buildFeatureAttackRows(resolved,mods,profs,proficiencyBonus,weaponAbilities=[]){var _a,_b,_c;const rows=[];const abilities=weaponAbilities.filter(o=>!o.pactWeapon);for(const rf of(_a=resolved.features)!=null?_a:[]){if(rf.renderSuppressed||rf.buildOnly)continue;const featureId=(_b=rf.feature.id)!=null?_b:rf.feature.name;((_c=rf.feature.attacks)!=null?_c:[]).forEach((a,n)=>{var _a2,_b2,_c2,_d,_e,_f,_g;if(!a.weapon_category||a.type!=="melee"&&a.type!=="ranged"||typeof a.damage!=="string"||!a.damage.trim())return;const long=(_c2=(_a2=a.range)==null?void 0:_a2.long)!=null?_c2:(_b2=a.range)==null?void 0:_b2.normal;const weapon={name:a.name,slug:`feature-attack_${featureId}_${n}`,category:`${a.weapon_category}-${a.type}`,damage:{dice:a.damage.trim(),type:(_d=a.damage_type)!=null?_d:""},properties:((_e=a.properties)!=null?_e:[]).map(p=>p.trim().toLowerCase()),...((_f=a.range)==null?void 0:_f.normal)!==void 0&&long!==void 0?{range:{normal:a.range.normal,long}}:{},...a.mastery?{mastery:[a.mastery.trim().toLowerCase()]}:{}};const proficient=isWeaponSlugProficient(weapon,weapon.slug,profs);const row=buildAttackRow({id:`feature-attack:${rf.source.kind}:${rf.source.slug}:${featureId}:${n}`,name:a.name,weapon,baseDice:weapon.damage.dice,ability:attackAbility(weapon,mods,abilities),mods,proficient,proficiencyBonus,magic:{atk:0,dmg:0,informational:[],riders:[]},actionCost:(_g=a.action)!=null?_g:WEAPON_DEFAULT_ACTION_COST,weaponMasteries:a.mastery?[bareEntitySlug(weapon.slug)]:[]});row.grantedBy=rf.feature.name;rows.push(row)})}return rows}function humanizeWeaponToken(s){return s.replace(/[-_]/g," ").replace(/(^|[\s(])\w/g,c=>c.toUpperCase())}function formatWeaponSubLabel(weapon,properties,modes){const parts=[];if(weapon.category){const cat=modes.melee&&/ranged/.test(weapon.category)?weapon.category.replace("ranged","melee"):weapon.category;parts.push(humanizeWeaponToken(cat))}if(properties.length>0)parts.push(properties.map(humanizeWeaponToken).join(", "));return parts.join(" \xB7 ")}function computeAttacks(equippedSlots,equipment,mods,profs,registry,warnings,proficiencyBonus,ctx,weaponMasteries,weaponAbilities=[],infusions,pactIndexes=null){var _a,_b;const rows=[];const rowFor=(index,entry,weapon,slotKey,versatileDice)=>{var _a2,_b2,_c,_d,_e;const slugFromEntry=(_a2=unwrapSlug(entry.item))!=null?_a2:weapon.slug;const proficient=isWeaponSlugProficient(weapon,slugFromEntry,profs)||isWeaponSlugProficient(weapon,weapon.slug,profs);if(!proficient){warnings.push(`Character not proficient with ${weapon.name}; proficiency bonus excluded.`)}const isPact=(pactIndexes==null?void 0:pactIndexes.has(index))===true;const ability=attackAbility(weapon,mods,pactScopedAbilities(weaponAbilities,pactIndexes!==null,isPact));const magic=magicBonusesForWeaponEntry(entry,registry,ctx,index,infusions);const ovr=(_b2=entry.overrides)!=null?_b2:{};const row=buildAttackRow({id:`${index}:standard`,name:(_d=(_c=ovr.name)!=null?_c:magic.itemName)!=null?_d:weapon.name,weapon,baseDice:weapon.damage.dice,ability,mods,proficient,proficiencyBonus,magic,slotKey,actionCost:(_e=ovr.action)!=null?_e:WEAPON_DEFAULT_ACTION_COST,versatileDice,weaponMasteries});if(isPact)row.pactWeapon=true;return row};const handedSlots=[{key:"mainhand",placed:equippedSlots.mainhand},{key:"offhand",placed:equippedSlots.offhand}];for(const{key,placed}of handedSlots){if(!placed)continue;const{entity,entry}=placed;if(!entity)continue;const weapon=effectiveWeapon(entity,registry);if(!weapon){if(isItemEntity(entity)&&typeof entity.base_item==="string"&&!resolveBaseItem(entity.base_item,registry)){warnings.push(`Magic weapon ${entity.name} references missing base_item ${entity.base_item}.`)}continue}const versatileDice=key==="mainhand"&&hasProperty(weapon,"versatile")&&typeof weapon.damage.versatile_dice==="string"&&!equippedSlots.offhand?weapon.damage.versatile_dice:void 0;rows.push(rowFor(placed.index,entry,weapon,key,versatileDice))}const handIndex=new Set([(_a=equippedSlots.mainhand)==null?void 0:_a.index,(_b=equippedSlots.offhand)==null?void 0:_b.index]);equipment.forEach((entry,index)=>{if(!entry.equipped||handIndex.has(index))return;const{entity}=resolveEntryEntity(entry,index,registry,infusions);const weapon=effectiveWeapon(entity,registry);if(!weapon)return;rows.push(rowFor(index,entry,weapon))});return rows}function coerceWeight(raw){if(typeof raw==="number"&&Number.isFinite(raw)&&raw>=0)return raw;if(typeof raw==="string"){const n=Number.parseFloat(raw);if(Number.isFinite(n)&&n>=0)return n}return 0}function computeCarriedWeight(resolved,registry){var _a;const equipment=(_a=resolved.definition.equipment)!=null?_a:[];const view=resolveContainment(equipment,registry);const weightlessContainer=equipment.map(entry=>{var _a2,_b,_c;const data=(_a2=resolveBaseItem(entry.item,registry))==null?void 0:_a2.data;return((_c=(_b=data==null?void 0:data.container)==null?void 0:_b.capacity)==null?void 0:_c.weightless)===true});const exempt=i=>{for(let p=view.parentOf[i];p!==null;p=view.parentOf[p])if(weightlessContainer[p])return true;return false};let total=0;equipment.forEach((entry,i)=>{if(exempt(i))return;const found=resolveBaseItem(entry.item,registry);if(!found)return;const entity=found.data;const w=coerceWeight(entity.weight);if(w===0)return;const qty=typeof entry.qty==="number"&&entry.qty>=0?entry.qty:1;total+=w*qty});return total}function computeSlotsAndAttacks(resolved,mods,profs,registry,warnings,proficiencyBonus,weaponAbilities=[],weaponMasteries=[],attunementFloor=0){var _a,_b,_c,_d,_e;const equippedSlots=assignSlots(resolved,registry,warnings);twoHandedShieldWarnings((_a=resolved.definition.equipment)!=null?_a:[],registry,warnings,resolved.infusions);const overrides=(_b=resolved.definition.overrides)!=null?_b:{};const acOut=computeAC(equippedSlots,resolved,mods,registry,warnings);const ctx=buildConditionContext(resolved,equippedSlots,registry);const attacks=computeAttacks(equippedSlots,(_c=resolved.definition.equipment)!=null?_c:[],mods,profs,registry,warnings,proficiencyBonus,ctx,weaponMasteries,weaponAbilities,resolved.infusions,pactWeaponIndexes(resolved,registry));return{ac:acOut.ac,acBreakdown:acOut.breakdown,acInformational:acOut.informational,attacks,equippedSlots,carriedWeight:computeCarriedWeight(resolved,registry),attunementUsed:((_d=resolved.definition.equipment)!=null?_d:[]).filter(e=>e.attuned).length,attunementLimit:(_e=overrides.attunement_limit)!=null?_e:Math.max(3,attunementFloor)}}export{emptyAppliedBonuses,computeAppliedBonuses,pactWeaponIndexes,isWeaponSlugProficient,buildUnarmedRow,buildFeatureAttackRows,computeSlotsAndAttacks};
|
package/dist/chunk-GD7WRCNH.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{normalizeRollScope}from"./chunk-FOLHTMSC.js";import{toProfSlug}from"./chunk-VTQ4RWEG.js";import{memberSpellTargets}from"./chunk-WAUNLUFQ.js";import{heldPicks}from"./chunk-PKIMOVQG.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{bareEntitySlug}from"./chunk-63YJPWTM.js";import{normalizeAbility}from"./chunk-EVT7MGAC.js";function emptyFeatureEffectTotals(){return{initiative_bonus:0,initiative_terms:[],initiative_amount_terms:[],skill_bonus_terms:[],save_bonus_terms:[],half_proficiency_terms:[],hp_per_level_bonus:0,hp_per_level_terms:[],speed_walk_bonus:0,speed_walk_terms:[],speed_terms:[],ignore_armor_strength:[],speed_walk_set:0,attunement_set:0,ability_bonus:{},senses:{darkvision:0,blindsight:0,tremorsense:0,truesight:0},ac_terms:[],resistances:[],immunities:[],vulnerabilities:[],condition_immunities:[],proficiencies:{skills:[],skillExpertise:[],tools:[],languages:[],saves:[],armor:[],weapons:[]},weaponAbilities:[],rollModifiers:[],saveOutcomes:[],critRange:20,conditionalCrits:[],extraAttack:0,scopedExtraAttacks:[],attackNotes:[],damageBonuses:[],spellDamageBonuses:[]}}function pushUnique(list,value){const key=value.trim().toLowerCase();if(!key)return;if(!list.some(v=>v.trim().toLowerCase()===key))list.push(value.trim())}function pushDefenseGrant(list,value,source,condition,item){var _a;const key=value.trim().toLowerCase();if(!key)return;const existing=list.find(g=>g.value.trim().toLowerCase()===key);if(existing){if(!existing.sources.includes(source))existing.sources.push(source);if(!existing.condition&&condition)existing.condition=condition;if(item)mergeDefenseItems((_a=existing.items)!=null?_a:existing.items=[],[item]);return}list.push({value:value.trim(),sources:[source],...condition?{condition}:{},...item?{items:[item]}:{}})}function mergeDefenseItems(into,from){for(const it of from)if(!into.some(x=>x.index===it.index))into.push({...it})}function ownerItem(owner,label){return(owner==null?void 0:owner.kind)==="item"?{index:owner.index,name:label}:void 0}var NAMED_COLUMN=/^column\(\s*'([^']+)'\s*\)$/;function foldsNow(rf,activeBuffs){if(rf.feature.activatable!==true)return true;const id=rf.feature.id;return!!id&&activeBuffs.has(id)}function assembleEffectFeatures(resolved){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j;const activeBuffs=new Set((_b=(_a=resolved.state)==null?void 0:_a.active_buffs)!=null?_b:[]);const featureIds=new Set(((_c=resolved.features)!=null?_c:[]).map(f=>f.feature.id).filter(id=>!!id));const aliases=[];for(const pool of(_d=resolved.pools)!=null?_d:[]){for(const entry of[...(_e=pool.selected)!=null?_e:[],...(_f=pool.grants)!=null?_f:[]]){if(activeBuffs.has(entry.slug))continue;const bare=bareEntitySlug(entry.slug);for(const stored of activeBuffs){if(featureIds.has(stored))continue;if(bareEntitySlug(stored)===bare){aliases.push(entry.slug);break}}}}for(const a of aliases)activeBuffs.add(a);const buffFeatures=[];const pushBoon=(item,pool)=>{var _a2,_b2,_c2,_d2,_e2,_f2,_g2,_h2,_i2,_j2,_k;const e=item.entity;if(!e||item.itemBound===true||((_b2=(_a2=e.effects)==null?void 0:_a2.length)!=null?_b2:0)===0)return;const block=(_f2=(_e2=(_d2=(_c2=resolved.classes)==null?void 0:_c2[pool.classIndex])==null?void 0:_d2.choices)==null?void 0:_e2[pool.anchorLevel])!=null?_f2:{};const spellTargets=memberSpellTargets(e,id=>{var _a3;return block[`${pool.id}:${(_a3=item.key)!=null?_a3:item.slug}:${id}`]});buffFeatures.push({feature:{id:item.slug,name:e.name,activatable:(_g2=e.activatable)!=null?_g2:false,effects:e.effects},source:{kind:"class",slug:(_k=(_j2=(_i2=(_h2=resolved.classes)==null?void 0:_h2[pool.classIndex])==null?void 0:_i2.entity)==null?void 0:_j2.slug)!=null?_k:pool.id,level:pool.anchorLevel},...spellTargets?{spellTargets}:{}})};for(const pool of(_g=resolved.pools)!=null?_g:[]){for(const sel of heldPicks(pool))pushBoon(sel,pool);for(const g of(_h=pool.grants)!=null?_h:[])pushBoon(g,pool)}return{features:[...(_i=resolved.features)!=null?_i:[],...buffFeatures,...(_j=resolved.itemFeatures)!=null?_j:[]],activeBuffs}}function foldsOnSelf(eff){if(eff.subject===void 0||eff.subject==="self")return true;warnOnce(eff.subject,`archivist: unrecognised effect subject "${eff.subject}" (only "self" folds)`);return false}function selfEffectsOf(f){var _a;return((_a=f.effects)!=null?_a:[]).filter(foldsOnSelf)}function computeFeatureEffects(features,opts){var _a,_b,_c;const out=emptyFeatureEffectTotals();for(const rf of features){if(!foldsNow(rf,(_a=opts==null?void 0:opts.activeBuffs)!=null?_a:new Set))continue;const level=(_b=opts==null?void 0:opts.levelFor)==null?void 0:_b.call(opts,rf.source);for(const eff of selfEffectsOf(rf.feature)){const effect=columnScaledRider(eff,rf,level,opts==null?void 0:opts.tableDiceFor,opts==null?void 0:opts.tableCellFor);if(effect)applyEffect(out,effect,(_c=rf.feature.name)!=null?_c:"Feature",level,rf.source,rf.spellTargets)}}return out}function classifyProficiencyEffect(eff){if(eff.kind!=="proficiency")return null;const raw=eff.value;const expertise=eff.expertise===true;switch(eff.proficiency_type){case"skill":return{bucket:"skills",value:toProfSlug(raw),raw,expertise};case"tool":return{bucket:"tools",value:toProfSlug(raw),raw,expertise};case"language":return{bucket:"languages",value:toProfSlug(raw),raw,expertise};case"armor":return{bucket:"armor",value:raw.toLowerCase(),raw,expertise};case"weapon":return{bucket:"weapons",value:raw.toLowerCase(),raw,expertise};default:{const ab=normalizeAbility(raw);return ab?{bucket:"saves",value:ab,raw,expertise}:null}}}function collectProficiencyEffectGrants(features,activeBuffs){const out={skills:[],tools:[],languages:[],saves:[],armor:[],weapons:[]};for(const rf of features){if(!foldsNow(rf,activeBuffs))continue;for(const eff of selfEffectsOf(rf.feature)){const c=classifyProficiencyEffect(eff);if(!c)continue;out[c.bucket].push({value:c.value,raw:c.raw,sourceKind:rf.source.kind,sourceSlug:rf.source.slug,...c.expertise?{expertise:true}:{}})}}return out}function scaled(base,key,scalesAt,level){if(level===void 0||!(scalesAt==null?void 0:scalesAt.length))return base;let best=base;let bestLevel=-1;for(const step of scalesAt){if(step.level>level||step.level<=bestLevel)continue;const v=step[key];if(typeof v!=="number")continue;best=v;bestLevel=step.level}return best}function columnScaledRider(eff,rf,level,tableDiceFor,tableCellFor){var _a;if(eff.kind!=="damage-bonus")return eff;const named=NAMED_COLUMN.exec(eff.amount.trim());if(named){const cell=(_a=tableCellFor==null?void 0:tableCellFor(rf.source,named[1]))!=null?_a:null;return cell?{...eff,amount:cell}:null}if(level===void 0||!tableDiceFor)return eff;const src=rf.source;const column=rf.feature.name;if(src.kind!=="class"&&src.kind!=="subclass"||!column)return eff;const atGain=tableDiceFor(src,column,src.level);if(!atGain||atGain.toLowerCase()!==eff.amount.trim().toLowerCase())return eff;const now=tableDiceFor(src,column,level);return now?{...eff,amount:now}:eff}function riderScope(appliesTo){if(appliesTo===void 0||appliesTo==="all"||appliesTo==="spell")return void 0;return Array.isArray(appliesTo)?[...appliesTo]:[appliesTo]}function applyEffect(out,eff,label,level,owner,targets){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o;switch(eff.kind){case"initiative-bonus":if(typeof eff.value==="number"){out.initiative_bonus+=eff.value;out.initiative_terms.push({label,value:eff.value})}else if(typeof eff.amount==="string"){out.initiative_amount_terms.push({label,amount:eff.amount,...owner?{owner}:{}})}break;case"skill-bonus":out.skill_bonus_terms.push({skills:eff.skills.map(toProfSlug),ability:eff.ability,minimum:(_a=eff.minimum)!=null?_a:0,label});break;case"save-bonus":out.save_bonus_terms.push({saves:[...(_b=eff.saves)!=null?_b:[]],ability:eff.ability,minimum:(_c=eff.minimum)!=null?_c:0,...eff.inactive_while?{inactiveWhile:eff.inactive_while}:{},label});break;case"half-proficiency":out.half_proficiency_terms.push({skills:((_d=eff.skills)!=null?_d:[]).map(toProfSlug),round:(_e=eff.round)!=null?_e:"down",label});break;case"hp-per-level-bonus":out.hp_per_level_bonus+=eff.value;out.hp_per_level_terms.push({label,value:eff.value});break;case"speed-bonus":{const gate=eff.inactive_while===void 0?void 0:[].concat(eff.inactive_while);const qualifiers={...eff.condition?{condition:eff.condition}:{},...gate?{inactiveWhile:gate}:{}};if(eff.equal_to==="walk"){out.speed_terms.push({mode:eff.mode,label,value:0,set:false,equalsWalk:true,...qualifiers});break}const value=scaled((_f=eff.value)!=null?_f:0,"value",eff.scales_at,level);out.speed_terms.push({mode:eff.mode,label,value,set:eff.set===true,...qualifiers});if(eff.mode==="walk"&&!gate){if(eff.set)out.speed_walk_set=Math.max(out.speed_walk_set,value);else{out.speed_walk_bonus+=value;out.speed_walk_terms.push({label,value})}}break}case"speed-rule":if(eff.flag==="ignore-armor-strength")out.ignore_armor_strength.push(label);break;case"attunement-limit":{out.attunement_set=Math.max(out.attunement_set,scaled(eff.value,"value",eff.scales_at,level));break}case"sense":out.senses[eff.type]=Math.max(out.senses[eff.type],eff.range);break;case"resistance":pushDefenseGrant(out.resistances,eff.damage_type,label,eff.condition,ownerItem(owner,label));break;case"immunity":pushDefenseGrant(out.immunities,eff.damage_type,label,eff.condition,ownerItem(owner,label));break;case"vulnerability":pushDefenseGrant(out.vulnerabilities,eff.damage_type,label,eff.condition,ownerItem(owner,label));break;case"immune-condition":if(!eff.while)pushDefenseGrant(out.condition_immunities,eff.condition,label,void 0,ownerItem(owner,label));else if((owner==null?void 0:owner.kind)==="item")pushDefenseGrant(out.condition_immunities,eff.condition,label,eff.while,ownerItem(owner,label));break;case"proficiency":{const c=classifyProficiencyEffect(eff);if(!c)break;if(c.bucket==="saves"){pushUnique(out.proficiencies.saves,c.value)}else{pushUnique(out.proficiencies[c.bucket],c.value)}if(c.expertise&&c.bucket==="skills")pushUnique(out.proficiencies.skillExpertise,c.value);break}case"ac-bonus":out.ac_terms.push({value:eff.value,requires_armor:eff.requires_armor===true,label,condition:eff.condition});break;case"weapon-ability":{if(eff.ability!=="spellcasting"){const w=eff.weapons;if(w==="pact-weapon"){out.weaponAbilities.push({ability:eff.ability,pactWeapon:true});break}const weaponSlugs=!w||w==="chosen"?void 0:Array.isArray(w)?w.map(bareEntitySlug):[bareEntitySlug(w)];out.weaponAbilities.push({ability:eff.ability,weaponSlugs})}break}case"roll-modifier":{const rolls=eff.roll==="any"?["ability-check","saving-throw","attack"]:[eff.roll];const scopes=(_g=normalizeRollScope(eff.scope,rolls[0]))!=null?_g:[eff.scope];for(const roll of rolls)for(const scope of scopes)out.rollModifiers.push({mode:eff.mode,roll,scope,condition:eff.condition,label});break}case"save-outcome":out.saveOutcomes.push({ability:eff.ability==="any"?void 0:eff.ability,on_success:eff.on_success,on_failure:eff.on_failure,appliesTo:(_h=eff.applies_to)!=null?_h:void 0,condition:eff.condition,label});break;case"crit-range":if(((_i=eff.applies_to)!=null?_i:"weapon")==="spell")break;if((_j=eff.condition)==null?void 0:_j.trim())out.conditionalCrits.push({minRoll:eff.min_roll,condition:eff.condition.trim(),source:label});else out.critRange=Math.min(out.critRange,eff.min_roll);break;case"extra-attack":{const count=scaled(eff.count,"count",eff.scales_at,level);const scope=riderScope(eff.applies_to);if(scope)out.scopedExtraAttacks.push({count,scope});else out.extraAttack=Math.max(out.extraAttack,count)}break;case"reroll-damage":{const qualifiers=[eff.once_per_die?"once/die":"",(_l=(_k=eff.condition)==null?void 0:_k.trim())!=null?_l:""].filter(q=>q!=="");out.attackNotes.push(`Reroll ${eff.max_reroll}s${qualifiers.length?` (${qualifiers.join(", ")})`:""}`)}break;case"attack-rule":if(eff.flag==="no-ranged-in-melee-disadvantage")out.attackNotes.push("No disadvantage firing in melee");break;case"damage-bonus":if(((_m=eff.applies_to)!=null?_m:"weapon")!=="spell"){const scope=riderScope(eff.applies_to);out.damageBonuses.push({amount:eff.amount,damage_type:eff.damage_type,source:label,...eff.condition?{condition:eff.condition}:{},...scope?{scope}:{},...owner?{owner}:{}})}if(eff.applies_to==="spell"||eff.applies_to==="all"){const spellScope=(_n=eff.spell_scope)!=null?_n:eff.applies_to==="all"?{}:void 0;out.spellDamageBonuses.push({amount:eff.amount,damage_type:eff.damage_type,source:label,...eff.condition?{condition:eff.condition}:{},...owner?{owner}:{},...targets?{targets}:{},...spellScope?{scope:spellScope}:{}})}break;case"ability-score-increase":if(eff.abilities==="chosen")break;for(const ab of eff.abilities)out.ability_bonus[ab]=((_o=out.ability_bonus[ab])!=null?_o:0)+eff.amount;break;default:break}}export{emptyFeatureEffectTotals,pushDefenseGrant,mergeDefenseItems,foldsNow,assembleEffectFeatures,foldsOnSelf,selfEffectsOf,computeFeatureEffects,classifyProficiencyEffect,collectProficiencyEffectGrants};
|