@swrpg-online/dice 1.4.0 → 2.0.0

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e="ADVANTAGE",a="THREAT",t="TRIUMPH",s="DESPAIR",i=[{description:"Recover one strain (may be applied more than once).",cost:{[e]:1,[t]:1}},{description:"Add a boost die to the next allied active character's check.",cost:{[e]:1,[t]:1}},{description:"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.",cost:{[e]:1,[t]:1}},{description:"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Activate a weapon quality (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.",cost:{[e]:2,[t]:1}},{description:"Add a setback die to the targeted character's next check.",cost:{[e]:2,[t]:1}},{description:"Add a boost die to any allied character's next check, including that of the active character.",cost:{[e]:2,[t]:1}},{description:"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.",cost:{[e]:3,[t]:1}},{description:"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.",cost:{[e]:3,[t]:1}},{description:"Gain + 1 melee or ranged defense until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"Force the target to drop a melee or ranged weapon they are wielding.",cost:{[e]:3,[t]:1}},{description:"Upgrade the difficulty of the targeted character's next check.",cost:{[t]:1}},{description:"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.",cost:{[t]:1}},{description:"Upgrade any allied character's next check, including that of the current active character.",cost:{[t]:1}},{description:"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.",cost:{[t]:2}},{description:"The active character suffers 1 strain.",cost:{[a]:1,[s]:1}},{description:"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.",cost:{[a]:1,[s]:1}},{description:"An opponent may immediately perform one free maneuver in response to the active character's check.",cost:{[a]:2,[s]:1}},{description:"Add a boost die to the targeted character's next check.",cost:{[a]:1,[s]:1}},{description:"The active character or an allied character suffers a setback die on their next action.",cost:{[a]:2,[s]:1}},{description:"The active character falls prone.",cost:{[a]:3,[s]:1}},{description:"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.",cost:{[a]:3,[s]:1}},{description:"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.",cost:{[s]:1}},{description:"Upgrade the difficulty of an allied character's next check, including that of the current active character.",cost:{[s]:1}},{description:"The tool or melee weapon the character is using becomes damaged.",cost:{[s]:1}}];const r=e=>Math.floor(Math.random()*e)+1,c=e=>{switch(e){case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},d=e=>{switch(e){case 3:case 4:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},n=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},u=e=>{switch(e){case 2:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 3:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},o=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:case 8:case 9:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:1,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},h=e=>{switch(e){case 2:case 3:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:case 9:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:1,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},l=e=>{switch(e){case 1:case 2:case 3:case 4:case 5:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:1,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:2,darkSide:0};case 8:case 9:case 10:case 11:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:1};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:2};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}};exports.applyTalentModifiers=(e,a)=>({...e,automaticSuccesses:(e.automaticSuccesses||0)+(a.automaticSuccesses||0),automaticFailures:(e.automaticFailures||0)+(a.automaticFailures||0),automaticAdvantages:(e.automaticAdvantages||0)+(a.automaticAdvantages||0),automaticThreats:(e.automaticThreats||0)+(a.automaticThreats||0),automaticTriumphs:(e.automaticTriumphs||0)+(a.automaticTriumphs||0),automaticDespairs:(e.automaticDespairs||0)+(a.automaticDespairs||0),upgradeAbility:(e.upgradeAbility||0)+(a.upgradeAbility||0),upgradeDifficulty:(e.upgradeDifficulty||0)+(a.upgradeDifficulty||0),downgradeProficiency:(e.downgradeProficiency||0)+(a.downgradeProficiency||0),downgradeChallenge:(e.downgradeChallenge||0)+(a.downgradeChallenge||0)}),exports.createCombatCheck=(e,a,t=0,s)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,a),boostDice:Math.max(0,t),...s}),exports.createDifficultyPool=(e,a=0,t)=>({difficultyDice:Math.max(0,e),challengeDice:Math.max(0,a),...t}),exports.createOpposedCheck=(e,a,t,s=0,i)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,a),difficultyDice:Math.max(0,t),challengeDice:Math.max(0,s),...i}),exports.createSkillCheck=(e,a,t)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,a),...t}),exports.roll=(e,a)=>{var t,s,p,g,f,m,v,S,y;const k=(e=>{const a={...e};if(e.upgradeAbility&&e.upgradeAbility>0){let t=e.upgradeAbility;const s=a.abilityDice||0,i=Math.min(s,t);a.abilityDice=s-i,a.proficiencyDice=(a.proficiencyDice||0)+i,t-=i,t>0&&(a.proficiencyDice=(a.proficiencyDice||0)+t)}if(e.upgradeDifficulty&&e.upgradeDifficulty>0){let t=e.upgradeDifficulty;const s=a.difficultyDice||0,i=Math.min(s,t);a.difficultyDice=s-i,a.challengeDice=(a.challengeDice||0)+i,t-=i,t>0&&(a.challengeDice=(a.challengeDice||0)+t)}if(e.downgradeProficiency&&e.downgradeProficiency>0){const t=a.proficiencyDice||0,s=Math.min(t,e.downgradeProficiency);a.proficiencyDice=t-s,a.abilityDice=(a.abilityDice||0)+s}if(e.downgradeChallenge&&e.downgradeChallenge>0){const t=a.challengeDice||0,s=Math.min(t,e.downgradeChallenge);a.challengeDice=t-s,a.difficultyDice=(a.difficultyDice||0)+s}return a})(e),b=null!==(t=k.boostDice)&&void 0!==t?t:0,D=null!==(s=k.abilityDice)&&void 0!==s?s:0,x=null!==(p=k.proficiencyDice)&&void 0!==p?p:0,w=null!==(g=k.setBackDice)&&void 0!==g?g:0,M=null!==(f=k.difficultyDice)&&void 0!==f?f:0,T=null!==(m=k.challengeDice)&&void 0!==m?m:0,A=null!==(v=k.forceDice)&&void 0!==v?v:0,$=null!==(S=null==a?void 0:a.maxDicePerType)&&void 0!==S?S:100,C=null!==(y=null==a?void 0:a.maxTotalDice)&&void 0!==y?y:500,P=Math.max(0,Math.min(b,$)),j=Math.max(0,Math.min(D,$)),O=Math.max(0,Math.min(x,$)),E=Math.max(0,Math.min(w,$)),G=Math.max(0,Math.min(M,$)),I=Math.max(0,Math.min(T,$)),R=Math.max(0,Math.min(A,$)),F=b>$||D>$||x>$||w>$||M>$||T>$||A>$,N=P+j+O+E+G+I+R;if(N>C)throw new Error(`Total dice count (${N}) exceeds maximum allowed (${C}). Please reduce the number of dice in your pool.`);if(F&&(null==a?void 0:a.throwOnLimitExceeded)){const e=[];throw b>$&&e.push(`boost: ${b}`),D>$&&e.push(`ability: ${D}`),x>$&&e.push(`proficiency: ${x}`),w>$&&e.push(`setback: ${w}`),M>$&&e.push(`difficulty: ${M}`),T>$&&e.push(`challenge: ${T}`),A>$&&e.push(`force: ${A}`),new Error(`Dice counts exceed per-type limit (${$}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const U=[];for(let e=0;e<P;e++){const e=r(6);U.push({type:"boost",roll:e,result:c(e)})}for(let e=0;e<j;e++){const e=r(8);U.push({type:"ability",roll:e,result:n(e)})}for(let e=0;e<O;e++){const e=r(12);U.push({type:"proficiency",roll:e,result:o(e)})}for(let e=0;e<E;e++){const e=r(6);U.push({type:"setback",roll:e,result:d(e)})}for(let e=0;e<G;e++){const e=r(8);U.push({type:"difficulty",roll:e,result:u(e)})}for(let e=0;e<I;e++){const e=r(12);U.push({type:"challenge",roll:e,result:h(e)})}for(let e=0;e<R;e++){const e=r(12);U.push({type:"force",roll:e,result:l(e)})}const q={successes:e.automaticSuccesses,failures:e.automaticFailures,advantages:e.automaticAdvantages,threats:e.automaticThreats,triumphs:e.automaticTriumphs,despairs:e.automaticDespairs},L=((e,a)=>{const t=e.reduce((e,a)=>({successes:e.successes+a.successes,failures:e.failures+a.failures,advantages:e.advantages+a.advantages,threats:e.threats+a.threats,triumphs:e.triumphs+a.triumphs,despair:e.despair+a.despair,lightSide:e.lightSide+(a.lightSide||0),darkSide:e.darkSide+(a.darkSide||0)}),{successes:(null==a?void 0:a.successes)||0,failures:(null==a?void 0:a.failures)||0,advantages:(null==a?void 0:a.advantages)||0,threats:(null==a?void 0:a.threats)||0,triumphs:(null==a?void 0:a.triumphs)||0,despair:(null==a?void 0:a.despairs)||0,lightSide:0,darkSide:0});let s=0,i=0;t.successes===t.failures?(s=0,i=0):t.successes>t.failures?s=t.successes-t.failures:i=t.failures-t.successes;let r=0,c=0;return t.advantages===t.threats?(r=0,c=0):t.advantages>t.threats?r=t.advantages-t.threats:c=t.threats-t.advantages,{successes:s,failures:i,advantages:r,threats:c,triumphs:t.triumphs,despair:t.despair,lightSide:t.lightSide,darkSide:t.darkSide}})(U.map(e=>e.result),q);if(null==a?void 0:a.hints){const e=i.filter(e=>{const{cost:a}=e;return Object.entries(a).some(([e,a])=>{const t=e.toLowerCase()+"s",s=L[t];return"number"==typeof s&&(void 0!==a&&a>0&&s>=a)})});L.hints=e.map(e=>`${function(e){if(!e.cost||0===Object.keys(e.cost).length)return"No cost";const a=Object.entries(e.cost).filter(([e,a])=>a&&a>0).map(([e,a])=>`${a} ${e.charAt(0).toUpperCase()+e.toLowerCase().slice(1)}${a>1?"s":""}`);return a.length>1?a.join(" OR "):a.length>0?a[0]:"No cost"}(e)} - ${e.description}`)}return{results:U,summary:L}};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e={SUCCESS:"SUCCESS",FAILURE:"FAILURE",ADVANTAGE:"ADVANTAGE",THREAT:"THREAT",TRIUMPH:"TRIUMPH",DESPAIR:"DESPAIR",LIGHT:"LIGHT",DARK:"DARK"},t=[{description:"Recover one strain (may be applied more than once).",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Add a boost die to the next allied active character's check.",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Activate a weapon quality (Advantage cost may vary).",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.",cost:{[e.ADVANTAGE]:2,[e.TRIUMPH]:1}},{description:"Add a setback die to the targeted character's next check.",cost:{[e.ADVANTAGE]:2,[e.TRIUMPH]:1}},{description:"Add a boost die to any allied character's next check, including that of the active character.",cost:{[e.ADVANTAGE]:2,[e.TRIUMPH]:1}},{description:"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Gain + 1 melee or ranged defense until the end of the active character's next turn.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Force the target to drop a melee or ranged weapon they are wielding.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Upgrade the difficulty of the targeted character's next check.",cost:{[e.TRIUMPH]:1}},{description:"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.",cost:{[e.TRIUMPH]:1}},{description:"Upgrade any allied character's next check, including that of the current active character.",cost:{[e.TRIUMPH]:1}},{description:"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.",cost:{[e.TRIUMPH]:2}},{description:"The active character suffers 1 strain.",cost:{[e.THREAT]:1,[e.DESPAIR]:1}},{description:"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.",cost:{[e.THREAT]:1,[e.DESPAIR]:1}},{description:"An opponent may immediately perform one free maneuver in response to the active character's check.",cost:{[e.THREAT]:2,[e.DESPAIR]:1}},{description:"Add a boost die to the targeted character's next check.",cost:{[e.THREAT]:1,[e.DESPAIR]:1}},{description:"The active character or an allied character suffers a setback die on their next action.",cost:{[e.THREAT]:2,[e.DESPAIR]:1}},{description:"The active character falls prone.",cost:{[e.THREAT]:3,[e.DESPAIR]:1}},{description:"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.",cost:{[e.THREAT]:3,[e.DESPAIR]:1}},{description:"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.",cost:{[e.DESPAIR]:1}},{description:"Upgrade the difficulty of an allied character's next check, including that of the current active character.",cost:{[e.DESPAIR]:1}},{description:"The tool or melee weapon the character is using becomes damaged.",cost:{[e.DESPAIR]:1}}];const a={1:{},2:{},3:{successes:1},4:{successes:1,advantages:1},5:{successes:1,advantages:1},6:{advantages:1}},s={1:{},2:{},3:{failures:1},4:{failures:1},5:{threats:1},6:{threats:1}},i={1:{},2:{successes:1},3:{successes:1},4:{successes:2},5:{advantages:1},6:{advantages:1},7:{successes:1,advantages:1},8:{advantages:2}},r={1:{},2:{failures:1},3:{failures:2},4:{threats:1},5:{threats:1},6:{threats:1},7:{threats:2},8:{failures:1,threats:1}},c={1:{},2:{successes:1},3:{successes:1},4:{successes:2},5:{successes:2},6:{advantages:1},7:{successes:1,advantages:1},8:{successes:1,advantages:1},9:{successes:1,advantages:1},10:{advantages:2},11:{advantages:2},12:{triumphs:1}},o={1:{},2:{failures:1},3:{failures:1},4:{failures:2},5:{failures:2},6:{threats:1},7:{threats:1},8:{failures:1,threats:1},9:{failures:1,threats:1},10:{threats:2},11:{threats:2},12:{despairs:1}},n={1:{darkSide:1},2:{darkSide:1},3:{darkSide:1},4:{darkSide:1},5:{darkSide:1},6:{darkSide:1},7:{darkSide:2},8:{lightSide:1},9:{lightSide:1},10:{lightSide:2},11:{lightSide:2},12:{lightSide:2}},d={boost:a,setback:s,ability:i,difficulty:r,proficiency:c,challenge:o,force:n},l=e=>Math.floor(Math.random()*e)+1,u=e=>{const t=a[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},h=e=>{const t=s[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},p=e=>{const t=i[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},g=e=>{const t=r[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},f=e=>{const t=c[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},m=e=>{const t=o[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},v=e=>{const t=n[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}};exports.ABILITY_DIE_FACES=i,exports.BOOST_DIE_FACES=a,exports.CHALLENGE_DIE_FACES=o,exports.DICE_FACES=d,exports.DIFFICULTY_DIE_FACES=r,exports.FORCE_DIE_FACES=n,exports.PROFICIENCY_DIE_FACES=c,exports.SETBACK_DIE_FACES=s,exports.SYMBOLS=e,exports.applyTalentModifiers=(e,t)=>({...e,automaticSuccesses:(e.automaticSuccesses||0)+(t.automaticSuccesses||0),automaticFailures:(e.automaticFailures||0)+(t.automaticFailures||0),automaticAdvantages:(e.automaticAdvantages||0)+(t.automaticAdvantages||0),automaticThreats:(e.automaticThreats||0)+(t.automaticThreats||0),automaticTriumphs:(e.automaticTriumphs||0)+(t.automaticTriumphs||0),automaticDespairs:(e.automaticDespairs||0)+(t.automaticDespairs||0),upgradeAbility:(e.upgradeAbility||0)+(t.upgradeAbility||0),upgradeDifficulty:(e.upgradeDifficulty||0)+(t.upgradeDifficulty||0),downgradeProficiency:(e.downgradeProficiency||0)+(t.downgradeProficiency||0),downgradeChallenge:(e.downgradeChallenge||0)+(t.downgradeChallenge||0)}),exports.createCombatCheck=(e,t,a=0,s)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,t),boostDice:Math.max(0,a),...s}),exports.createDifficultyPool=(e,t=0,a)=>({difficultyDice:Math.max(0,e),challengeDice:Math.max(0,t),...a}),exports.createOpposedCheck=(e,t,a,s=0,i)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,t),difficultyDice:Math.max(0,a),challengeDice:Math.max(0,s),...i}),exports.createSkillCheck=(e,t,a)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,t),...a}),exports.roll=(e,a)=>{var s,i,r,c,o,n,d,A,y;const S=(e=>{const t={...e};if(e.upgradeAbility&&e.upgradeAbility>0){let a=e.upgradeAbility;const s=t.abilityDice||0,i=Math.min(s,a);t.abilityDice=s-i,t.proficiencyDice=(t.proficiencyDice||0)+i,a-=i,a>0&&(t.proficiencyDice=(t.proficiencyDice||0)+a)}if(e.upgradeDifficulty&&e.upgradeDifficulty>0){let a=e.upgradeDifficulty;const s=t.difficultyDice||0,i=Math.min(s,a);t.difficultyDice=s-i,t.challengeDice=(t.challengeDice||0)+i,a-=i,a>0&&(t.challengeDice=(t.challengeDice||0)+a)}if(e.downgradeProficiency&&e.downgradeProficiency>0){const a=t.proficiencyDice||0,s=Math.min(a,e.downgradeProficiency);t.proficiencyDice=a-s,t.abilityDice=(t.abilityDice||0)+s}if(e.downgradeChallenge&&e.downgradeChallenge>0){const a=t.challengeDice||0,s=Math.min(a,e.downgradeChallenge);t.challengeDice=a-s,t.difficultyDice=(t.difficultyDice||0)+s}return t})(e),D=null!==(s=S.boostDice)&&void 0!==s?s:0,T=null!==(i=S.abilityDice)&&void 0!==i?i:0,E=null!==(r=S.proficiencyDice)&&void 0!==r?r:0,b=null!==(c=S.setBackDice)&&void 0!==c?c:0,k=null!==(o=S.difficultyDice)&&void 0!==o?o:0,M=null!==(n=S.challengeDice)&&void 0!==n?n:0,x=null!==(d=S.forceDice)&&void 0!==d?d:0,I=null!==(A=null==a?void 0:a.maxDicePerType)&&void 0!==A?A:100,R=null!==(y=null==a?void 0:a.maxTotalDice)&&void 0!==y?y:500,P=Math.max(0,Math.min(D,I)),C=Math.max(0,Math.min(T,I)),w=Math.max(0,Math.min(E,I)),H=Math.max(0,Math.min(b,I)),U=Math.max(0,Math.min(k,I)),G=Math.max(0,Math.min(M,I)),N=Math.max(0,Math.min(x,I)),F=D>I||T>I||E>I||b>I||k>I||M>I||x>I,_=P+C+w+H+U+G+N;if(_>R)throw new Error(`Total dice count (${_}) exceeds maximum allowed (${R}). Please reduce the number of dice in your pool.`);if(F&&(null==a?void 0:a.throwOnLimitExceeded)){const e=[];throw D>I&&e.push(`boost: ${D}`),T>I&&e.push(`ability: ${T}`),E>I&&e.push(`proficiency: ${E}`),b>I&&e.push(`setback: ${b}`),k>I&&e.push(`difficulty: ${k}`),M>I&&e.push(`challenge: ${M}`),x>I&&e.push(`force: ${x}`),new Error(`Dice counts exceed per-type limit (${I}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const $=[];for(let e=0;e<P;e++){const e=l(6);$.push({type:"boost",roll:e,result:u(e)})}for(let e=0;e<C;e++){const e=l(8);$.push({type:"ability",roll:e,result:p(e)})}for(let e=0;e<w;e++){const e=l(12);$.push({type:"proficiency",roll:e,result:f(e)})}for(let e=0;e<H;e++){const e=l(6);$.push({type:"setback",roll:e,result:h(e)})}for(let e=0;e<U;e++){const e=l(8);$.push({type:"difficulty",roll:e,result:g(e)})}for(let e=0;e<G;e++){const e=l(12);$.push({type:"challenge",roll:e,result:m(e)})}for(let e=0;e<N;e++){const e=l(12);$.push({type:"force",roll:e,result:v(e)})}const V={successes:e.automaticSuccesses,failures:e.automaticFailures,advantages:e.automaticAdvantages,threats:e.automaticThreats,triumphs:e.automaticTriumphs,despairs:e.automaticDespairs,lightSide:e.automaticLightSide,darkSide:e.automaticDarkSide},L=((e,t)=>{const a=e.reduce((e,t)=>({successes:e.successes+t.successes,failures:e.failures+t.failures,advantages:e.advantages+t.advantages,threats:e.threats+t.threats,triumphs:e.triumphs+t.triumphs,despair:e.despair+t.despair,lightSide:e.lightSide+(t.lightSide||0),darkSide:e.darkSide+(t.darkSide||0)}),{successes:(null==t?void 0:t.successes)||0,failures:(null==t?void 0:t.failures)||0,advantages:(null==t?void 0:t.advantages)||0,threats:(null==t?void 0:t.threats)||0,triumphs:(null==t?void 0:t.triumphs)||0,despair:(null==t?void 0:t.despairs)||0,lightSide:(null==t?void 0:t.lightSide)||0,darkSide:(null==t?void 0:t.darkSide)||0});let s=0,i=0;a.successes===a.failures?(s=0,i=0):a.successes>a.failures?s=a.successes-a.failures:i=a.failures-a.successes;let r=0,c=0;return a.advantages===a.threats?(r=0,c=0):a.advantages>a.threats?r=a.advantages-a.threats:c=a.threats-a.advantages,{successes:s,failures:i,advantages:r,threats:c,triumphs:a.triumphs,despair:a.despair,lightSide:a.lightSide,darkSide:a.darkSide}})($.map(e=>e.result),V);if(null==a?void 0:a.hints){const e=t.filter(e=>{const{cost:t}=e;return Object.entries(t).some(([e,t])=>{const a=e.toLowerCase()+"s",s=L[a];return"number"==typeof s&&(void 0!==t&&t>0&&s>=t)})});L.hints=e.map(e=>`${function(e){if(!e.cost||0===Object.keys(e.cost).length)return"No cost";const t=Object.entries(e.cost).filter(([e,t])=>t&&t>0).map(([e,t])=>`${t} ${e.charAt(0).toUpperCase()+e.toLowerCase().slice(1)}${t>1?"s":""}`);return t.length>1?t.join(" OR "):t.length>0?t[0]:"No cost"}(e)} - ${e.description}`)}return{results:$,summary:L}};
2
2
  //# sourceMappingURL=bundle.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bundle.cjs.js","sources":["../src/types.ts","../src/hints.ts","../src/dice.ts","../src/pools.ts"],"sourcesContent":["export type DicePool = {\n boostDice?: number;\n abilityDice?: number;\n proficiencyDice?: number;\n setBackDice?: number;\n difficultyDice?: number;\n challengeDice?: number;\n forceDice?: number;\n // Automatic symbols added to the result (from talents, attachments, etc.)\n automaticSuccesses?: number;\n automaticFailures?: number;\n automaticAdvantages?: number;\n automaticThreats?: number;\n automaticTriumphs?: number;\n automaticDespairs?: number;\n // Dice upgrades and downgrades\n upgradeAbility?: number; // Upgrades ability (green) to proficiency (yellow)\n upgradeDifficulty?: number; // Upgrades difficulty (purple) to challenge (red)\n downgradeProficiency?: number; // Downgrades proficiency (yellow) to ability (green)\n downgradeChallenge?: number; // Downgrades challenge (red) to difficulty (purple)\n};\n\nexport type DiceResult = {\n successes: number;\n failures: number;\n advantages: number;\n threats: number;\n triumphs: number;\n despair: number;\n lightSide: number;\n darkSide: number;\n hints?: string[];\n};\n\nexport type DieType =\n | \"boost\"\n | \"ability\"\n | \"proficiency\"\n | \"setback\"\n | \"difficulty\"\n | \"challenge\"\n | \"force\";\n\nexport type DetailedDieResult = {\n type: DieType;\n roll: number;\n result: DiceResult;\n};\n\nexport type RollResult = {\n results: DetailedDieResult[];\n summary: DiceResult;\n};\n\nexport const SYMBOLS = {\n SUCCESS: \"SUCCESS\" as const,\n FAILURE: \"FAILURE\" as const,\n ADVANTAGE: \"ADVANTAGE\" as const,\n THREAT: \"THREAT\" as const,\n TRIUMPH: \"TRIUMPH\" as const,\n DESPAIR: \"DESPAIR\" as const,\n LIGHT: \"LIGHT\" as const,\n DARK: \"DARK\" as const,\n} as const;\n\nexport type Symbol = keyof typeof SYMBOLS;\n\nexport type RollOptions = {\n hints?: boolean;\n /**\n * Maximum number of dice allowed per die type.\n * Default: 100\n */\n maxDicePerType?: number;\n /**\n * Maximum total number of dice allowed in a single roll.\n * Default: 500\n */\n maxTotalDice?: number;\n /**\n * Whether to throw an error when dice limits are exceeded.\n * If false, dice counts will be silently capped to the maximum.\n * Default: false\n */\n throwOnLimitExceeded?: boolean;\n};\n","import { SYMBOLS, type Symbol } from \"./types\";\n\n// 1 advantage or 1 triumph\nconst recoverOneStrain = \"Recover one strain (may be applied more than once).\";\nconst addBoostDieToActiveAlly =\n \"Add a boost die to the next allied active character's check.\";\nconst noticeImportantPoint =\n \"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.\";\nconst inflictCriticalInjury =\n \"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).\";\nconst activateWeaponQuality =\n \"Activate a weapon quality (Advantage cost may vary).\";\n\n// 2 advantage or 1 triumph\nconst performManeuver =\n \"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.\";\nconst addSetbackDie =\n \"Add a setback die to the targeted character's next check.\";\nconst addBoostDieToAnyAlly =\n \"Add a boost die to any allied character's next check, including that of the active character.\";\n\n// 3 advantage or 1 triumph\nconst negateEnemy =\n \"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.\";\nconst ignoreEnvironment =\n \"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.\";\nconst disableOpponent =\n \"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.\";\nconst gainDefense =\n \"Gain + 1 melee or ranged defense until the end of the active character's next turn.\";\nconst dropWeapon =\n \"Force the target to drop a melee or ranged weapon they are wielding.\";\n\n// 1 triumph\nconst upgradeDifficultyTargetedCharacter =\n \"Upgrade the difficulty of the targeted character's next check.\";\nconst doSomethingVital =\n \"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.\";\nconst upgradeAnyAllyCheck =\n \"Upgrade any allied character's next check, including that of the current active character.\";\n\n// 2 triumph\nconst destroyEquipment =\n \"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.\";\n\n// 1 threat or 1 despair\nconst sufferStrain = \"The active character suffers 1 strain.\";\nconst loseManeuverBenefit =\n \"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.\";\n\n// 2 threat or 1 despair\nconst freeManeuver =\n \"An opponent may immediately perform one free maneuver in response to the active character's check.\";\nconst addBoostDieToTargetedCharacter =\n \"Add a boost die to the targeted character's next check.\";\nconst sufferSetback =\n \"The active character or an allied character suffers a setback die on their next action.\";\n\n// 3 threat or 1 despair\nconst fallProne = \"The active character falls prone.\";\nconst gainSignificantAdvantage =\n \"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.\";\n\n// 1 despair\nconst outOfAmmo =\n \"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.\";\nconst upgradeDifficultyAlliedCharacter =\n \"Upgrade the difficulty of an allied character's next check, including that of the current active character.\";\nconst damagedItem =\n \"The tool or melee weapon the character is using becomes damaged.\";\n\nexport type CostType = {\n [key in Symbol]?: number;\n};\n\ntype Hint = {\n description: string;\n cost: CostType;\n};\n\nexport const hints: Hint[] = [\n // 1 advantage or 1 triumph\n {\n description: recoverOneStrain,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToActiveAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: noticeImportantPoint,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: inflictCriticalInjury,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: activateWeaponQuality,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 advantage or 1 triumph\n {\n description: performManeuver,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addSetbackDie,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToAnyAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 3 advantage or 1 triumph\n {\n description: negateEnemy,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: ignoreEnvironment,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: disableOpponent,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: gainDefense,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: dropWeapon,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 1 triumph\n {\n description: upgradeDifficultyTargetedCharacter,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: doSomethingVital,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: upgradeAnyAllyCheck,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 triumph\n {\n description: destroyEquipment,\n cost: {\n [SYMBOLS.TRIUMPH]: 2,\n },\n },\n // 1 threat or 1 despair\n {\n description: sufferStrain,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: loseManeuverBenefit,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 2 threat or 1 despair\n {\n description: freeManeuver,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: addBoostDieToTargetedCharacter,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: sufferSetback,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 3 threat or 1 despair\n {\n description: fallProne,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: gainSignificantAdvantage,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 1 despair\n {\n description: outOfAmmo,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: upgradeDifficultyAlliedCharacter,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: damagedItem,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n];\n\nexport function hintCostDisplayText(hint: Hint): string {\n if (!hint.cost || Object.keys(hint.cost).length === 0) {\n return \"No cost\";\n }\n const parts = Object.entries(hint.cost)\n .filter(([_, count]) => count && count > 0)\n .map(([symbol, count]) => {\n const symbolName =\n symbol.charAt(0).toUpperCase() + symbol.toLowerCase().slice(1);\n const plural = count > 1 ? \"s\" : \"\";\n return `${count} ${symbolName}${plural}`;\n });\n\n // Use \"OR\" in uppercase for clarity when multiple options exist\n if (parts.length > 1) {\n return parts.join(\" OR \");\n }\n return parts.length > 0 ? parts[0] : \"No cost\";\n}\n","import { hintCostDisplayText, hints } from \"./hints\";\nimport {\n DicePool,\n RollResult,\n DiceResult,\n DetailedDieResult,\n RollOptions,\n} from \"./types\";\n\n// Default dice limits for performance and security\nexport const DEFAULT_MAX_DICE_PER_TYPE = 100;\nexport const DEFAULT_MAX_TOTAL_DICE = 500;\n\nconst rollDie = (sides: number): number =>\n Math.floor(Math.random() * sides) + 1;\n\nconst boostDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst setBackDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 3:\n case 4:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst abilityDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst difficultyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 3:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst proficiencyDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 1,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 2,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n return {\n successes: 0,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 7:\n case 8:\n case 9:\n return {\n successes: 1,\n failures: 0,\n advantages: 1,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 2,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 1,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst challengeDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 2:\n case 3:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 2,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 8:\n case 9:\n return {\n successes: 0,\n failures: 1,\n advantages: 0,\n threats: 1,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 2,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 1,\n lightSide: 0,\n darkSide: 0,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\nconst forceDieResult = (roll: number): DiceResult => {\n switch (roll) {\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 1,\n darkSide: 0,\n };\n case 6:\n case 7:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 2,\n darkSide: 0,\n };\n case 8:\n case 9:\n case 10:\n case 11:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 1,\n };\n case 12:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 2,\n };\n default:\n return {\n successes: 0,\n failures: 0,\n advantages: 0,\n threats: 0,\n triumphs: 0,\n despair: 0,\n lightSide: 0,\n darkSide: 0,\n };\n }\n};\n\n/**\n * Applies dice upgrades and downgrades to a pool.\n * Upgrades are applied first, then downgrades.\n *\n * @param pool - The dice pool to modify\n * @returns A new dice pool with upgrades/downgrades applied\n */\nconst applyDiceModifications = (pool: DicePool): DicePool => {\n const modifiedPool = { ...pool };\n\n // Apply upgrades first (per game rules)\n if (pool.upgradeAbility && pool.upgradeAbility > 0) {\n let upgradesToApply = pool.upgradeAbility;\n const currentAbility = modifiedPool.abilityDice || 0;\n\n // Upgrade existing ability dice to proficiency\n const upgradedDice = Math.min(currentAbility, upgradesToApply);\n modifiedPool.abilityDice = currentAbility - upgradedDice;\n modifiedPool.proficiencyDice =\n (modifiedPool.proficiencyDice || 0) + upgradedDice;\n upgradesToApply -= upgradedDice;\n\n // Add remaining upgrades as new proficiency dice\n if (upgradesToApply > 0) {\n modifiedPool.proficiencyDice =\n (modifiedPool.proficiencyDice || 0) + upgradesToApply;\n }\n }\n\n if (pool.upgradeDifficulty && pool.upgradeDifficulty > 0) {\n let upgradesToApply = pool.upgradeDifficulty;\n const currentDifficulty = modifiedPool.difficultyDice || 0;\n\n // Upgrade existing difficulty dice to challenge\n const upgradedDice = Math.min(currentDifficulty, upgradesToApply);\n modifiedPool.difficultyDice = currentDifficulty - upgradedDice;\n modifiedPool.challengeDice =\n (modifiedPool.challengeDice || 0) + upgradedDice;\n upgradesToApply -= upgradedDice;\n\n // Add remaining upgrades as new challenge dice\n if (upgradesToApply > 0) {\n modifiedPool.challengeDice =\n (modifiedPool.challengeDice || 0) + upgradesToApply;\n }\n }\n\n // Apply downgrades after upgrades\n if (pool.downgradeProficiency && pool.downgradeProficiency > 0) {\n const currentProficiency = modifiedPool.proficiencyDice || 0;\n const downgradesToApply = Math.min(\n currentProficiency,\n pool.downgradeProficiency,\n );\n\n // Downgrade proficiency dice to ability dice\n modifiedPool.proficiencyDice = currentProficiency - downgradesToApply;\n modifiedPool.abilityDice =\n (modifiedPool.abilityDice || 0) + downgradesToApply;\n // Excess downgrades are ignored (per requirements)\n }\n\n if (pool.downgradeChallenge && pool.downgradeChallenge > 0) {\n const currentChallenge = modifiedPool.challengeDice || 0;\n const downgradesToApply = Math.min(\n currentChallenge,\n pool.downgradeChallenge,\n );\n\n // Downgrade challenge dice to difficulty dice\n modifiedPool.challengeDice = currentChallenge - downgradesToApply;\n modifiedPool.difficultyDice =\n (modifiedPool.difficultyDice || 0) + downgradesToApply;\n // Excess downgrades are ignored (per requirements)\n }\n\n return modifiedPool;\n};\n\nconst sumResults = (\n results: DiceResult[],\n automaticSymbols?: {\n successes?: number;\n failures?: number;\n advantages?: number;\n threats?: number;\n triumphs?: number;\n despairs?: number;\n },\n options?: RollOptions,\n): DiceResult => {\n const sums = results.reduce(\n (acc, curr) => ({\n successes: acc.successes + curr.successes,\n failures: acc.failures + curr.failures,\n advantages: acc.advantages + curr.advantages,\n threats: acc.threats + curr.threats,\n triumphs: acc.triumphs + curr.triumphs,\n despair: acc.despair + curr.despair,\n lightSide: acc.lightSide + (curr.lightSide || 0),\n darkSide: acc.darkSide + (curr.darkSide || 0),\n }),\n {\n successes: automaticSymbols?.successes || 0,\n failures: automaticSymbols?.failures || 0,\n advantages: automaticSymbols?.advantages || 0,\n threats: automaticSymbols?.threats || 0,\n triumphs: automaticSymbols?.triumphs || 0,\n despair: automaticSymbols?.despairs || 0,\n lightSide: 0,\n darkSide: 0,\n },\n );\n\n let netSuccesses = 0;\n let netFailures = 0;\n\n if (sums.successes === sums.failures) {\n netSuccesses = 0;\n netFailures = 0;\n } else if (sums.successes > sums.failures) {\n netSuccesses = sums.successes - sums.failures;\n } else {\n netFailures = sums.failures - sums.successes;\n }\n\n // Advantages and threats cancel each other out\n let netAdvantages = 0;\n let netThreats = 0;\n\n if (sums.advantages === sums.threats) {\n netAdvantages = 0;\n netThreats = 0;\n } else if (sums.advantages > sums.threats) {\n netAdvantages = sums.advantages - sums.threats;\n } else {\n netThreats = sums.threats - sums.advantages;\n }\n\n const result: DiceResult = {\n successes: netSuccesses,\n failures: netFailures,\n advantages: netAdvantages,\n threats: netThreats,\n triumphs: sums.triumphs,\n despair: sums.despair,\n lightSide: sums.lightSide,\n darkSide: sums.darkSide,\n };\n\n return result;\n};\n\n/**\n * Rolls a dice pool and returns the results.\n *\n * @param pool - The dice pool to roll\n * @param options - Optional roll configuration including dice limits\n * @returns The roll results with detailed die information and summary\n * @throws {Error} If dice counts exceed configured limits\n *\n * Default limits:\n * - Max dice per type: 100 (configurable via options.maxDicePerType)\n * - Max total dice: 500 (configurable via options.maxTotalDice)\n */\nexport const roll = (pool: DicePool, options?: RollOptions): RollResult => {\n // Apply dice modifications (upgrades/downgrades)\n const modifiedPool = applyDiceModifications(pool);\n\n const boostCount = modifiedPool.boostDice ?? 0;\n const abilityCount = modifiedPool.abilityDice ?? 0;\n const proficiencyCount = modifiedPool.proficiencyDice ?? 0;\n const setBackCount = modifiedPool.setBackDice ?? 0;\n const difficultyCount = modifiedPool.difficultyDice ?? 0;\n const challengeCount = modifiedPool.challengeDice ?? 0;\n const forceCount = modifiedPool.forceDice ?? 0;\n\n // Get limits from options or use defaults\n const maxDicePerType = options?.maxDicePerType ?? DEFAULT_MAX_DICE_PER_TYPE;\n const maxTotalDice = options?.maxTotalDice ?? DEFAULT_MAX_TOTAL_DICE;\n\n // Ensure all dice counts are non-negative and apply per-type limits\n const sanitizedPool = {\n boostDice: Math.max(0, Math.min(boostCount, maxDicePerType)),\n abilityDice: Math.max(0, Math.min(abilityCount, maxDicePerType)),\n proficiencyDice: Math.max(0, Math.min(proficiencyCount, maxDicePerType)),\n setBackDice: Math.max(0, Math.min(setBackCount, maxDicePerType)),\n difficultyDice: Math.max(0, Math.min(difficultyCount, maxDicePerType)),\n challengeDice: Math.max(0, Math.min(challengeCount, maxDicePerType)),\n forceDice: Math.max(0, Math.min(forceCount, maxDicePerType)),\n };\n\n // Check if any dice counts exceeded the per-type limit\n const exceedsPerTypeLimit =\n boostCount > maxDicePerType ||\n abilityCount > maxDicePerType ||\n proficiencyCount > maxDicePerType ||\n setBackCount > maxDicePerType ||\n difficultyCount > maxDicePerType ||\n challengeCount > maxDicePerType ||\n forceCount > maxDicePerType;\n\n // Calculate total dice count\n const totalDice =\n sanitizedPool.boostDice +\n sanitizedPool.abilityDice +\n sanitizedPool.proficiencyDice +\n sanitizedPool.setBackDice +\n sanitizedPool.difficultyDice +\n sanitizedPool.challengeDice +\n sanitizedPool.forceDice;\n\n // Check total dice limit\n if (totalDice > maxTotalDice) {\n throw new Error(\n `Total dice count (${totalDice}) exceeds maximum allowed (${maxTotalDice}). ` +\n `Please reduce the number of dice in your pool.`,\n );\n }\n\n // Warn if per-type limits were exceeded (but continue with capped values)\n if (exceedsPerTypeLimit && options?.throwOnLimitExceeded) {\n const exceeded = [];\n if (boostCount > maxDicePerType) exceeded.push(`boost: ${boostCount}`);\n if (abilityCount > maxDicePerType)\n exceeded.push(`ability: ${abilityCount}`);\n if (proficiencyCount > maxDicePerType)\n exceeded.push(`proficiency: ${proficiencyCount}`);\n if (setBackCount > maxDicePerType)\n exceeded.push(`setback: ${setBackCount}`);\n if (difficultyCount > maxDicePerType)\n exceeded.push(`difficulty: ${difficultyCount}`);\n if (challengeCount > maxDicePerType)\n exceeded.push(`challenge: ${challengeCount}`);\n if (forceCount > maxDicePerType) exceeded.push(`force: ${forceCount}`);\n\n throw new Error(\n `Dice counts exceed per-type limit (${maxDicePerType}): ${exceeded.join(\", \")}. ` +\n `Dice counts have been capped to the maximum.`,\n );\n }\n\n const detailedResults: DetailedDieResult[] = [];\n\n // Roll boost dice\n for (let i = 0; i < sanitizedPool.boostDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"boost\",\n roll,\n result: boostDieResult(roll),\n });\n }\n\n // Roll ability dice\n for (let i = 0; i < sanitizedPool.abilityDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"ability\",\n roll,\n result: abilityDieResult(roll),\n });\n }\n\n // Roll proficiency dice\n for (let i = 0; i < sanitizedPool.proficiencyDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"proficiency\",\n roll,\n result: proficiencyDieResult(roll),\n });\n }\n\n // Roll setback dice\n for (let i = 0; i < sanitizedPool.setBackDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"setback\",\n roll,\n result: setBackDieResult(roll),\n });\n }\n\n // Roll difficulty dice\n for (let i = 0; i < sanitizedPool.difficultyDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"difficulty\",\n roll,\n result: difficultyDieResult(roll),\n });\n }\n\n // Roll challenge dice\n for (let i = 0; i < sanitizedPool.challengeDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"challenge\",\n roll,\n result: challengeDieResult(roll),\n });\n }\n\n // Roll force dice\n for (let i = 0; i < sanitizedPool.forceDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"force\",\n roll,\n result: forceDieResult(roll),\n });\n }\n\n const automaticSymbols = {\n successes: pool.automaticSuccesses,\n failures: pool.automaticFailures,\n advantages: pool.automaticAdvantages,\n threats: pool.automaticThreats,\n triumphs: pool.automaticTriumphs,\n despairs: pool.automaticDespairs,\n };\n\n const summary = sumResults(\n detailedResults.map((r) => r.result),\n automaticSymbols,\n options,\n );\n\n if (options?.hints) {\n const applicableHints = hints.filter((hint) => {\n const { cost } = hint;\n // For OR conditions: at least one option must be fully satisfied\n // Each entry in cost represents an alternative way to pay for the hint\n return Object.entries(cost).some(([symbol, required]) => {\n const summaryKey = (symbol.toLowerCase() + \"s\") as keyof typeof summary;\n const value = summary[summaryKey];\n if (typeof value !== \"number\") return false;\n // Check if we have enough of this symbol type to afford the hint\n return required !== undefined && required > 0 && value >= required;\n });\n });\n summary.hints = applicableHints.map(\n (hint) => `${hintCostDisplayText(hint)} - ${hint.description}`,\n );\n }\n\n return {\n results: detailedResults,\n summary: summary,\n };\n};\n","import { DicePool } from \"./types\";\n\n/**\n * Options for applying talent or equipment modifiers to a dice pool\n */\nexport type PoolModifiers = {\n automaticSuccesses?: number;\n automaticFailures?: number;\n automaticAdvantages?: number;\n automaticThreats?: number;\n automaticTriumphs?: number;\n automaticDespairs?: number;\n upgradeAbility?: number;\n upgradeDifficulty?: number;\n downgradeProficiency?: number;\n downgradeChallenge?: number;\n};\n\n/**\n * Creates a basic skill check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for a basic skill check\n */\nexport const createSkillCheck = (\n ability: number,\n proficiency: number,\n modifiers?: PoolModifiers,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n ...modifiers,\n});\n\n/**\n * Creates a combat check dice pool with optional boost die\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param boost Number of boost (blue) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for a combat check\n */\nexport const createCombatCheck = (\n ability: number,\n proficiency: number,\n boost: number = 0,\n modifiers?: PoolModifiers,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n boostDice: Math.max(0, boost),\n ...modifiers,\n});\n\n/**\n * Creates an opposed check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for an opposed check\n */\nexport const createOpposedCheck = (\n ability: number,\n proficiency: number,\n difficulty: number,\n challenge: number = 0,\n modifiers?: PoolModifiers,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n ...modifiers,\n});\n\n/**\n * Creates a difficulty check dice pool\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for a pure difficulty check\n */\nexport const createDifficultyPool = (\n difficulty: number,\n challenge: number = 0,\n modifiers?: PoolModifiers,\n): DicePool => ({\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n ...modifiers,\n});\n\n/**\n * Applies talent modifiers to an existing dice pool\n * Common use case for talents that add automatic advantages, successes, or upgrade dice\n * @param pool The base dice pool\n * @param modifiers The modifiers to apply\n * @returns A new dice pool with modifiers applied\n */\nexport const applyTalentModifiers = (\n pool: DicePool,\n modifiers: PoolModifiers,\n): DicePool => ({\n ...pool,\n automaticSuccesses:\n (pool.automaticSuccesses || 0) + (modifiers.automaticSuccesses || 0),\n automaticFailures:\n (pool.automaticFailures || 0) + (modifiers.automaticFailures || 0),\n automaticAdvantages:\n (pool.automaticAdvantages || 0) + (modifiers.automaticAdvantages || 0),\n automaticThreats:\n (pool.automaticThreats || 0) + (modifiers.automaticThreats || 0),\n automaticTriumphs:\n (pool.automaticTriumphs || 0) + (modifiers.automaticTriumphs || 0),\n automaticDespairs:\n (pool.automaticDespairs || 0) + (modifiers.automaticDespairs || 0),\n upgradeAbility: (pool.upgradeAbility || 0) + (modifiers.upgradeAbility || 0),\n upgradeDifficulty:\n (pool.upgradeDifficulty || 0) + (modifiers.upgradeDifficulty || 0),\n downgradeProficiency:\n (pool.downgradeProficiency || 0) + (modifiers.downgradeProficiency || 0),\n downgradeChallenge:\n (pool.downgradeChallenge || 0) + (modifiers.downgradeChallenge || 0),\n});\n"],"names":["SYMBOLS","hints","description","cost","SYMBOLS_ADVANTAGE","SYMBOLS_TRIUMPH","SYMBOLS_THREAT","SYMBOLS_DESPAIR","rollDie","sides","Math","floor","random","boostDieResult","roll","successes","failures","advantages","threats","triumphs","despair","lightSide","darkSide","setBackDieResult","abilityDieResult","difficultyDieResult","proficiencyDieResult","challengeDieResult","forceDieResult","pool","modifiers","automaticSuccesses","automaticFailures","automaticAdvantages","automaticThreats","automaticTriumphs","automaticDespairs","upgradeAbility","upgradeDifficulty","downgradeProficiency","downgradeChallenge","ability","proficiency","boost","abilityDice","max","proficiencyDice","boostDice","difficulty","challenge","difficultyDice","challengeDice","options","modifiedPool","upgradesToApply","currentAbility","upgradedDice","min","currentDifficulty","currentProficiency","downgradesToApply","currentChallenge","applyDiceModifications","boostCount","_a","abilityCount","_b","proficiencyCount","_c","setBackCount","_d","setBackDice","difficultyCount","_e","challengeCount","_f","forceCount","_g","forceDice","maxDicePerType","_h","maxTotalDice","_j","sanitizedPool","exceedsPerTypeLimit","totalDice","Error","throwOnLimitExceeded","exceeded","push","join","detailedResults","i","type","result","automaticSymbols","despairs","summary","results","sums","reduce","acc","curr","netSuccesses","netFailures","netAdvantages","netThreats","sumResults","map","r","applicableHints","filter","hint","Object","entries","some","symbol","required","summaryKey","toLowerCase","value","undefined","keys","length","parts","_","count","charAt","toUpperCase","slice","hintCostDisplayText"],"mappings":"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"}
1
+ {"version":3,"file":"bundle.cjs.js","sources":["../src/types.ts","../src/hints.ts","../src/diceFaces.ts","../src/dice.ts","../src/pools.ts"],"sourcesContent":["export type DicePool = {\n boostDice?: number;\n abilityDice?: number;\n proficiencyDice?: number;\n setBackDice?: number;\n difficultyDice?: number;\n challengeDice?: number;\n forceDice?: number;\n // Automatic symbols added to the result (from talents, attachments, etc.)\n automaticSuccesses?: number;\n automaticFailures?: number;\n automaticAdvantages?: number;\n automaticThreats?: number;\n automaticTriumphs?: number;\n automaticDespairs?: number;\n automaticLightSide?: number;\n automaticDarkSide?: number;\n // Dice upgrades and downgrades\n upgradeAbility?: number; // Upgrades ability (green) to proficiency (yellow)\n upgradeDifficulty?: number; // Upgrades difficulty (purple) to challenge (red)\n downgradeProficiency?: number; // Downgrades proficiency (yellow) to ability (green)\n downgradeChallenge?: number; // Downgrades challenge (red) to difficulty (purple)\n};\n\nexport type DiceResult = {\n successes: number;\n failures: number;\n advantages: number;\n threats: number;\n triumphs: number;\n despair: number;\n lightSide: number;\n darkSide: number;\n hints?: string[];\n};\n\nexport type DieType =\n | \"boost\"\n | \"ability\"\n | \"proficiency\"\n | \"setback\"\n | \"difficulty\"\n | \"challenge\"\n | \"force\";\n\nexport type DetailedDieResult = {\n type: DieType;\n roll: number;\n result: DiceResult;\n};\n\nexport type RollResult = {\n results: DetailedDieResult[];\n summary: DiceResult;\n};\n\nexport const SYMBOLS = {\n SUCCESS: \"SUCCESS\" as const,\n FAILURE: \"FAILURE\" as const,\n ADVANTAGE: \"ADVANTAGE\" as const,\n THREAT: \"THREAT\" as const,\n TRIUMPH: \"TRIUMPH\" as const,\n DESPAIR: \"DESPAIR\" as const,\n LIGHT: \"LIGHT\" as const,\n DARK: \"DARK\" as const,\n} as const;\n\nexport type Symbol = keyof typeof SYMBOLS;\n\nexport type DieFaceSymbols = {\n successes?: number;\n failures?: number;\n advantages?: number;\n threats?: number;\n triumphs?: number;\n despairs?: number;\n lightSide?: number;\n darkSide?: number;\n};\n\nexport type BoostDieFace = 1 | 2 | 3 | 4 | 5 | 6;\nexport type SetbackDieFace = 1 | 2 | 3 | 4 | 5 | 6;\nexport type AbilityDieFace = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;\nexport type DifficultyDieFace = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;\nexport type ProficiencyDieFace =\n | 1\n | 2\n | 3\n | 4\n | 5\n | 6\n | 7\n | 8\n | 9\n | 10\n | 11\n | 12;\nexport type ChallengeDieFace = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;\nexport type ForceDieFace = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;\n\nexport type RollOptions = {\n hints?: boolean;\n /**\n * Maximum number of dice allowed per die type.\n * Default: 100\n */\n maxDicePerType?: number;\n /**\n * Maximum total number of dice allowed in a single roll.\n * Default: 500\n */\n maxTotalDice?: number;\n /**\n * Whether to throw an error when dice limits are exceeded.\n * If false, dice counts will be silently capped to the maximum.\n * Default: false\n */\n throwOnLimitExceeded?: boolean;\n};\n","import { SYMBOLS, type Symbol } from \"./types\";\n\n// 1 advantage or 1 triumph\nconst recoverOneStrain = \"Recover one strain (may be applied more than once).\";\nconst addBoostDieToActiveAlly =\n \"Add a boost die to the next allied active character's check.\";\nconst noticeImportantPoint =\n \"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.\";\nconst inflictCriticalInjury =\n \"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).\";\nconst activateWeaponQuality =\n \"Activate a weapon quality (Advantage cost may vary).\";\n\n// 2 advantage or 1 triumph\nconst performManeuver =\n \"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.\";\nconst addSetbackDie =\n \"Add a setback die to the targeted character's next check.\";\nconst addBoostDieToAnyAlly =\n \"Add a boost die to any allied character's next check, including that of the active character.\";\n\n// 3 advantage or 1 triumph\nconst negateEnemy =\n \"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.\";\nconst ignoreEnvironment =\n \"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.\";\nconst disableOpponent =\n \"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.\";\nconst gainDefense =\n \"Gain + 1 melee or ranged defense until the end of the active character's next turn.\";\nconst dropWeapon =\n \"Force the target to drop a melee or ranged weapon they are wielding.\";\n\n// 1 triumph\nconst upgradeDifficultyTargetedCharacter =\n \"Upgrade the difficulty of the targeted character's next check.\";\nconst doSomethingVital =\n \"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.\";\nconst upgradeAnyAllyCheck =\n \"Upgrade any allied character's next check, including that of the current active character.\";\n\n// 2 triumph\nconst destroyEquipment =\n \"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.\";\n\n// 1 threat or 1 despair\nconst sufferStrain = \"The active character suffers 1 strain.\";\nconst loseManeuverBenefit =\n \"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.\";\n\n// 2 threat or 1 despair\nconst freeManeuver =\n \"An opponent may immediately perform one free maneuver in response to the active character's check.\";\nconst addBoostDieToTargetedCharacter =\n \"Add a boost die to the targeted character's next check.\";\nconst sufferSetback =\n \"The active character or an allied character suffers a setback die on their next action.\";\n\n// 3 threat or 1 despair\nconst fallProne = \"The active character falls prone.\";\nconst gainSignificantAdvantage =\n \"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.\";\n\n// 1 despair\nconst outOfAmmo =\n \"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.\";\nconst upgradeDifficultyAlliedCharacter =\n \"Upgrade the difficulty of an allied character's next check, including that of the current active character.\";\nconst damagedItem =\n \"The tool or melee weapon the character is using becomes damaged.\";\n\nexport type CostType = {\n [key in Symbol]?: number;\n};\n\ntype Hint = {\n description: string;\n cost: CostType;\n};\n\nexport const hints: Hint[] = [\n // 1 advantage or 1 triumph\n {\n description: recoverOneStrain,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToActiveAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: noticeImportantPoint,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: inflictCriticalInjury,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: activateWeaponQuality,\n cost: {\n [SYMBOLS.ADVANTAGE]: 1,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 advantage or 1 triumph\n {\n description: performManeuver,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addSetbackDie,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: addBoostDieToAnyAlly,\n cost: {\n [SYMBOLS.ADVANTAGE]: 2,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 3 advantage or 1 triumph\n {\n description: negateEnemy,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: ignoreEnvironment,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: disableOpponent,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: gainDefense,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: dropWeapon,\n cost: {\n [SYMBOLS.ADVANTAGE]: 3,\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 1 triumph\n {\n description: upgradeDifficultyTargetedCharacter,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: doSomethingVital,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n {\n description: upgradeAnyAllyCheck,\n cost: {\n [SYMBOLS.TRIUMPH]: 1,\n },\n },\n // 2 triumph\n {\n description: destroyEquipment,\n cost: {\n [SYMBOLS.TRIUMPH]: 2,\n },\n },\n // 1 threat or 1 despair\n {\n description: sufferStrain,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: loseManeuverBenefit,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 2 threat or 1 despair\n {\n description: freeManeuver,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: addBoostDieToTargetedCharacter,\n cost: {\n [SYMBOLS.THREAT]: 1,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: sufferSetback,\n cost: {\n [SYMBOLS.THREAT]: 2,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 3 threat or 1 despair\n {\n description: fallProne,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: gainSignificantAdvantage,\n cost: {\n [SYMBOLS.THREAT]: 3,\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n // 1 despair\n {\n description: outOfAmmo,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: upgradeDifficultyAlliedCharacter,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n {\n description: damagedItem,\n cost: {\n [SYMBOLS.DESPAIR]: 1,\n },\n },\n];\n\nexport function hintCostDisplayText(hint: Hint): string {\n if (!hint.cost || Object.keys(hint.cost).length === 0) {\n return \"No cost\";\n }\n const parts = Object.entries(hint.cost)\n .filter(([_, count]) => count && count > 0)\n .map(([symbol, count]) => {\n const symbolName =\n symbol.charAt(0).toUpperCase() + symbol.toLowerCase().slice(1);\n const plural = count > 1 ? \"s\" : \"\";\n return `${count} ${symbolName}${plural}`;\n });\n\n // Use \"OR\" in uppercase for clarity when multiple options exist\n if (parts.length > 1) {\n return parts.join(\" OR \");\n }\n return parts.length > 0 ? parts[0] : \"No cost\";\n}\n","import { DieFaceSymbols } from \"./types\";\n\nexport const BOOST_DIE_FACES: Record<number, DieFaceSymbols> = {\n 1: {}, // Blank\n 2: {}, // Blank\n 3: { successes: 1 }, // (S)\n 4: { successes: 1, advantages: 1 }, // (S)(A)\n 5: { successes: 1, advantages: 1 }, // (S)(A)\n 6: { advantages: 1 }, // (A)\n};\n\nexport const SETBACK_DIE_FACES: Record<number, DieFaceSymbols> = {\n 1: {}, // Blank\n 2: {}, // Blank\n 3: { failures: 1 }, // (F)\n 4: { failures: 1 }, // (F)\n 5: { threats: 1 }, // (TH)\n 6: { threats: 1 }, // (TH)\n};\n\nexport const ABILITY_DIE_FACES: Record<number, DieFaceSymbols> = {\n 1: {}, // Blank\n 2: { successes: 1 }, // (S)\n 3: { successes: 1 }, // (S)\n 4: { successes: 2 }, // (S)(S)\n 5: { advantages: 1 }, // (A)\n 6: { advantages: 1 }, // (A)\n 7: { successes: 1, advantages: 1 }, // (S)(A)\n 8: { advantages: 2 }, // (A)(A)\n};\n\nexport const DIFFICULTY_DIE_FACES: Record<number, DieFaceSymbols> = {\n 1: {}, // Blank\n 2: { failures: 1 }, // (F)\n 3: { failures: 2 }, // (F)(F)\n 4: { threats: 1 }, // (TH)\n 5: { threats: 1 }, // (TH)\n 6: { threats: 1 }, // (TH)\n 7: { threats: 2 }, // (TH)(TH)\n 8: { failures: 1, threats: 1 }, // (F)(TH)\n};\n\nexport const PROFICIENCY_DIE_FACES: Record<number, DieFaceSymbols> = {\n 1: {}, // Blank\n 2: { successes: 1 }, // (S)\n 3: { successes: 1 }, // (S)\n 4: { successes: 2 }, // (S)(S)\n 5: { successes: 2 }, // (S)(S)\n 6: { advantages: 1 }, // (A)\n 7: { successes: 1, advantages: 1 }, // (S)(A)\n 8: { successes: 1, advantages: 1 }, // (S)(A)\n 9: { successes: 1, advantages: 1 }, // (S)(A)\n 10: { advantages: 2 }, // (A)(A)\n 11: { advantages: 2 }, // (A)(A)\n 12: { triumphs: 1 }, // (TR)\n};\n\nexport const CHALLENGE_DIE_FACES: Record<number, DieFaceSymbols> = {\n 1: {}, // Blank\n 2: { failures: 1 }, // (F)\n 3: { failures: 1 }, // (F)\n 4: { failures: 2 }, // (F)(F)\n 5: { failures: 2 }, // (F)(F)\n 6: { threats: 1 }, // (TH)\n 7: { threats: 1 }, // (TH)\n 8: { failures: 1, threats: 1 }, // (F)(TH)\n 9: { failures: 1, threats: 1 }, // (F)(TH)\n 10: { threats: 2 }, // (TH)(TH)\n 11: { threats: 2 }, // (TH)(TH)\n 12: { despairs: 1 }, // (D)\n};\n\nexport const FORCE_DIE_FACES: Record<number, DieFaceSymbols> = {\n 1: { darkSide: 1 }, // (DS)\n 2: { darkSide: 1 }, // (DS)\n 3: { darkSide: 1 }, // (DS)\n 4: { darkSide: 1 }, // (DS)\n 5: { darkSide: 1 }, // (DS)\n 6: { darkSide: 1 }, // (DS)\n 7: { darkSide: 2 }, // (DS)(DS)\n 8: { lightSide: 1 }, // (LS)\n 9: { lightSide: 1 }, // (LS)\n 10: { lightSide: 2 }, // (LS)(LS)\n 11: { lightSide: 2 }, // (LS)(LS)\n 12: { lightSide: 2 }, // (LS)(LS)\n};\n\nexport const DICE_FACES = {\n boost: BOOST_DIE_FACES,\n setback: SETBACK_DIE_FACES,\n ability: ABILITY_DIE_FACES,\n difficulty: DIFFICULTY_DIE_FACES,\n proficiency: PROFICIENCY_DIE_FACES,\n challenge: CHALLENGE_DIE_FACES,\n force: FORCE_DIE_FACES,\n} as const;\n","import { hintCostDisplayText, hints } from \"./hints\";\nimport {\n DicePool,\n RollResult,\n DiceResult,\n DetailedDieResult,\n RollOptions,\n} from \"./types\";\nimport {\n BOOST_DIE_FACES,\n SETBACK_DIE_FACES,\n ABILITY_DIE_FACES,\n DIFFICULTY_DIE_FACES,\n PROFICIENCY_DIE_FACES,\n CHALLENGE_DIE_FACES,\n FORCE_DIE_FACES,\n} from \"./diceFaces\";\n\n// Default dice limits for performance and security\nexport const DEFAULT_MAX_DICE_PER_TYPE = 100;\nexport const DEFAULT_MAX_TOTAL_DICE = 500;\n\nconst rollDie = (sides: number): number =>\n Math.floor(Math.random() * sides) + 1;\n\nconst boostDieResult = (roll: number): DiceResult => {\n const face = BOOST_DIE_FACES[roll];\n return {\n successes: face.successes || 0,\n failures: face.failures || 0,\n advantages: face.advantages || 0,\n threats: face.threats || 0,\n triumphs: face.triumphs || 0,\n despair: face.despairs || 0,\n lightSide: face.lightSide || 0,\n darkSide: face.darkSide || 0,\n };\n};\n\nconst setBackDieResult = (roll: number): DiceResult => {\n const face = SETBACK_DIE_FACES[roll];\n return {\n successes: face.successes || 0,\n failures: face.failures || 0,\n advantages: face.advantages || 0,\n threats: face.threats || 0,\n triumphs: face.triumphs || 0,\n despair: face.despairs || 0,\n lightSide: face.lightSide || 0,\n darkSide: face.darkSide || 0,\n };\n};\n\nconst abilityDieResult = (roll: number): DiceResult => {\n const face = ABILITY_DIE_FACES[roll];\n return {\n successes: face.successes || 0,\n failures: face.failures || 0,\n advantages: face.advantages || 0,\n threats: face.threats || 0,\n triumphs: face.triumphs || 0,\n despair: face.despairs || 0,\n lightSide: face.lightSide || 0,\n darkSide: face.darkSide || 0,\n };\n};\n\nconst difficultyDieResult = (roll: number): DiceResult => {\n const face = DIFFICULTY_DIE_FACES[roll];\n return {\n successes: face.successes || 0,\n failures: face.failures || 0,\n advantages: face.advantages || 0,\n threats: face.threats || 0,\n triumphs: face.triumphs || 0,\n despair: face.despairs || 0,\n lightSide: face.lightSide || 0,\n darkSide: face.darkSide || 0,\n };\n};\n\nconst proficiencyDieResult = (roll: number): DiceResult => {\n const face = PROFICIENCY_DIE_FACES[roll];\n return {\n successes: face.successes || 0,\n failures: face.failures || 0,\n advantages: face.advantages || 0,\n threats: face.threats || 0,\n triumphs: face.triumphs || 0,\n despair: face.despairs || 0,\n lightSide: face.lightSide || 0,\n darkSide: face.darkSide || 0,\n };\n};\n\nconst challengeDieResult = (roll: number): DiceResult => {\n const face = CHALLENGE_DIE_FACES[roll];\n return {\n successes: face.successes || 0,\n failures: face.failures || 0,\n advantages: face.advantages || 0,\n threats: face.threats || 0,\n triumphs: face.triumphs || 0,\n despair: face.despairs || 0,\n lightSide: face.lightSide || 0,\n darkSide: face.darkSide || 0,\n };\n};\n\nconst forceDieResult = (roll: number): DiceResult => {\n const face = FORCE_DIE_FACES[roll];\n return {\n successes: face.successes || 0,\n failures: face.failures || 0,\n advantages: face.advantages || 0,\n threats: face.threats || 0,\n triumphs: face.triumphs || 0,\n despair: face.despairs || 0,\n lightSide: face.lightSide || 0,\n darkSide: face.darkSide || 0,\n };\n};\n\n/**\n * Applies dice upgrades and downgrades to a pool.\n * Upgrades are applied first, then downgrades.\n *\n * @param pool - The dice pool to modify\n * @returns A new dice pool with upgrades/downgrades applied\n */\nconst applyDiceModifications = (pool: DicePool): DicePool => {\n const modifiedPool = { ...pool };\n\n // Apply upgrades first (per game rules)\n if (pool.upgradeAbility && pool.upgradeAbility > 0) {\n let upgradesToApply = pool.upgradeAbility;\n const currentAbility = modifiedPool.abilityDice || 0;\n\n // Upgrade existing ability dice to proficiency\n const upgradedDice = Math.min(currentAbility, upgradesToApply);\n modifiedPool.abilityDice = currentAbility - upgradedDice;\n modifiedPool.proficiencyDice =\n (modifiedPool.proficiencyDice || 0) + upgradedDice;\n upgradesToApply -= upgradedDice;\n\n // Add remaining upgrades as new proficiency dice\n if (upgradesToApply > 0) {\n modifiedPool.proficiencyDice =\n (modifiedPool.proficiencyDice || 0) + upgradesToApply;\n }\n }\n\n if (pool.upgradeDifficulty && pool.upgradeDifficulty > 0) {\n let upgradesToApply = pool.upgradeDifficulty;\n const currentDifficulty = modifiedPool.difficultyDice || 0;\n\n // Upgrade existing difficulty dice to challenge\n const upgradedDice = Math.min(currentDifficulty, upgradesToApply);\n modifiedPool.difficultyDice = currentDifficulty - upgradedDice;\n modifiedPool.challengeDice =\n (modifiedPool.challengeDice || 0) + upgradedDice;\n upgradesToApply -= upgradedDice;\n\n // Add remaining upgrades as new challenge dice\n if (upgradesToApply > 0) {\n modifiedPool.challengeDice =\n (modifiedPool.challengeDice || 0) + upgradesToApply;\n }\n }\n\n // Apply downgrades after upgrades\n if (pool.downgradeProficiency && pool.downgradeProficiency > 0) {\n const currentProficiency = modifiedPool.proficiencyDice || 0;\n const downgradesToApply = Math.min(\n currentProficiency,\n pool.downgradeProficiency,\n );\n\n // Downgrade proficiency dice to ability dice\n modifiedPool.proficiencyDice = currentProficiency - downgradesToApply;\n modifiedPool.abilityDice =\n (modifiedPool.abilityDice || 0) + downgradesToApply;\n // Excess downgrades are ignored (per requirements)\n }\n\n if (pool.downgradeChallenge && pool.downgradeChallenge > 0) {\n const currentChallenge = modifiedPool.challengeDice || 0;\n const downgradesToApply = Math.min(\n currentChallenge,\n pool.downgradeChallenge,\n );\n\n // Downgrade challenge dice to difficulty dice\n modifiedPool.challengeDice = currentChallenge - downgradesToApply;\n modifiedPool.difficultyDice =\n (modifiedPool.difficultyDice || 0) + downgradesToApply;\n // Excess downgrades are ignored (per requirements)\n }\n\n return modifiedPool;\n};\n\nconst sumResults = (\n results: DiceResult[],\n automaticSymbols?: {\n successes?: number;\n failures?: number;\n advantages?: number;\n threats?: number;\n triumphs?: number;\n despairs?: number;\n lightSide?: number;\n darkSide?: number;\n },\n options?: RollOptions,\n): DiceResult => {\n const sums = results.reduce(\n (acc, curr) => ({\n successes: acc.successes + curr.successes,\n failures: acc.failures + curr.failures,\n advantages: acc.advantages + curr.advantages,\n threats: acc.threats + curr.threats,\n triumphs: acc.triumphs + curr.triumphs,\n despair: acc.despair + curr.despair,\n lightSide: acc.lightSide + (curr.lightSide || 0),\n darkSide: acc.darkSide + (curr.darkSide || 0),\n }),\n {\n successes: automaticSymbols?.successes || 0,\n failures: automaticSymbols?.failures || 0,\n advantages: automaticSymbols?.advantages || 0,\n threats: automaticSymbols?.threats || 0,\n triumphs: automaticSymbols?.triumphs || 0,\n despair: automaticSymbols?.despairs || 0,\n lightSide: automaticSymbols?.lightSide || 0,\n darkSide: automaticSymbols?.darkSide || 0,\n },\n );\n\n let netSuccesses = 0;\n let netFailures = 0;\n\n if (sums.successes === sums.failures) {\n netSuccesses = 0;\n netFailures = 0;\n } else if (sums.successes > sums.failures) {\n netSuccesses = sums.successes - sums.failures;\n } else {\n netFailures = sums.failures - sums.successes;\n }\n\n // Advantages and threats cancel each other out\n let netAdvantages = 0;\n let netThreats = 0;\n\n if (sums.advantages === sums.threats) {\n netAdvantages = 0;\n netThreats = 0;\n } else if (sums.advantages > sums.threats) {\n netAdvantages = sums.advantages - sums.threats;\n } else {\n netThreats = sums.threats - sums.advantages;\n }\n\n const result: DiceResult = {\n successes: netSuccesses,\n failures: netFailures,\n advantages: netAdvantages,\n threats: netThreats,\n triumphs: sums.triumphs,\n despair: sums.despair,\n lightSide: sums.lightSide,\n darkSide: sums.darkSide,\n };\n\n return result;\n};\n\n/**\n * Rolls a dice pool and returns the results.\n *\n * @param pool - The dice pool to roll\n * @param options - Optional roll configuration including dice limits\n * @returns The roll results with detailed die information and summary\n * @throws {Error} If dice counts exceed configured limits\n *\n * Default limits:\n * - Max dice per type: 100 (configurable via options.maxDicePerType)\n * - Max total dice: 500 (configurable via options.maxTotalDice)\n */\nexport const roll = (pool: DicePool, options?: RollOptions): RollResult => {\n // Apply dice modifications (upgrades/downgrades)\n const modifiedPool = applyDiceModifications(pool);\n\n const boostCount = modifiedPool.boostDice ?? 0;\n const abilityCount = modifiedPool.abilityDice ?? 0;\n const proficiencyCount = modifiedPool.proficiencyDice ?? 0;\n const setBackCount = modifiedPool.setBackDice ?? 0;\n const difficultyCount = modifiedPool.difficultyDice ?? 0;\n const challengeCount = modifiedPool.challengeDice ?? 0;\n const forceCount = modifiedPool.forceDice ?? 0;\n\n // Get limits from options or use defaults\n const maxDicePerType = options?.maxDicePerType ?? DEFAULT_MAX_DICE_PER_TYPE;\n const maxTotalDice = options?.maxTotalDice ?? DEFAULT_MAX_TOTAL_DICE;\n\n // Ensure all dice counts are non-negative and apply per-type limits\n const sanitizedPool = {\n boostDice: Math.max(0, Math.min(boostCount, maxDicePerType)),\n abilityDice: Math.max(0, Math.min(abilityCount, maxDicePerType)),\n proficiencyDice: Math.max(0, Math.min(proficiencyCount, maxDicePerType)),\n setBackDice: Math.max(0, Math.min(setBackCount, maxDicePerType)),\n difficultyDice: Math.max(0, Math.min(difficultyCount, maxDicePerType)),\n challengeDice: Math.max(0, Math.min(challengeCount, maxDicePerType)),\n forceDice: Math.max(0, Math.min(forceCount, maxDicePerType)),\n };\n\n // Check if any dice counts exceeded the per-type limit\n const exceedsPerTypeLimit =\n boostCount > maxDicePerType ||\n abilityCount > maxDicePerType ||\n proficiencyCount > maxDicePerType ||\n setBackCount > maxDicePerType ||\n difficultyCount > maxDicePerType ||\n challengeCount > maxDicePerType ||\n forceCount > maxDicePerType;\n\n // Calculate total dice count\n const totalDice =\n sanitizedPool.boostDice +\n sanitizedPool.abilityDice +\n sanitizedPool.proficiencyDice +\n sanitizedPool.setBackDice +\n sanitizedPool.difficultyDice +\n sanitizedPool.challengeDice +\n sanitizedPool.forceDice;\n\n // Check total dice limit\n if (totalDice > maxTotalDice) {\n throw new Error(\n `Total dice count (${totalDice}) exceeds maximum allowed (${maxTotalDice}). ` +\n `Please reduce the number of dice in your pool.`,\n );\n }\n\n // Warn if per-type limits were exceeded (but continue with capped values)\n if (exceedsPerTypeLimit && options?.throwOnLimitExceeded) {\n const exceeded = [];\n if (boostCount > maxDicePerType) exceeded.push(`boost: ${boostCount}`);\n if (abilityCount > maxDicePerType)\n exceeded.push(`ability: ${abilityCount}`);\n if (proficiencyCount > maxDicePerType)\n exceeded.push(`proficiency: ${proficiencyCount}`);\n if (setBackCount > maxDicePerType)\n exceeded.push(`setback: ${setBackCount}`);\n if (difficultyCount > maxDicePerType)\n exceeded.push(`difficulty: ${difficultyCount}`);\n if (challengeCount > maxDicePerType)\n exceeded.push(`challenge: ${challengeCount}`);\n if (forceCount > maxDicePerType) exceeded.push(`force: ${forceCount}`);\n\n throw new Error(\n `Dice counts exceed per-type limit (${maxDicePerType}): ${exceeded.join(\", \")}. ` +\n `Dice counts have been capped to the maximum.`,\n );\n }\n\n const detailedResults: DetailedDieResult[] = [];\n\n // Roll boost dice\n for (let i = 0; i < sanitizedPool.boostDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"boost\",\n roll,\n result: boostDieResult(roll),\n });\n }\n\n // Roll ability dice\n for (let i = 0; i < sanitizedPool.abilityDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"ability\",\n roll,\n result: abilityDieResult(roll),\n });\n }\n\n // Roll proficiency dice\n for (let i = 0; i < sanitizedPool.proficiencyDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"proficiency\",\n roll,\n result: proficiencyDieResult(roll),\n });\n }\n\n // Roll setback dice\n for (let i = 0; i < sanitizedPool.setBackDice; i++) {\n const roll = rollDie(6);\n detailedResults.push({\n type: \"setback\",\n roll,\n result: setBackDieResult(roll),\n });\n }\n\n // Roll difficulty dice\n for (let i = 0; i < sanitizedPool.difficultyDice; i++) {\n const roll = rollDie(8);\n detailedResults.push({\n type: \"difficulty\",\n roll,\n result: difficultyDieResult(roll),\n });\n }\n\n // Roll challenge dice\n for (let i = 0; i < sanitizedPool.challengeDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"challenge\",\n roll,\n result: challengeDieResult(roll),\n });\n }\n\n // Roll force dice\n for (let i = 0; i < sanitizedPool.forceDice; i++) {\n const roll = rollDie(12);\n detailedResults.push({\n type: \"force\",\n roll,\n result: forceDieResult(roll),\n });\n }\n\n const automaticSymbols = {\n successes: pool.automaticSuccesses,\n failures: pool.automaticFailures,\n advantages: pool.automaticAdvantages,\n threats: pool.automaticThreats,\n triumphs: pool.automaticTriumphs,\n despairs: pool.automaticDespairs,\n lightSide: pool.automaticLightSide,\n darkSide: pool.automaticDarkSide,\n };\n\n const summary = sumResults(\n detailedResults.map((r) => r.result),\n automaticSymbols,\n options,\n );\n\n if (options?.hints) {\n const applicableHints = hints.filter((hint) => {\n const { cost } = hint;\n // For OR conditions: at least one option must be fully satisfied\n // Each entry in cost represents an alternative way to pay for the hint\n return Object.entries(cost).some(([symbol, required]) => {\n const summaryKey = (symbol.toLowerCase() + \"s\") as keyof typeof summary;\n const value = summary[summaryKey];\n if (typeof value !== \"number\") return false;\n // Check if we have enough of this symbol type to afford the hint\n return required !== undefined && required > 0 && value >= required;\n });\n });\n summary.hints = applicableHints.map(\n (hint) => `${hintCostDisplayText(hint)} - ${hint.description}`,\n );\n }\n\n return {\n results: detailedResults,\n summary: summary,\n };\n};\n","import { DicePool } from \"./types\";\n\n/**\n * Options for applying talent or equipment modifiers to a dice pool\n */\nexport type PoolModifiers = {\n automaticSuccesses?: number;\n automaticFailures?: number;\n automaticAdvantages?: number;\n automaticThreats?: number;\n automaticTriumphs?: number;\n automaticDespairs?: number;\n upgradeAbility?: number;\n upgradeDifficulty?: number;\n downgradeProficiency?: number;\n downgradeChallenge?: number;\n};\n\n/**\n * Creates a basic skill check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for a basic skill check\n */\nexport const createSkillCheck = (\n ability: number,\n proficiency: number,\n modifiers?: PoolModifiers,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n ...modifiers,\n});\n\n/**\n * Creates a combat check dice pool with optional boost die\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param boost Number of boost (blue) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for a combat check\n */\nexport const createCombatCheck = (\n ability: number,\n proficiency: number,\n boost: number = 0,\n modifiers?: PoolModifiers,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n boostDice: Math.max(0, boost),\n ...modifiers,\n});\n\n/**\n * Creates an opposed check dice pool\n * @param ability Number of ability (green) dice\n * @param proficiency Number of proficiency (yellow) dice\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for an opposed check\n */\nexport const createOpposedCheck = (\n ability: number,\n proficiency: number,\n difficulty: number,\n challenge: number = 0,\n modifiers?: PoolModifiers,\n): DicePool => ({\n abilityDice: Math.max(0, ability),\n proficiencyDice: Math.max(0, proficiency),\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n ...modifiers,\n});\n\n/**\n * Creates a difficulty check dice pool\n * @param difficulty Number of difficulty (purple) dice\n * @param challenge Number of challenge (red) dice\n * @param modifiers Optional modifiers from talents, equipment, etc.\n * @returns DicePool configured for a pure difficulty check\n */\nexport const createDifficultyPool = (\n difficulty: number,\n challenge: number = 0,\n modifiers?: PoolModifiers,\n): DicePool => ({\n difficultyDice: Math.max(0, difficulty),\n challengeDice: Math.max(0, challenge),\n ...modifiers,\n});\n\n/**\n * Applies talent modifiers to an existing dice pool\n * Common use case for talents that add automatic advantages, successes, or upgrade dice\n * @param pool The base dice pool\n * @param modifiers The modifiers to apply\n * @returns A new dice pool with modifiers applied\n */\nexport const applyTalentModifiers = (\n pool: DicePool,\n modifiers: PoolModifiers,\n): DicePool => ({\n ...pool,\n automaticSuccesses:\n (pool.automaticSuccesses || 0) + (modifiers.automaticSuccesses || 0),\n automaticFailures:\n (pool.automaticFailures || 0) + (modifiers.automaticFailures || 0),\n automaticAdvantages:\n (pool.automaticAdvantages || 0) + (modifiers.automaticAdvantages || 0),\n automaticThreats:\n (pool.automaticThreats || 0) + (modifiers.automaticThreats || 0),\n automaticTriumphs:\n (pool.automaticTriumphs || 0) + (modifiers.automaticTriumphs || 0),\n automaticDespairs:\n (pool.automaticDespairs || 0) + (modifiers.automaticDespairs || 0),\n upgradeAbility: (pool.upgradeAbility || 0) + (modifiers.upgradeAbility || 0),\n upgradeDifficulty:\n (pool.upgradeDifficulty || 0) + (modifiers.upgradeDifficulty || 0),\n downgradeProficiency:\n (pool.downgradeProficiency || 0) + (modifiers.downgradeProficiency || 0),\n downgradeChallenge:\n (pool.downgradeChallenge || 0) + (modifiers.downgradeChallenge || 0),\n});\n"],"names":["SYMBOLS","SUCCESS","FAILURE","ADVANTAGE","THREAT","TRIUMPH","DESPAIR","LIGHT","DARK","hints","description","cost","BOOST_DIE_FACES","successes","advantages","SETBACK_DIE_FACES","failures","threats","ABILITY_DIE_FACES","DIFFICULTY_DIE_FACES","PROFICIENCY_DIE_FACES","triumphs","CHALLENGE_DIE_FACES","despairs","FORCE_DIE_FACES","darkSide","lightSide","DICE_FACES","boost","setback","ability","difficulty","proficiency","challenge","force","rollDie","sides","Math","floor","random","boostDieResult","roll","face","despair","setBackDieResult","abilityDieResult","difficultyDieResult","proficiencyDieResult","challengeDieResult","forceDieResult","pool","modifiers","automaticSuccesses","automaticFailures","automaticAdvantages","automaticThreats","automaticTriumphs","automaticDespairs","upgradeAbility","upgradeDifficulty","downgradeProficiency","downgradeChallenge","abilityDice","max","proficiencyDice","boostDice","difficultyDice","challengeDice","options","modifiedPool","upgradesToApply","currentAbility","upgradedDice","min","currentDifficulty","currentProficiency","downgradesToApply","currentChallenge","applyDiceModifications","boostCount","_a","abilityCount","_b","proficiencyCount","_c","setBackCount","_d","setBackDice","difficultyCount","_e","challengeCount","_f","forceCount","_g","forceDice","maxDicePerType","_h","maxTotalDice","_j","sanitizedPool","exceedsPerTypeLimit","totalDice","Error","throwOnLimitExceeded","exceeded","push","join","detailedResults","i","type","result","automaticSymbols","automaticLightSide","automaticDarkSide","summary","results","sums","reduce","acc","curr","netSuccesses","netFailures","netAdvantages","netThreats","sumResults","map","r","applicableHints","filter","hint","Object","entries","some","symbol","required","summaryKey","toLowerCase","value","undefined","keys","length","parts","_","count","charAt","toUpperCase","slice","hintCostDisplayText"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e="ADVANTAGE",a="THREAT",t="TRIUMPH",s="DESPAIR",i=[{description:"Recover one strain (may be applied more than once).",cost:{[e]:1,[t]:1}},{description:"Add a boost die to the next allied active character's check.",cost:{[e]:1,[t]:1}},{description:"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.",cost:{[e]:1,[t]:1}},{description:"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Activate a weapon quality (Advantage cost may vary).",cost:{[e]:1,[t]:1}},{description:"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.",cost:{[e]:2,[t]:1}},{description:"Add a setback die to the targeted character's next check.",cost:{[e]:2,[t]:1}},{description:"Add a boost die to any allied character's next check, including that of the active character.",cost:{[e]:2,[t]:1}},{description:"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.",cost:{[e]:3,[t]:1}},{description:"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.",cost:{[e]:3,[t]:1}},{description:"Gain + 1 melee or ranged defense until the end of the active character's next turn.",cost:{[e]:3,[t]:1}},{description:"Force the target to drop a melee or ranged weapon they are wielding.",cost:{[e]:3,[t]:1}},{description:"Upgrade the difficulty of the targeted character's next check.",cost:{[t]:1}},{description:"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.",cost:{[t]:1}},{description:"Upgrade any allied character's next check, including that of the current active character.",cost:{[t]:1}},{description:"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.",cost:{[t]:2}},{description:"The active character suffers 1 strain.",cost:{[a]:1,[s]:1}},{description:"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.",cost:{[a]:1,[s]:1}},{description:"An opponent may immediately perform one free maneuver in response to the active character's check.",cost:{[a]:2,[s]:1}},{description:"Add a boost die to the targeted character's next check.",cost:{[a]:1,[s]:1}},{description:"The active character or an allied character suffers a setback die on their next action.",cost:{[a]:2,[s]:1}},{description:"The active character falls prone.",cost:{[a]:3,[s]:1}},{description:"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.",cost:{[a]:3,[s]:1}},{description:"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.",cost:{[s]:1}},{description:"Upgrade the difficulty of an allied character's next check, including that of the current active character.",cost:{[s]:1}},{description:"The tool or melee weapon the character is using becomes damaged.",cost:{[s]:1}}];const r=e=>Math.floor(Math.random()*e)+1,c=e=>{switch(e){case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},d=e=>{switch(e){case 3:case 4:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},n=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 5:case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},u=e=>{switch(e){case 2:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 3:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:case 6:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},o=e=>{switch(e){case 2:case 3:return{successes:1,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:2,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:return{successes:0,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 7:case 8:case 9:return{successes:1,failures:0,advantages:1,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:2,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:1,despair:0,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},h=e=>{switch(e){case 2:case 3:return{successes:0,failures:1,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 4:case 5:return{successes:0,failures:2,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 8:case 9:return{successes:0,failures:1,advantages:0,threats:1,triumphs:0,despair:0,lightSide:0,darkSide:0};case 10:case 11:return{successes:0,failures:0,advantages:0,threats:2,triumphs:0,despair:0,lightSide:0,darkSide:0};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:1,lightSide:0,darkSide:0};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},l=e=>{switch(e){case 1:case 2:case 3:case 4:case 5:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:1,darkSide:0};case 6:case 7:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:2,darkSide:0};case 8:case 9:case 10:case 11:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:1};case 12:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:2};default:return{successes:0,failures:0,advantages:0,threats:0,triumphs:0,despair:0,lightSide:0,darkSide:0}}},p=(e,a)=>{var t,s,p,g,f,m,v,S,y;const k=(e=>{const a={...e};if(e.upgradeAbility&&e.upgradeAbility>0){let t=e.upgradeAbility;const s=a.abilityDice||0,i=Math.min(s,t);a.abilityDice=s-i,a.proficiencyDice=(a.proficiencyDice||0)+i,t-=i,t>0&&(a.proficiencyDice=(a.proficiencyDice||0)+t)}if(e.upgradeDifficulty&&e.upgradeDifficulty>0){let t=e.upgradeDifficulty;const s=a.difficultyDice||0,i=Math.min(s,t);a.difficultyDice=s-i,a.challengeDice=(a.challengeDice||0)+i,t-=i,t>0&&(a.challengeDice=(a.challengeDice||0)+t)}if(e.downgradeProficiency&&e.downgradeProficiency>0){const t=a.proficiencyDice||0,s=Math.min(t,e.downgradeProficiency);a.proficiencyDice=t-s,a.abilityDice=(a.abilityDice||0)+s}if(e.downgradeChallenge&&e.downgradeChallenge>0){const t=a.challengeDice||0,s=Math.min(t,e.downgradeChallenge);a.challengeDice=t-s,a.difficultyDice=(a.difficultyDice||0)+s}return a})(e),D=null!==(t=k.boostDice)&&void 0!==t?t:0,b=null!==(s=k.abilityDice)&&void 0!==s?s:0,w=null!==(p=k.proficiencyDice)&&void 0!==p?p:0,x=null!==(g=k.setBackDice)&&void 0!==g?g:0,M=null!==(f=k.difficultyDice)&&void 0!==f?f:0,T=null!==(m=k.challengeDice)&&void 0!==m?m:0,A=null!==(v=k.forceDice)&&void 0!==v?v:0,$=null!==(S=null==a?void 0:a.maxDicePerType)&&void 0!==S?S:100,C=null!==(y=null==a?void 0:a.maxTotalDice)&&void 0!==y?y:500,P=Math.max(0,Math.min(D,$)),j=Math.max(0,Math.min(b,$)),E=Math.max(0,Math.min(w,$)),G=Math.max(0,Math.min(x,$)),I=Math.max(0,Math.min(M,$)),R=Math.max(0,Math.min(T,$)),F=Math.max(0,Math.min(A,$)),N=D>$||b>$||w>$||x>$||M>$||T>$||A>$,O=P+j+E+G+I+R+F;if(O>C)throw new Error(`Total dice count (${O}) exceeds maximum allowed (${C}). Please reduce the number of dice in your pool.`);if(N&&(null==a?void 0:a.throwOnLimitExceeded)){const e=[];throw D>$&&e.push(`boost: ${D}`),b>$&&e.push(`ability: ${b}`),w>$&&e.push(`proficiency: ${w}`),x>$&&e.push(`setback: ${x}`),M>$&&e.push(`difficulty: ${M}`),T>$&&e.push(`challenge: ${T}`),A>$&&e.push(`force: ${A}`),new Error(`Dice counts exceed per-type limit (${$}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const U=[];for(let e=0;e<P;e++){const e=r(6);U.push({type:"boost",roll:e,result:c(e)})}for(let e=0;e<j;e++){const e=r(8);U.push({type:"ability",roll:e,result:n(e)})}for(let e=0;e<E;e++){const e=r(12);U.push({type:"proficiency",roll:e,result:o(e)})}for(let e=0;e<G;e++){const e=r(6);U.push({type:"setback",roll:e,result:d(e)})}for(let e=0;e<I;e++){const e=r(8);U.push({type:"difficulty",roll:e,result:u(e)})}for(let e=0;e<R;e++){const e=r(12);U.push({type:"challenge",roll:e,result:h(e)})}for(let e=0;e<F;e++){const e=r(12);U.push({type:"force",roll:e,result:l(e)})}const q={successes:e.automaticSuccesses,failures:e.automaticFailures,advantages:e.automaticAdvantages,threats:e.automaticThreats,triumphs:e.automaticTriumphs,despairs:e.automaticDespairs},L=((e,a)=>{const t=e.reduce((e,a)=>({successes:e.successes+a.successes,failures:e.failures+a.failures,advantages:e.advantages+a.advantages,threats:e.threats+a.threats,triumphs:e.triumphs+a.triumphs,despair:e.despair+a.despair,lightSide:e.lightSide+(a.lightSide||0),darkSide:e.darkSide+(a.darkSide||0)}),{successes:(null==a?void 0:a.successes)||0,failures:(null==a?void 0:a.failures)||0,advantages:(null==a?void 0:a.advantages)||0,threats:(null==a?void 0:a.threats)||0,triumphs:(null==a?void 0:a.triumphs)||0,despair:(null==a?void 0:a.despairs)||0,lightSide:0,darkSide:0});let s=0,i=0;t.successes===t.failures?(s=0,i=0):t.successes>t.failures?s=t.successes-t.failures:i=t.failures-t.successes;let r=0,c=0;return t.advantages===t.threats?(r=0,c=0):t.advantages>t.threats?r=t.advantages-t.threats:c=t.threats-t.advantages,{successes:s,failures:i,advantages:r,threats:c,triumphs:t.triumphs,despair:t.despair,lightSide:t.lightSide,darkSide:t.darkSide}})(U.map(e=>e.result),q);if(null==a?void 0:a.hints){const e=i.filter(e=>{const{cost:a}=e;return Object.entries(a).some(([e,a])=>{const t=e.toLowerCase()+"s",s=L[t];return"number"==typeof s&&(void 0!==a&&a>0&&s>=a)})});L.hints=e.map(e=>`${function(e){if(!e.cost||0===Object.keys(e.cost).length)return"No cost";const a=Object.entries(e.cost).filter(([e,a])=>a&&a>0).map(([e,a])=>`${a} ${e.charAt(0).toUpperCase()+e.toLowerCase().slice(1)}${a>1?"s":""}`);return a.length>1?a.join(" OR "):a.length>0?a[0]:"No cost"}(e)} - ${e.description}`)}return{results:U,summary:L}},g=(e,a,t)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,a),...t}),f=(e,a,t=0,s)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,a),boostDice:Math.max(0,t),...s}),m=(e,a,t,s=0,i)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,a),difficultyDice:Math.max(0,t),challengeDice:Math.max(0,s),...i}),v=(e,a=0,t)=>({difficultyDice:Math.max(0,e),challengeDice:Math.max(0,a),...t}),S=(e,a)=>({...e,automaticSuccesses:(e.automaticSuccesses||0)+(a.automaticSuccesses||0),automaticFailures:(e.automaticFailures||0)+(a.automaticFailures||0),automaticAdvantages:(e.automaticAdvantages||0)+(a.automaticAdvantages||0),automaticThreats:(e.automaticThreats||0)+(a.automaticThreats||0),automaticTriumphs:(e.automaticTriumphs||0)+(a.automaticTriumphs||0),automaticDespairs:(e.automaticDespairs||0)+(a.automaticDespairs||0),upgradeAbility:(e.upgradeAbility||0)+(a.upgradeAbility||0),upgradeDifficulty:(e.upgradeDifficulty||0)+(a.upgradeDifficulty||0),downgradeProficiency:(e.downgradeProficiency||0)+(a.downgradeProficiency||0),downgradeChallenge:(e.downgradeChallenge||0)+(a.downgradeChallenge||0)});export{S as applyTalentModifiers,f as createCombatCheck,v as createDifficultyPool,m as createOpposedCheck,g as createSkillCheck,p as roll};
1
+ const e={SUCCESS:"SUCCESS",FAILURE:"FAILURE",ADVANTAGE:"ADVANTAGE",THREAT:"THREAT",TRIUMPH:"TRIUMPH",DESPAIR:"DESPAIR",LIGHT:"LIGHT",DARK:"DARK"},t=[{description:"Recover one strain (may be applied more than once).",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Add a boost die to the next allied active character's check.",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Notice a single important point in the ongoing conflict, such as the location of a blast door's control panel or a weak point on an attack speeder.",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Inflict a Critical Injury with a successful attack that deals damage past soak (Advantage cost may vary).",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Activate a weapon quality (Advantage cost may vary).",cost:{[e.ADVANTAGE]:1,[e.TRIUMPH]:1}},{description:"Perform an immediate free maneuver that does not exceed the two maneuver per turn limit.",cost:{[e.ADVANTAGE]:2,[e.TRIUMPH]:1}},{description:"Add a setback die to the targeted character's next check.",cost:{[e.ADVANTAGE]:2,[e.TRIUMPH]:1}},{description:"Add a boost die to any allied character's next check, including that of the active character.",cost:{[e.ADVANTAGE]:2,[e.TRIUMPH]:1}},{description:"Negate the targeted enemy's defensive bonuses (such as the defense gained from cover, equipment, or performing the Guarded Stance maneuver) util the end of the current round.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Ignore penalizing environmental effects such as inclement weather, zero gravity, or similar circumstances until the end of the active character's next turn.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain. This could include hobbling them temporarily with a shot to the leg, or disabling their comlink. This should be agreed upon by the player and the GM, and the effects are up to the GM (although Table 6-10: Critical Injury Result is a god resource to consult for possible effects). The effects should be temporary and not too excessive.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Gain + 1 melee or ranged defense until the end of the active character's next turn.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Force the target to drop a melee or ranged weapon they are wielding.",cost:{[e.ADVANTAGE]:3,[e.TRIUMPH]:1}},{description:"Upgrade the difficulty of the targeted character's next check.",cost:{[e.TRIUMPH]:1}},{description:"Do something vital, such as shooting the controls to the nearby blast doors to seal them shut.",cost:{[e.TRIUMPH]:1}},{description:"Upgrade any allied character's next check, including that of the current active character.",cost:{[e.TRIUMPH]:1}},{description:"When dealing damage to a target, have the attack destroy a piece of equipment the target is using, such as blowing up his blaster or destroying a personal shield generator.",cost:{[e.TRIUMPH]:2}},{description:"The active character suffers 1 strain.",cost:{[e.THREAT]:1,[e.DESPAIR]:1}},{description:"The active character loses the benefits of a prior maneuver (such as from taking cover or assuming a Guarded Stance) until they perform the maneuver again.",cost:{[e.THREAT]:1,[e.DESPAIR]:1}},{description:"An opponent may immediately perform one free maneuver in response to the active character's check.",cost:{[e.THREAT]:2,[e.DESPAIR]:1}},{description:"Add a boost die to the targeted character's next check.",cost:{[e.THREAT]:1,[e.DESPAIR]:1}},{description:"The active character or an allied character suffers a setback die on their next action.",cost:{[e.THREAT]:2,[e.DESPAIR]:1}},{description:"The active character falls prone.",cost:{[e.THREAT]:3,[e.DESPAIR]:1}},{description:"The active character grants the enemy a significant advantage in the ongoing encounter, such as accidentally blasting the controls to a bridge the active character was planning to use for their escape.",cost:{[e.THREAT]:3,[e.DESPAIR]:1}},{description:"The character's ranged weapon imediately runs out of ammunition and may not be used for the remainder of the encounter.",cost:{[e.DESPAIR]:1}},{description:"Upgrade the difficulty of an allied character's next check, including that of the current active character.",cost:{[e.DESPAIR]:1}},{description:"The tool or melee weapon the character is using becomes damaged.",cost:{[e.DESPAIR]:1}}];const a={1:{},2:{},3:{successes:1},4:{successes:1,advantages:1},5:{successes:1,advantages:1},6:{advantages:1}},s={1:{},2:{},3:{failures:1},4:{failures:1},5:{threats:1},6:{threats:1}},i={1:{},2:{successes:1},3:{successes:1},4:{successes:2},5:{advantages:1},6:{advantages:1},7:{successes:1,advantages:1},8:{advantages:2}},r={1:{},2:{failures:1},3:{failures:2},4:{threats:1},5:{threats:1},6:{threats:1},7:{threats:2},8:{failures:1,threats:1}},c={1:{},2:{successes:1},3:{successes:1},4:{successes:2},5:{successes:2},6:{advantages:1},7:{successes:1,advantages:1},8:{successes:1,advantages:1},9:{successes:1,advantages:1},10:{advantages:2},11:{advantages:2},12:{triumphs:1}},n={1:{},2:{failures:1},3:{failures:1},4:{failures:2},5:{failures:2},6:{threats:1},7:{threats:1},8:{failures:1,threats:1},9:{failures:1,threats:1},10:{threats:2},11:{threats:2},12:{despairs:1}},o={1:{darkSide:1},2:{darkSide:1},3:{darkSide:1},4:{darkSide:1},5:{darkSide:1},6:{darkSide:1},7:{darkSide:2},8:{lightSide:1},9:{lightSide:1},10:{lightSide:2},11:{lightSide:2},12:{lightSide:2}},d={boost:a,setback:s,ability:i,difficulty:r,proficiency:c,challenge:n,force:o},l=e=>Math.floor(Math.random()*e)+1,u=e=>{const t=a[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},h=e=>{const t=s[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},p=e=>{const t=i[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},g=e=>{const t=r[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},f=e=>{const t=c[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},m=e=>{const t=n[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},v=e=>{const t=o[e];return{successes:t.successes||0,failures:t.failures||0,advantages:t.advantages||0,threats:t.threats||0,triumphs:t.triumphs||0,despair:t.despairs||0,lightSide:t.lightSide||0,darkSide:t.darkSide||0}},y=(e,a)=>{var s,i,r,c,n,o,d,y,A;const D=(e=>{const t={...e};if(e.upgradeAbility&&e.upgradeAbility>0){let a=e.upgradeAbility;const s=t.abilityDice||0,i=Math.min(s,a);t.abilityDice=s-i,t.proficiencyDice=(t.proficiencyDice||0)+i,a-=i,a>0&&(t.proficiencyDice=(t.proficiencyDice||0)+a)}if(e.upgradeDifficulty&&e.upgradeDifficulty>0){let a=e.upgradeDifficulty;const s=t.difficultyDice||0,i=Math.min(s,a);t.difficultyDice=s-i,t.challengeDice=(t.challengeDice||0)+i,a-=i,a>0&&(t.challengeDice=(t.challengeDice||0)+a)}if(e.downgradeProficiency&&e.downgradeProficiency>0){const a=t.proficiencyDice||0,s=Math.min(a,e.downgradeProficiency);t.proficiencyDice=a-s,t.abilityDice=(t.abilityDice||0)+s}if(e.downgradeChallenge&&e.downgradeChallenge>0){const a=t.challengeDice||0,s=Math.min(a,e.downgradeChallenge);t.challengeDice=a-s,t.difficultyDice=(t.difficultyDice||0)+s}return t})(e),S=null!==(s=D.boostDice)&&void 0!==s?s:0,T=null!==(i=D.abilityDice)&&void 0!==i?i:0,b=null!==(r=D.proficiencyDice)&&void 0!==r?r:0,k=null!==(c=D.setBackDice)&&void 0!==c?c:0,M=null!==(n=D.difficultyDice)&&void 0!==n?n:0,R=null!==(o=D.challengeDice)&&void 0!==o?o:0,E=null!==(d=D.forceDice)&&void 0!==d?d:0,P=null!==(y=null==a?void 0:a.maxDicePerType)&&void 0!==y?y:100,I=null!==(A=null==a?void 0:a.maxTotalDice)&&void 0!==A?A:500,x=Math.max(0,Math.min(S,P)),w=Math.max(0,Math.min(T,P)),H=Math.max(0,Math.min(b,P)),U=Math.max(0,Math.min(k,P)),G=Math.max(0,Math.min(M,P)),N=Math.max(0,Math.min(R,P)),$=Math.max(0,Math.min(E,P)),C=S>P||T>P||b>P||k>P||M>P||R>P||E>P,V=x+w+H+U+G+N+$;if(V>I)throw new Error(`Total dice count (${V}) exceeds maximum allowed (${I}). Please reduce the number of dice in your pool.`);if(C&&(null==a?void 0:a.throwOnLimitExceeded)){const e=[];throw S>P&&e.push(`boost: ${S}`),T>P&&e.push(`ability: ${T}`),b>P&&e.push(`proficiency: ${b}`),k>P&&e.push(`setback: ${k}`),M>P&&e.push(`difficulty: ${M}`),R>P&&e.push(`challenge: ${R}`),E>P&&e.push(`force: ${E}`),new Error(`Dice counts exceed per-type limit (${P}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const L=[];for(let e=0;e<x;e++){const e=l(6);L.push({type:"boost",roll:e,result:u(e)})}for(let e=0;e<w;e++){const e=l(8);L.push({type:"ability",roll:e,result:p(e)})}for(let e=0;e<H;e++){const e=l(12);L.push({type:"proficiency",roll:e,result:f(e)})}for(let e=0;e<U;e++){const e=l(6);L.push({type:"setback",roll:e,result:h(e)})}for(let e=0;e<G;e++){const e=l(8);L.push({type:"difficulty",roll:e,result:g(e)})}for(let e=0;e<N;e++){const e=l(12);L.push({type:"challenge",roll:e,result:m(e)})}for(let e=0;e<$;e++){const e=l(12);L.push({type:"force",roll:e,result:v(e)})}const j={successes:e.automaticSuccesses,failures:e.automaticFailures,advantages:e.automaticAdvantages,threats:e.automaticThreats,triumphs:e.automaticTriumphs,despairs:e.automaticDespairs,lightSide:e.automaticLightSide,darkSide:e.automaticDarkSide},F=((e,t)=>{const a=e.reduce((e,t)=>({successes:e.successes+t.successes,failures:e.failures+t.failures,advantages:e.advantages+t.advantages,threats:e.threats+t.threats,triumphs:e.triumphs+t.triumphs,despair:e.despair+t.despair,lightSide:e.lightSide+(t.lightSide||0),darkSide:e.darkSide+(t.darkSide||0)}),{successes:(null==t?void 0:t.successes)||0,failures:(null==t?void 0:t.failures)||0,advantages:(null==t?void 0:t.advantages)||0,threats:(null==t?void 0:t.threats)||0,triumphs:(null==t?void 0:t.triumphs)||0,despair:(null==t?void 0:t.despairs)||0,lightSide:(null==t?void 0:t.lightSide)||0,darkSide:(null==t?void 0:t.darkSide)||0});let s=0,i=0;a.successes===a.failures?(s=0,i=0):a.successes>a.failures?s=a.successes-a.failures:i=a.failures-a.successes;let r=0,c=0;return a.advantages===a.threats?(r=0,c=0):a.advantages>a.threats?r=a.advantages-a.threats:c=a.threats-a.advantages,{successes:s,failures:i,advantages:r,threats:c,triumphs:a.triumphs,despair:a.despair,lightSide:a.lightSide,darkSide:a.darkSide}})(L.map(e=>e.result),j);if(null==a?void 0:a.hints){const e=t.filter(e=>{const{cost:t}=e;return Object.entries(t).some(([e,t])=>{const a=e.toLowerCase()+"s",s=F[a];return"number"==typeof s&&(void 0!==t&&t>0&&s>=t)})});F.hints=e.map(e=>`${function(e){if(!e.cost||0===Object.keys(e.cost).length)return"No cost";const t=Object.entries(e.cost).filter(([e,t])=>t&&t>0).map(([e,t])=>`${t} ${e.charAt(0).toUpperCase()+e.toLowerCase().slice(1)}${t>1?"s":""}`);return t.length>1?t.join(" OR "):t.length>0?t[0]:"No cost"}(e)} - ${e.description}`)}return{results:L,summary:F}},A=(e,t,a)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,t),...a}),D=(e,t,a=0,s)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,t),boostDice:Math.max(0,a),...s}),S=(e,t,a,s=0,i)=>({abilityDice:Math.max(0,e),proficiencyDice:Math.max(0,t),difficultyDice:Math.max(0,a),challengeDice:Math.max(0,s),...i}),T=(e,t=0,a)=>({difficultyDice:Math.max(0,e),challengeDice:Math.max(0,t),...a}),b=(e,t)=>({...e,automaticSuccesses:(e.automaticSuccesses||0)+(t.automaticSuccesses||0),automaticFailures:(e.automaticFailures||0)+(t.automaticFailures||0),automaticAdvantages:(e.automaticAdvantages||0)+(t.automaticAdvantages||0),automaticThreats:(e.automaticThreats||0)+(t.automaticThreats||0),automaticTriumphs:(e.automaticTriumphs||0)+(t.automaticTriumphs||0),automaticDespairs:(e.automaticDespairs||0)+(t.automaticDespairs||0),upgradeAbility:(e.upgradeAbility||0)+(t.upgradeAbility||0),upgradeDifficulty:(e.upgradeDifficulty||0)+(t.upgradeDifficulty||0),downgradeProficiency:(e.downgradeProficiency||0)+(t.downgradeProficiency||0),downgradeChallenge:(e.downgradeChallenge||0)+(t.downgradeChallenge||0)});export{i as ABILITY_DIE_FACES,a as BOOST_DIE_FACES,n as CHALLENGE_DIE_FACES,d as DICE_FACES,r as DIFFICULTY_DIE_FACES,o as FORCE_DIE_FACES,c as PROFICIENCY_DIE_FACES,s as SETBACK_DIE_FACES,e as SYMBOLS,b as applyTalentModifiers,D as createCombatCheck,T as createDifficultyPool,S as createOpposedCheck,A as createSkillCheck,y as roll};
2
2
  //# sourceMappingURL=bundle.esm.js.map