Fixed reroll

This commit is contained in:
WBHarry 2026-03-03 21:31:43 +01:00
parent a0fa743b8e
commit fa277d2888
8 changed files with 83 additions and 45 deletions

View file

@ -33,7 +33,8 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
toggleSelectMember: TagTeamDialog.#toggleSelectMember, toggleSelectMember: TagTeamDialog.#toggleSelectMember,
startTagTeamRoll: TagTeamDialog.#startTagTeamRoll, startTagTeamRoll: TagTeamDialog.#startTagTeamRoll,
makeRoll: TagTeamDialog.#makeRoll, makeRoll: TagTeamDialog.#makeRoll,
removeRoll: TagTeamDialog.#removeRoll removeRoll: TagTeamDialog.#removeRoll,
rerollDice: TagTeamDialog.#rerollDice
}, },
form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false } form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false }
}; };
@ -105,6 +106,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
acc[actorId] = { acc[actorId] = {
...data, ...data,
key: actorId,
readyToRoll: Boolean(data.rollChoice), readyToRoll: Boolean(data.rollChoice),
hasRolled: Boolean(data.rollData), hasRolled: Boolean(data.rollData),
rollOptions rollOptions
@ -192,6 +194,8 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
if (!result) return; if (!result) return;
if (!game.modules.get('dice-so-nice')?.active) foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice });
const rollData = result.messageRoll.toJSON(); const rollData = result.messageRoll.toJSON();
delete rollData.options.messageRoll; delete rollData.options.messageRoll;
await this.party.update({ await this.party.update({
@ -230,5 +234,29 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
}); });
} }
static async #rerollDice(_, button) {
const { member, diceType } = button.dataset;
const memberData = this.party.system.tagTeam.members[member];
const dieIndex = diceType === 'hope' ? 0 : diceType === 'fear' ? 2 : 4;
const { parsedRoll, newRoll } = await game.system.api.dice.DualityRoll.reroll(
memberData.rollData,
dieIndex,
diceType
);
const rollData = parsedRoll.toJSON();
await this.party.update({
[`system.tagTeam.members.${member}.rollData`]: {
...rollData,
options: {
...rollData.options,
roll: newRoll
}
}
});
this.render();
}
//#endregion //#endregion
} }

View file

@ -717,8 +717,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
const costResources = const costResources =
result.costs?.filter(x => x.enabled).map(cost => ({ ...cost, value: -cost.value, total: -cost.total })) || result.costs?.filter(x => x.enabled).map(cost => ({ ...cost, value: -cost.value, total: -cost.total })) ||
{}; {};
config.resourceUpdates.addResources(costResources); result.resourceUpdates.addResources(costResources);
await config.resourceUpdates.updateResources(); await result.resourceUpdates.updateResources();
} }
//TODO: redo toggleEquipItem method //TODO: redo toggleEquipItem method

View file

@ -204,7 +204,11 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
if (!game.modules.get('dice-so-nice')?.active) foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice }); if (!game.modules.get('dice-so-nice')?.active) foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice });
const { newRoll, parsedRoll } = await rollClass.reroll(originalRoll_parsed, target, message); const { newRoll, parsedRoll } = await rollClass.reroll(
originalRoll_parsed,
target.dataset.dieIndex,
target.dataset.type
);
await game.messages.get(message._id).update({ await game.messages.get(message._id).update({
'system.roll': newRoll, 'system.roll': newRoll,

View file

@ -3,8 +3,16 @@ export default class TagTeamData extends foundry.abstract.DataModel {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
members: new fields.TypedObjectField( members: new fields.TypedObjectField(new fields.EmbeddedDataField(MemberData))
new fields.SchemaField({ };
}
}
class MemberData extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
name: new fields.StringField({ required: true }), name: new fields.StringField({ required: true }),
img: new fields.StringField({ required: true }), img: new fields.StringField({ required: true }),
rollType: new fields.StringField({ rollType: new fields.StringField({
@ -15,14 +23,10 @@ export default class TagTeamData extends foundry.abstract.DataModel {
}), }),
rollChoice: new fields.StringField({ nullable: true, initial: null }), rollChoice: new fields.StringField({ nullable: true, initial: null }),
rollData: new fields.JSONField({ nullable: true, initial: null }) rollData: new fields.JSONField({ nullable: true, initial: null })
})
)
}; };
} }
get roll() { get roll() {
const roll = CONFIG.Dice.daggerheart.DualityRoll(JSON.parse(this.rollData)); return this.rollData ? CONFIG.Dice.daggerheart.DualityRoll.fromData(this.rollData) : null;
return this.rollData ? CONFIG.Dice.daggerheart.DualityRoll(JSON.parse(this.rollData)) : null;
} }
} }

View file

