Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/module/apps/roll-dialog.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ export class GrimwildRollDialog extends foundry.applications.api.DialogV2 {
if (value !== 0) {
// Ensure there is a name to the assist
const name = nameInput.value || "Assist";
assisters[name] = value;
assisters[name] = !assisters[name]
? value
: assisters[name] + value;
}
});
const sparks = dialog.element.querySelectorAll(".sparkCheck");
Expand Down
1 change: 1 addition & 0 deletions src/module/data/actor-character.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ export default class GrimwildCharacter extends GrimwildActorBase {
name: this?.name ?? this?.parent?.name,
spark: rollData?.spark,
stat: options.stat,
diceLabel: game.i18n.localize(`GRIMWILD.Stat.${options.stat}.long`),
diceDefault: rollData?.stats?.[options.stat].value,
isBloodied: rollData?.isBloodied,
isRattled: rollData?.isRattled,
Expand Down
10 changes: 10 additions & 0 deletions src/module/dice/rolls.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ export default class GrimwildRoll extends Roll {
hasActions: false
};

if (this.options.pool) {
const dropped = chatData.dice.slice(0, this.options.pool.diceNum).filter((die) => die.result < 4);
chatData.startPool = !isPrivate
? `${this.options.pool.diceNum}d`
: "???";
chatData.endPool = !isPrivate
? `${this.options.pool.diceNum - dropped.length}d`
: "???";
}

const sixes = chatData.dice.filter((die) => die.result === 6);
const cuts = chatData.thorns.filter((die) => die.result >= 7);

Expand Down
4 changes: 3 additions & 1 deletion src/module/grimwild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { GrimwildActorMonsterSheetVue } from "./sheets/actor-monster-sheet-vue.m
import { GrimwildItemSheet } from "./sheets/item-sheet.mjs";
import { GrimwildItemSheetVue } from "./sheets/item-sheet-vue.mjs";
import { GrimwildRollTableCrucibleSheet } from "./sheets/table-crucible-sheet.mjs";
import { GrimwildRollDialog } from "./apps/roll-dialog.mjs";
// Import helper/utility classes and constants.
import { GRIMWILD } from "./helpers/config.mjs";
import * as dice from "./dice/_module.mjs";
Expand Down Expand Up @@ -42,7 +43,8 @@ globalThis.grimwild = {
GrimwildItemSheet,
GrimwildItemSheetVue,
GrimwildCombatTracker,
GrimwildRollTableCrucibleSheet
GrimwildRollTableCrucibleSheet,
GrimwildRollDialog
},
utils: {
rollItemMacro
Expand Down
3 changes: 2 additions & 1 deletion src/module/helpers/schema.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export class DicePoolField extends fields.SchemaField {
}),
max: new fields.NumberField({
min: 0
})
}),
powerPool: new fields.BooleanField()
};
super(dpFields, options, context);
}
Expand Down
121 changes: 97 additions & 24 deletions src/module/sheets/actor-sheet-vue.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ export class GrimwildActorSheetVue extends VueRenderingMixin(GrimwildBaseVueActo
let pool = null;
let rollData = {};
let fieldData = null;
let dropped = [];
const update = {};

// Handle item pools (talents).
if (itemId) {
Expand All @@ -591,27 +593,97 @@ export class GrimwildActorSheetVue extends VueRenderingMixin(GrimwildBaseVueActo

// Handle roll.
if (pool.diceNum > 0) {
const roll = new grimwild.diePools(`{${pool.diceNum}d6}`, rollData);
const result = await roll.evaluate();
const dice = result.dice[0].results;
const dropped = dice.filter((die) => die.result < 4);

// Initialize chat data.
const speaker = ChatMessage.getSpeaker({ actor: this.actor });
const rollMode = game.settings.get("core", "rollMode");
const label = item
? `[${item.type}] ${item.name}`
: `[${field}] ${fieldData[key]?.name ?? ""}`;
// Send to chat.
const msg = await roll.toMessage({
speaker: speaker,
rollMode: rollMode,
flavor: label
});
// Wait for Dice So Nice if enabled.
if (game.dice3d && msg?.id) {
await game.dice3d.waitFor3DAnimationByMessageID(msg.id);
if (tracker.pool.powerPool) {
const options = {};
const rollData = this.actor.getRollData();
const rollDialog = await grimwild.applications.GrimwildRollDialog.open({
rollData: {
name: this.actor.name,
spark: rollData?.spark,
stat: null,
diceLabel: `[${item.name}] ${tracker.label}`,
diceDefault: pool.diceNum,
isBloodied: rollData?.isBloodied,
isRattled: rollData?.isRattled,
isMarked: false,
actor: this.actor
}
});
if (rollDialog === null) {
return;
}

rollData.thorns = rollDialog.thorns;
rollData.statDice = rollDialog.dice;
options.assists = rollDialog.assisters;
options.pool = tracker.pool;
const formula = `{${rollData.statDice}d6kh, ${rollData.thorns}d8}`;
const roll = new grimwild.roll(formula, rollData, options);
const result = await roll.evaluate();
// Limit to just the pool dice when checking for dropped dice.
const dice = result.dice[0].results.slice(0, pool.diceNum);
dropped = dice.filter((die) => die.result < 4);

// Add spark to the update.
if (rollDialog.sparkUsed > 0) {
let sparkUsed = rollDialog.sparkUsed;
const newSpark = {
steps: this.document.system.spark.steps
};
// All of your spark is used.
if (sparkUsed > 1 || this.document.system.spark.value === 1) {
newSpark.steps[0] = false;
newSpark.steps[1] = false;
}
// If half of your spark is used.
else if (sparkUsed === 1 && this.document.system.spark.value > 1) {
newSpark.steps[0] = true;
newSpark.steps[1] = false;
}
update["system.spark"] = newSpark;
}

// Initialize chat data.
const speaker = ChatMessage.getSpeaker({ actor: this.actor });
const rollMode = game.settings.get("core", "rollMode");
const label = item && tracker.label
? `[${item.name}] ${tracker.label}`
: (item ? item.name : `[${field}] ${fieldData[key]?.name ?? ""}`);
// Send to chat.
const msg = await roll.toMessage({
speaker: speaker,
rollMode: rollMode,
flavor: label
});
// Wait for Dice So Nice if enabled.
if (game.dice3d && msg?.id) {
await game.dice3d.waitFor3DAnimationByMessageID(msg.id);
}
}
else {
const roll = new grimwild.diePools(`{${pool.diceNum}d6}`, rollData);
const result = await roll.evaluate();
const dice = result.dice[0].results;
dropped = dice.filter((die) => die.result < 4);

// Initialize chat data.
const speaker = ChatMessage.getSpeaker({ actor: this.actor });
const rollMode = game.settings.get("core", "rollMode");
const label = item
? `[${item.type}] ${item.name}`
: `[${field}] ${fieldData[key]?.name ?? ""}`;
// Send to chat.
const msg = await roll.toMessage({
speaker: speaker,
rollMode: rollMode,
flavor: label
});
// Wait for Dice So Nice if enabled.
if (game.dice3d && msg?.id) {
await game.dice3d.waitFor3DAnimationByMessageID(msg.id);
}
}

// Recalculate the pool value.
pool.diceNum -= dropped.length;
// Update the item.
Expand All @@ -627,11 +699,12 @@ export class GrimwildActorSheetVue extends VueRenderingMixin(GrimwildBaseVueActo
else {
fieldData.pool = pool;
}
const update = {};
update[`system.${field}`] = fieldData;
await this.document.update({
[`system.${field}`]: fieldData
});
}

// Handle actor updates.
if (Object.keys(update).length > 0) {
await this.document.update(update);
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/templates/chat/roll-action.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
{{/if}}
{{localize (concat "GRIMWILD.Dice.results." result)}}</h2>
{{#if stat}}<strong class="dice-stat">{{localize (concat "GRIMWILD.Stat." stat ".long")}}</strong>{{/if}}
{{#if startPool}}
<div class="pool-result">
<strong>{{ startPool }} &#8594; {{ endPool }}</strong>
</div>
{{/if}}
<div></div>
</div>
<div class="dice-tooltip expanded">
<section class="tooltip-part">
Expand Down
2 changes: 1 addition & 1 deletion src/templates/dialog/stat-roll.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<legend>{{localize "GRIMWILD.Dice.dice"}}</legend>
<div class="dialog-character">
<div class="dialog-stats grimwild-form-group">
<label for="stat">{{localize (concat "GRIMWILD.Stat." stat ".long")}}</label>
<label for="stat">{{diceLabel}}</label>
<input type="number" class="rollDice rollDiceInput" id="stat" name="stat" data-prev="{{diceDefault}}" data-action-input="updateDice" value="{{diceDefault}}" min="0">
</div>
<div class="dialog-spark grimwild-form-group">
Expand Down
18 changes: 12 additions & 6 deletions src/vue/components/item/talent/TalentTrackers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
<!-- Tracker -->
<div v-for="(tracker, trackerKey) in context.system.trackers" :key="trackerKey" class="form-group stacked trackers-group">
<!-- Type -->
<div class="tracker-type form-group stacked">
<label>Type</label>
<select :name="`system.trackers.${trackerKey}.type`" v-model="tracker.type">
<option value="pool">Pool</option>
<option value="points">Points</option>
</select>
<div class="tracker-type-group form-group">
<div class="tracker-type form-group stacked">
<label>Type</label>
<select :name="`system.trackers.${trackerKey}.type`" v-model="tracker.type">
<option value="pool">Pool</option>
<option value="points">Points</option>
</select>
</div>
<div v-if="tracker.type === 'pool'" class="tracker-power-pool form-group stacked">
<label>Power Pool</label>
<input type="checkbox" :name="`system.trackers.${trackerKey}.pool.powerPool`" v-model="tracker.pool.powerPool">
</div>
</div>
<!-- Options -->
<div class="tracker-options form-group">
Expand Down