Skip to content

Commit

Permalink
feat(graze damage): new approach to building graze rolls.
Browse files Browse the repository at this point in the history
Removed extra addition of modifier by apply damage function.
Removed excess style declaration.
  • Loading branch information
zithith committed Nov 10, 2024
1 parent ebcbb4c commit 64961a6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 30 deletions.
5 changes: 0 additions & 5 deletions src/style/sheets/item/module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,6 @@ app-item-details-damage {
flex: 2;
}

span {
flex: 3;
font-style: italic;
}

.controls {
margin-right: 0.5rem;
}
Expand Down
41 changes: 40 additions & 1 deletion src/system/dice/damage-roll.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DamageType, Skill, Attribute } from '@system/types/cosmere';
import { CosmereActorRollData } from '@system/documents/actor';
import { AdvantageMode } from '@system/types/roll';
import RollTerm from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/client-esm/dice/terms/term.mjs';

export type DamageRollData<
ActorRollData extends CosmereActorRollData = CosmereActorRollData,
Expand All @@ -15,7 +16,11 @@ export type DamageRollData<
attribute: Attribute;
};
attribute?: number;
baseRoll?: number;
damage?: {
total: DamageRoll;
unmodded: DamageRoll;
dice: foundry.dice.terms.DiceTerm[];
};
};

export interface DamageRollOptions
Expand Down Expand Up @@ -102,6 +107,40 @@ export class DamageRoll extends foundry.dice.Roll<DamageRollData> {
return this.options.advantageMode === AdvantageMode.Disadvantage;
}

/* --- Helper Functions --- */

public removeTermSafely(
conditional: (
value: RollTerm,
index: number,
obj: RollTerm[],
) => boolean,
) {
this.terms.findSplice(conditional);
if (
this.terms[this.terms.length - 1] instanceof
foundry.dice.terms.OperatorTerm
)
this.terms.pop();
this.resetFormula();
}

public replaceDieResults(sourceDicePool: foundry.dice.terms.DiceTerm[]) {
sourceDicePool.forEach((die) => {
let numDiceToAlter = die.number ?? 0;
while (numDiceToAlter > 0) {
const nextDie = this.dice.find(
(newDie) => newDie.faces === die.faces,
);
if (!nextDie) return;
nextDie.results = die.results;
numDiceToAlter--;
}
});
this._total = this._evaluateTotal();
// roll total doesn't update here!
}

/* --- Internal Functions --- */

private configureModifiers() {
Expand Down
1 change: 1 addition & 0 deletions src/system/dice/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { D20Roll, D20RollOptions, D20RollData } from './d20-roll';
import { DamageRoll, DamageRollOptions, DamageRollData } from './damage-roll';
import { AdvantageMode } from '../types/roll';
import { determineConfigurationMode } from '../utils/generic';
import { RollMode } from './types';

export * from './d20-roll';
export * from './damage-roll';
Expand Down
10 changes: 5 additions & 5 deletions src/system/documents/chat-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export class CosmereChatMessage extends ChatMessage {
'COSMERE.ChatMessage.Action.ApplyGraze',
),
icon: 'fa-solid fa-shield-halved',
callback: this.onApplyDamage.bind(this, false),
callback: this.onApplyDamage.bind(this),
},
]
: []),
Expand Down Expand Up @@ -317,7 +317,7 @@ export class CosmereChatMessage extends ChatMessage {
);
}

private onApplyDamage(includeMod = true) {
private onApplyDamage() {
// Get selected actor
const actor = (game.canvas!.tokens!.controlled?.[0]?.actor ??
game.user?.character) as CosmereActor | undefined;
Expand All @@ -333,13 +333,13 @@ export class CosmereChatMessage extends ChatMessage {
// Apply damage
void actor.applyDamage(
...damageRolls.map((r) => ({
amount: (r.total ?? 0) + (includeMod ? (r.mod ?? 0) : 0),
amount: r.total ?? 0,
type: r.damageType,
})),
);
}

private onApplyHealing(includeMod = true) {
private onApplyHealing() {
// Get selected actor
const actor = (game.canvas!.tokens!.controlled?.[0]?.actor ??
game.user?.character) as CosmereActor | undefined;
Expand All @@ -355,7 +355,7 @@ export class CosmereChatMessage extends ChatMessage {
// Apply damage
void actor.applyDamage(
...damageRolls.map((r) => ({
amount: (r.total ?? 0) + (includeMod ? (r.mod ?? 0) : 0),
amount: r.total ?? 0,
type: DamageType.Healing,
})),
);
Expand Down
44 changes: 25 additions & 19 deletions src/system/documents/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,28 +385,34 @@ export class CosmereItem<
// We want to store the unmodded damage for use in graze calcs
// This isn't a particularly perfect solution, but it's functional
// only undoing the automatic addition of the selected attribute
rollData.baseRoll = (roll.total ?? 0) - (rollData.mod ?? 0);
const unmoddedRoll = roll.clone();
rollData.damage = {
total: roll,
unmodded: unmoddedRoll,
dice: roll.dice,
};

unmoddedRoll.removeTermSafely(
(term) =>
term instanceof foundry.dice.terms.NumericTerm &&
term.total === rollData.mod,
);
await unmoddedRoll.evaluate();
unmoddedRoll.replaceDieResults(roll.dice);

// Roll the dice pool for graze damage silently if set.
let grazeRoll = undefined;
const grazeFormula =
this.system.damage.grazeOverrideFormula ?? `${rollData.baseRoll}`;
if (grazeFormula) {
grazeRoll = await damageRoll(
foundry.utils.mergeObject(options, {
formula: grazeFormula,
damageType: this.system.damage.type,
data: rollData,
}),
);
// hide from DSN
grazeRoll.dice.forEach(
(die) =>
(die.results[0] = Object.assign(die.results[0], {
hidden: true,
})),
);
}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
this.system.damage.grazeOverrideFormula || '@damage.unmodded';
const usesBaseDamage = grazeFormula.includes('@damage');
const grazeRoll = await damageRoll(
foundry.utils.mergeObject(options, {
formula: grazeFormula,
damageType: this.system.damage.type,
data: rollData,
}),
);
if (usesBaseDamage) grazeRoll.replaceDieResults(roll.dice);
if (!grazeRoll) return null;
roll.graze = grazeRoll;

Expand Down

0 comments on commit 64961a6

Please sign in to comment.