mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
* start development * finish party members tab * start resources tab * finish resources tab * finish inventory tab and add inital template to projects tab * add resource buttons actions methods * add group roll dialog * Main implementation * Fixed costs * Minor fixes and tweaks for the party sheet (#1239) * Minor fixes and tweaks for the party sheet * Fix scroll restoration for party sheet tabs * Finished GroupRoll * Removed/commented-out not yet implemented things * Commented out Difficulty since it's not used yet * Re-render party when members update (#1242) * Fixed so style applies in preview chat message * Added the clown car * Fixed so items can be dropped into the Party sheet * Added delete icon to inventory * Fixed TokenHUD token property useage. Fixed skipping roll message * Added visible modifier to GroupRoll leader result * Leader roll displays the large result display right away after rolling * Corrected tokenHUD for non-player-tokens * Fixed clowncar tokenData * Fixed TagTeam roll message and sound * Removed final TagTeamRoll roll sound * [PR] [Party Sheets] Sidebar character sheet changes (#1249) * Something experimenting * I am silly (wearning Dunce hat) * Stressful task * Armor functional to be hit * CSS Changes to accomadate pip boy * last minute change to resource section for better visual feeling * restoring old css for toggle * Added setting to toggle pip/number display * toggle functionality added * Fixed light-mode in characterSheet * Fixed multi-row resource pips display for character * Fixed separators * Added pip-display to Adversary and Companion. Some fixing on armor display --------- Co-authored-by: WBHarry <williambjrklund@gmail.com> * Fixed party height and resource armor update * Fixed deletebutton padding * Only showing expand-me icon on InventoryItem if there is a description to show * . * Fixed menu icon to be beige instead of white in dark mode --------- Co-authored-by: moliloo <dev.murilobrito@gmail.com> Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com> Co-authored-by: Nikhil Nagarajan <potter.nikhil@gmail.com>
290 lines
10 KiB
JavaScript
290 lines
10 KiB
JavaScript
import { RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
|
|
|
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
|
|
|
export default class RerollDamageDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
constructor(message, options = {}) {
|
|
super(options);
|
|
|
|
this.message = message;
|
|
this.damage = Object.keys(message.system.damage).reduce((acc, typeKey) => {
|
|
const type = message.system.damage[typeKey];
|
|
acc[typeKey] = Object.keys(type.parts).reduce((acc, partKey) => {
|
|
const part = type.parts[partKey];
|
|
acc[partKey] = Object.keys(part.dice).reduce((acc, diceKey) => {
|
|
const dice = part.dice[diceKey];
|
|
const activeResults = dice.results.filter(x => x.active);
|
|
acc[diceKey] = {
|
|
dice: dice.dice,
|
|
selectedResults: activeResults.length,
|
|
maxSelected: activeResults.length,
|
|
results: activeResults.map(x => ({ ...x, selected: true }))
|
|
};
|
|
|
|
return acc;
|
|
}, {});
|
|
|
|
return acc;
|
|
}, {});
|
|
|
|
return acc;
|
|
}, {});
|
|
}
|
|
|
|
static DEFAULT_OPTIONS = {
|
|
id: 'reroll-dialog',
|
|
classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'reroll-dialog'],
|
|
window: {
|
|
icon: 'fa-solid fa-dice'
|
|
},
|
|
actions: {
|
|
toggleResult: RerollDamageDialog.#toggleResult,
|
|
selectRoll: RerollDamageDialog.#selectRoll,
|
|
doReroll: RerollDamageDialog.#doReroll,
|
|
save: RerollDamageDialog.#save
|
|
}
|
|
};
|
|
|
|
/** @override */
|
|
static PARTS = {
|
|
main: {
|
|
id: 'main',
|
|
template: 'systems/daggerheart/templates/dialogs/rerollDialog/damage/main.hbs'
|
|
},
|
|
footer: {
|
|
id: 'footer',
|
|
template: 'systems/daggerheart/templates/dialogs/rerollDialog/footer.hbs'
|
|
}
|
|
};
|
|
|
|
get title() {
|
|
return game.i18n.localize('DAGGERHEART.APPLICATIONS.RerollDialog.damageTitle');
|
|
}
|
|
|
|
_attachPartListeners(partId, htmlElement, options) {
|
|
super._attachPartListeners(partId, htmlElement, options);
|
|
|
|
htmlElement.querySelectorAll('.to-reroll-input').forEach(element => {
|
|
element.addEventListener('change', this.toggleDice.bind(this));
|
|
});
|
|
}
|
|
|
|
async _prepareContext(_options) {
|
|
const context = await super._prepareContext(_options);
|
|
context.damage = this.damage;
|
|
context.disabledReroll = !this.getRerollDice().length;
|
|
context.saveDisabled = !this.isSelectionDone();
|
|
|
|
return context;
|
|
}
|
|
|
|
static async #save() {
|
|
const update = {
|
|
'system.damage': Object.keys(this.damage).reduce((acc, typeKey) => {
|
|
const type = this.damage[typeKey];
|
|
let typeTotal = 0;
|
|
const messageType = this.message.system.damage[typeKey];
|
|
const parts = Object.keys(type).map(partKey => {
|
|
const part = type[partKey];
|
|
const messagePart = messageType.parts[partKey];
|
|
let partTotal = messagePart.modifierTotal;
|
|
const dice = Object.keys(part).map(diceKey => {
|
|
const dice = part[diceKey];
|
|
const total = dice.results.reduce((acc, result) => {
|
|
if (result.active) acc += result.result;
|
|
return acc;
|
|
}, 0);
|
|
partTotal += total;
|
|
const messageDice = messagePart.dice[diceKey];
|
|
return {
|
|
...messageDice,
|
|
total: total,
|
|
results: dice.results.map(x => ({
|
|
...x,
|
|
hasRerolls: dice.results.length > 1
|
|
}))
|
|
};
|
|
});
|
|
|
|
typeTotal += partTotal;
|
|
return {
|
|
...messagePart,
|
|
total: partTotal,
|
|
dice: dice
|
|
};
|
|
});
|
|
|
|
acc[typeKey] = {
|
|
...messageType,
|
|
total: typeTotal,
|
|
parts: parts
|
|
};
|
|
|
|
return acc;
|
|
}, {})
|
|
};
|
|
await this.message.update(update);
|
|
|
|
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.TagTeamRoll });
|
|
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
|
action: socketEvent.Refresh,
|
|
data: {
|
|
refreshType: RefreshType.TagTeamRoll
|
|
}
|
|
});
|
|
|
|
await this.close();
|
|
}
|
|
|
|
getRerollDice() {
|
|
const rerollDice = [];
|
|
Object.keys(this.damage).forEach(typeKey => {
|
|
const type = this.damage[typeKey];
|
|
Object.keys(type).forEach(partKey => {
|
|
const part = type[partKey];
|
|
Object.keys(part).forEach(diceKey => {
|
|
const dice = part[diceKey];
|
|
Object.keys(dice.results).forEach(resultKey => {
|
|
const result = dice.results[resultKey];
|
|
if (result.toReroll) {
|
|
rerollDice.push({
|
|
...result,
|
|
dice: dice.dice,
|
|
type: typeKey,
|
|
part: partKey,
|
|
dice: diceKey,
|
|
result: resultKey
|
|
});
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
return rerollDice;
|
|
}
|
|
|
|
isSelectionDone() {
|
|
const diceFinishedData = [];
|
|
Object.keys(this.damage).forEach(typeKey => {
|
|
const type = this.damage[typeKey];
|
|
Object.keys(type).forEach(partKey => {
|
|
const part = type[partKey];
|
|
Object.keys(part).forEach(diceKey => {
|
|
const dice = part[diceKey];
|
|
const selected = dice.results.reduce((acc, result) => acc + (result.active ? 1 : 0), 0);
|
|
diceFinishedData.push(selected === dice.maxSelected);
|
|
});
|
|
});
|
|
});
|
|
|
|
return diceFinishedData.every(x => x);
|
|
}
|
|
|
|
toggleDice(event) {
|
|
const target = event.target;
|
|
const { type, part, dice } = target.dataset;
|
|
const toggleDice = this.damage[type][part][dice];
|
|
|
|
const existingDiceRerolls = this.getRerollDice().filter(
|
|
x => x.type === type && x.part === part && x.dice === dice
|
|
);
|
|
|
|
const allRerolled = existingDiceRerolls.length === toggleDice.results.filter(x => x.active).length;
|
|
|
|
toggleDice.toReroll = !allRerolled;
|
|
toggleDice.results.forEach(result => {
|
|
if (result.active) {
|
|
result.toReroll = !allRerolled;
|
|
}
|
|
});
|
|
|
|
this.render();
|
|
}
|
|
|
|
static #toggleResult(event) {
|
|
event.stopPropagation();
|
|
|
|
const target = event.target.closest('.to-reroll-result');
|
|
const { type, part, dice, result } = target.dataset;
|
|
const toggleDice = this.damage[type][part][dice];
|
|
const toggleResult = toggleDice.results[result];
|
|
toggleResult.toReroll = !toggleResult.toReroll;
|
|
|
|
const existingDiceRerolls = this.getRerollDice().filter(
|
|
x => x.type === type && x.part === part && x.dice === dice
|
|
);
|
|
|
|
const allToReroll = existingDiceRerolls.length === toggleDice.results.filter(x => x.active).length;
|
|
toggleDice.toReroll = allToReroll;
|
|
|
|
this.render();
|
|
}
|
|
|
|
static async #selectRoll(_, button) {
|
|
const { type, part, dice, result } = button.dataset;
|
|
|
|
const diceVal = this.damage[type][part][dice];
|
|
const diceResult = diceVal.results[result];
|
|
if (!diceResult.active && diceVal.results.filter(x => x.active).length === diceVal.maxSelected) {
|
|
return ui.notifications.warn(
|
|
game.i18n.localize('DAGGERHEART.APPLICATIONS.RerollDialog.deselectDiceNotification')
|
|
);
|
|
}
|
|
|
|
if (diceResult.active) {
|
|
diceVal.toReroll = false;
|
|
diceResult.toReroll = false;
|
|
}
|
|
|
|
diceVal.selectedResults += diceResult.active ? -1 : 1;
|
|
diceResult.active = !diceResult.active;
|
|
|
|
this.render();
|
|
}
|
|
|
|
static async #doReroll() {
|
|
const toReroll = this.getRerollDice().map(x => {
|
|
const { type, part, dice, result } = x;
|
|
const diceData = this.damage[type][part][dice].results[result];
|
|
return {
|
|
...diceData,
|
|
dice: this.damage[type][part][dice].dice,
|
|
typeKey: type,
|
|
partKey: part,
|
|
diceKey: dice,
|
|
resultsIndex: result
|
|
};
|
|
});
|
|
|
|
const roll = await new Roll(toReroll.map(x => `1${x.dice}`).join(' + ')).evaluate();
|
|
|
|
if (game.modules.get('dice-so-nice')?.active) {
|
|
const diceSoNiceRoll = {
|
|
_evaluated: true,
|
|
dice: roll.dice,
|
|
options: { appearance: {} }
|
|
};
|
|
|
|
await game.dice3d.showForRoll(diceSoNiceRoll, game.user, true);
|
|
}
|
|
|
|
toReroll.forEach((data, index) => {
|
|
const { typeKey, partKey, diceKey, resultsIndex } = data;
|
|
const rerolledDice = roll.dice[index];
|
|
|
|
const dice = this.damage[typeKey][partKey][diceKey];
|
|
dice.toReroll = false;
|
|
dice.results[resultsIndex].active = false;
|
|
dice.results[resultsIndex].discarded = true;
|
|
dice.results[resultsIndex].toReroll = false;
|
|
dice.results.splice(dice.results.length, 0, {
|
|
...rerolledDice.results[0],
|
|
toReroll: false,
|
|
selected: true
|
|
});
|
|
});
|
|
|
|
this.render();
|
|
}
|
|
}
|