@swrpg-online/dice
Version:
A TypeScript library that creates dice rolls using the narrative dice system for the Star Wars Roleplaying Game by Fantasy Flight Games and Edge Studio.
3 lines (2 loc) • 13.4 kB
JavaScript
;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:{advantages:2},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.SUCCESS]:"successes",[e.FAILURE]:"failures",[e.ADVANTAGE]:"advantages",[e.THREAT]:"threats",[e.TRIUMPH]:"triumphs",[e.DESPAIR]:"despair",[e.LIGHT]:"lightSide",[e.DARK]:"darkSide"},u=e=>Math.floor(Math.random()*e)+1,h=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}},p=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}},g=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}},f=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}},m=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}},A=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,S,y;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),T=null!==(s=D.boostDice)&&void 0!==s?s:0,E=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,I=null!==(o=D.difficultyDice)&&void 0!==o?o:0,M=null!==(n=D.challengeDice)&&void 0!==n?n:0,R=null!==(d=D.forceDice)&&void 0!==d?d:0,x=null!==(S=null==a?void 0:a.maxDicePerType)&&void 0!==S?S:100,P=null!==(y=null==a?void 0:a.maxTotalDice)&&void 0!==y?y:500,C=Math.max(0,Math.min(T,x)),H=Math.max(0,Math.min(E,x)),w=Math.max(0,Math.min(b,x)),U=Math.max(0,Math.min(k,x)),G=Math.max(0,Math.min(I,x)),N=Math.max(0,Math.min(M,x)),F=Math.max(0,Math.min(R,x)),_=T>x||E>x||b>x||k>x||I>x||M>x||R>x,V=C+H+w+U+G+N+F;if(V>P)throw new Error(`Total dice count (${V}) exceeds maximum allowed (${P}). Please reduce the number of dice in your pool.`);if(_&&(null==a?void 0:a.throwOnLimitExceeded)){const e=[];throw T>x&&e.push(`boost: ${T}`),E>x&&e.push(`ability: ${E}`),b>x&&e.push(`proficiency: ${b}`),k>x&&e.push(`setback: ${k}`),I>x&&e.push(`difficulty: ${I}`),M>x&&e.push(`challenge: ${M}`),R>x&&e.push(`force: ${R}`),new Error(`Dice counts exceed per-type limit (${x}): ${e.join(", ")}. Dice counts have been capped to the maximum.`)}const $=[];for(let e=0;e<C;e++){const e=u(6);$.push({type:"boost",roll:e,result:h(e)})}for(let e=0;e<H;e++){const e=u(8);$.push({type:"ability",roll:e,result:g(e)})}for(let e=0;e<w;e++){const e=u(12);$.push({type:"proficiency",roll:e,result:m(e)})}for(let e=0;e<U;e++){const e=u(6);$.push({type:"setback",roll:e,result:p(e)})}for(let e=0;e<G;e++){const e=u(8);$.push({type:"difficulty",roll:e,result:f(e)})}for(let e=0;e<N;e++){const e=u(12);$.push({type:"challenge",roll:e,result:A(e)})}for(let e=0;e<F;e++){const e=u(12);$.push({type:"force",roll:e,result:v(e)})}const L={successes:e.automaticSuccesses,failures:e.automaticFailures,advantages:e.automaticAdvantages,threats:e.automaticThreats,triumphs:e.automaticTriumphs,despairs:e.automaticDespairs,lightSide:e.automaticLightSide,darkSide:e.automaticDarkSide},O=((e,t)=>{const a=e.reduce((e,t)=>({successes:e.successes+t.successes+t.triumphs,failures:e.failures+t.failures+t.despair,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)+((null==t?void 0:t.triumphs)||0),failures:((null==t?void 0:t.failures)||0)+((null==t?void 0:t.despairs)||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),L);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=l[e];if(!a)return!1;const s=O[a];return"number"==typeof s&&(void 0!==t&&t>0&&s>=t)})});O.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:O}};
//# sourceMappingURL=bundle.cjs.js.map