@ -22,7 +22,8 @@ export default class DHRoll extends Roll {
const roll = await this.buildConfigure(config, message); const roll = await this.buildConfigure(config, message);
if (!roll) return; if (!roll) return;
config.messageRoll = roll; if (config.skips?.createMessage) config.messageRoll = roll;
await this.buildEvaluate(roll, config, (message = {})); await this.buildEvaluate(roll, config, (message = {}));
await this.buildPost(roll, config, (message = {})); await this.buildPost(roll, config, (message = {}));
return config; return config;

View file

@ -374,9 +374,9 @@ export default class DualityRoll extends D20Roll {
} }
} }
static async reroll(rollString, target, message) { static async reroll(rollBase, dieIndex, diceType) {
let parsedRoll = game.system.api.dice.DualityRoll.fromData({ ...rollString, evaluated: false }); let parsedRoll = game.system.api.dice.DualityRoll.fromData({ ...rollBase, evaluated: false });
const term = parsedRoll.terms[target.dataset.dieIndex]; const term = parsedRoll.terms[dieIndex];
await term.reroll(`/r1=${term.total}`); await term.reroll(`/r1=${term.total}`);
if (game.modules.get('dice-so-nice')?.active) { if (game.modules.get('dice-so-nice')?.active) {
const diceSoNiceRoll = { const diceSoNiceRoll = {
@ -392,36 +392,36 @@ export default class DualityRoll extends D20Roll {
}; };
const diceSoNicePresets = await getDiceSoNicePresets(`d${term._faces}`, `d${term._faces}`); const diceSoNicePresets = await getDiceSoNicePresets(`d${term._faces}`, `d${term._faces}`);
const type = target.dataset.type; if (diceSoNicePresets[diceType]) {
if (diceSoNicePresets[type]) { diceSoNiceRoll.dice[0].options = diceSoNicePresets[diceType];
diceSoNiceRoll.dice[0].options = diceSoNicePresets[type];
} }
await game.dice3d.showForRoll(diceSoNiceRoll, game.user, true); await game.dice3d.showForRoll(diceSoNiceRoll, game.user, true);
} else {
foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice });
} }
await parsedRoll.evaluate(); await parsedRoll.evaluate();
const newRoll = game.system.api.dice.DualityRoll.postEvaluate(parsedRoll, { const newRoll = game.system.api.dice.DualityRoll.postEvaluate(parsedRoll, {
targets: message.system.targets, targets: parsedRoll.options.targets ?? [],
roll: { roll: {
advantage: message.system.roll.advantage?.type, advantage: parsedRoll.options.roll.advantage?.type,
difficulty: message.system.roll.difficulty ? Number(message.system.roll.difficulty) : null difficulty: parsedRoll.options.roll.difficulty ? Number(parsedRoll.options.roll.difficulty) : null
} }
}); });
const extraIndex = newRoll.advantage ? 3 : 2; const extraIndex = newRoll.advantage ? 3 : 2;
newRoll.extra = newRoll.extra.slice(extraIndex); newRoll.extra = newRoll.extra.slice(extraIndex);
const tagTeamSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll); const actor = parsedRoll.options.source.actor
? await foundry.utils.fromUuid(parsedRoll.options.source.actor)
const actor = message.system.source.actor ? await foundry.utils.fromUuid(message.system.source.actor) : null; : null;
const config = { const config = {
source: { actor: message.system.source.actor ?? '' }, source: { actor: parsedRoll.options.source.actor ?? '' },
targets: message.system.targets, targets: parsedRoll.targets,
tagTeamSelected: Object.values(tagTeamSettings.members).some(x => x.messageId === message._id),
roll: newRoll, roll: newRoll,
rerolledRoll: message.system.roll, rerolledRoll: parsedRoll.roll,
resourceUpdates: new ResourceUpdateMap(actor) resourceUpdates: new ResourceUpdateMap(actor)
}; };

View file

@ -69,6 +69,7 @@
.roll-data { .roll-data {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center;
gap: 4px; gap: 4px;
&.hope { &.hope {
@ -88,7 +89,7 @@
.duality-label { .duality-label {
color: var(--text-color); color: var(--text-color);
font-size: var(--font-size-24); font-size: var(--font-size-20);
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
} }

View file

@ -51,19 +51,19 @@
<div class="roll-data <div class="roll-data
{{#if this.isCritical}}critical{{else}}{{#if (eq this.result.duality 1)}}hope{{else}}fear{{/if}}{{/if}}" {{#if this.isCritical}}critical{{else}}{{#if (eq this.result.duality 1)}}hope{{else}}fear{{/if}}{{/if}}"
> >
<div class="duality-label">{{localize "DAGGERHEART.GENERAL.withThing" thing=this.result.label}}</div> <div class="duality-label">{{this.total}} {{localize "DAGGERHEART.GENERAL.withThing" thing=this.result.label}}</div>
<div class="roll-dice-container"> <div class="roll-dice-container">
<div class="roll-dice"> <a class="roll-dice" data-action="rerollDice" data-member="{{../key}}" data-dice-type="hope">
<span class="dice-label">{{this.hope.value}}</span> <span class="dice-label">{{this.hope.value}}</span>
<img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" this.hope.dice ".svg"}}" /> <img src="{{concat "systems/daggerheart/assets/icons/dice/hope/" this.hope.dice ".svg"}}" />
</div> </a>
<span class="roll-operator">+</span> <span class="roll-operator">+</span>
<div class="roll-dice"> <a class="roll-dice" data-action="rerollDice" data-member="{{../key}}" data-dice-type="fear">
<span class="dice-label">{{this.fear.value}}</span> <span class="dice-label">{{this.fear.value}}</span>
<img src="{{concat "systems/daggerheart/assets/icons/dice/fear/" this.fear.dice ".svg"}}" /> <img src="{{concat "systems/daggerheart/assets/icons/dice/fear/" this.fear.dice ".svg"}}" />
</a>
</div> </div>
</div> <div class="roll-total">{{this.formula}}</div>
<div class="roll-total">{{../rollData.formula}}</div>
</div> </div>
{{/with}} {{/with}}
{{/if}} {{/if}}