Compare commits

..

No commits in common. "766c1742d73c270fb325f9c7e4c43608365f263a" and "686c660e86e67c380cb799f1cc9fadfea0593c82" have entirely different histories.

12 changed files with 93 additions and 124 deletions

View file

@ -35,7 +35,7 @@ CONFIG.Dice.daggerheart = {
FateRoll: FateRoll FateRoll: FateRoll
}; };
Object.assign(CONFIG.Dice.termTypes, dice.diceTypes); CONFIG.Dice.termTypes.DualityDie = dice.diceTypes.DualityDie;
CONFIG.Actor.documentClass = documents.DhpActor; CONFIG.Actor.documentClass = documents.DhpActor;
CONFIG.Actor.dataModels = models.actors.config; CONFIG.Actor.dataModels = models.actors.config;

View file

@ -452,12 +452,8 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
const dieIndex = diceType === 'hope' ? 0 : diceType === 'fear' ? 1 : 2; const dieIndex = diceType === 'hope' ? 0 : diceType === 'fear' ? 1 : 2;
const newRoll = game.system.api.dice.DualityRoll.fromData(memberData.rollData); const newRoll = game.system.api.dice.DualityRoll.fromData(memberData.rollData);
const dice = newRoll.dice[dieIndex]; const dice = newRoll.dice[dieIndex];
await dice.reroll(`/r1=${dice.total}`, { await dice.reroll(`/r1=${dice.total}`, { liveRoll: true });
liveRoll: { await newRoll._evaluate();
roll: newRoll,
isReaction: true
}
});
const rollData = newRoll.toJSON(); const rollData = newRoll.toJSON();
this.updatePartyData( this.updatePartyData(
{ {
@ -698,7 +694,6 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
const joinedRoll = await this.getJoinedRoll(); const joinedRoll = await this.getJoinedRoll();
const mainRoll = joinedRoll.rollData; const mainRoll = joinedRoll.rollData;
const finalRoll = foundry.utils.deepClone(joinedRoll.roll);
const mainActor = this.party.system.partyMembers.find(x => x.uuid === mainRoll.options.source.actor); const mainActor = this.party.system.partyMembers.find(x => x.uuid === mainRoll.options.source.actor);
mainRoll.options.title = game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.chatMessageRollTitle'); mainRoll.options.title = game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.chatMessageRollTitle');
@ -717,33 +712,34 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
await cls.create(msgData); await cls.create(msgData);
/* Handle resource updates from the finished TagTeamRoll */ /* Handle resource updates from the finished TagTeamRoll */
const tagTeamData = this.party.system.tagTeam; // const tagTeamData = this.party.system.tagTeam;
const fearUpdate = { key: 'fear', value: null, total: null, enabled: true }; // const fearUpdate = { key: 'fear', value: null, total: null, enabled: true };
for (let memberId in tagTeamData.members) { // for (let memberId in tagTeamData.members) {
const resourceUpdates = []; // const resourceUpdates = [];
const rollGivesHope = finalRoll.isCritical || finalRoll.withHope; // const rollGivesHope = mainRoll.options.roll.isCritical || mainRoll.options.roll.result.duality === 1;
if (memberId === tagTeamData.initiator.memberId) { // if (memberId === tagTeamData.initiator.memberId) {
const value = tagTeamData.initiator.cost // const value = tagTeamData.initiator.cost
? rollGivesHope // ? rollGivesHope
? 1 - tagTeamData.initiator.cost // ? 1 - tagTeamData.initiator.cost
: -tagTeamData.initiator.cost // : -tagTeamData.initiator.cost
: 1; // : 1;
resourceUpdates.push({ key: 'hope', value: value, total: -value, enabled: true }); // resourceUpdates.push({ key: 'hope', value: value, total: -value, enabled: true });
} else if (rollGivesHope) { // } else if (rollGivesHope) {
resourceUpdates.push({ key: 'hope', value: 1, total: -1, enabled: true }); // resourceUpdates.push({ key: 'hope', value: 1, total: -1, enabled: true });
} // }
if (finalRoll.isCritical) resourceUpdates.push({ key: 'stress', value: -1, total: 1, enabled: true }); // if (mainRoll.options.roll.isCritical)
if (finalRoll.withFear) { // resourceUpdates.push({ key: 'stress', value: -1, total: 1, enabled: true });
fearUpdate.value = fearUpdate.value === null ? 1 : fearUpdate.value + 1; // if (mainRoll.options.roll.result.duality === -1) {
fearUpdate.total = fearUpdate.total === null ? -1 : fearUpdate.total - 1; // fearUpdate.value = fearUpdate.value === null ? 1 : fearUpdate.value + 1;
} // fearUpdate.total = fearUpdate.total === null ? -1 : fearUpdate.total - 1;
// }
game.actors.get(memberId).modifyResource(resourceUpdates); // game.actors.get(memberId).modifyResource(resourceUpdates);
} // }
if (fearUpdate.value) { // if (fearUpdate.value) {
mainActor.modifyResource([fearUpdate]); // mainActor.modifyResource([fearUpdate]);
} // }
/* Fin */ /* Fin */
this.cancelRoll({ confirm: false }); this.cancelRoll({ confirm: false });

View file

@ -218,6 +218,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
isReaction: message.system.roll.options.actionType === 'reaction' isReaction: message.system.roll.options.actionType === 'reaction'
} }
}); });
// await message.system.roll._evaluate();
await message.update({ await message.update({
rolls: [message.system.roll.toJSON()] rolls: [message.system.roll.toJSON()]
}); });

View file

@ -4,4 +4,4 @@ export { default as DamageRoll } from './damageRoll.mjs';
export { default as DHRoll } from './dhRoll.mjs'; export { default as DHRoll } from './dhRoll.mjs';
export { default as DualityRoll } from './dualityRoll.mjs'; export { default as DualityRoll } from './dualityRoll.mjs';
export { default as FateRoll } from './fateRoll.mjs'; export { default as FateRoll } from './fateRoll.mjs';
export { diceTypes } from './die/_module.mjs'; export { Dice, diceTypes } from './die/_module.mjs';

View file

@ -1,9 +1,7 @@
import DualityDie from './dualityDie.mjs'; import DualityDie from './dualityDie.mjs';
import AdvantageDie from './advantageDie.mjs';
import DisadvantageDie from './disadvantageDie.mjs'; export const Dice = [DualityDie];
export const diceTypes = { export const diceTypes = {
DualityDie, DualityDie
AdvantageDie,
DisadvantageDie
}; };

View file

@ -1,7 +0,0 @@
export default class AdvantageDie extends foundry.dice.terms.Die {
constructor(options) {
super(options);
this.modifiers = [];
}
}

View file

@ -1,7 +0,0 @@
export default class DisadvantageDie extends foundry.dice.terms.Die {
constructor(options) {
super(options);
this.modifiers = [];
}
}

View file

@ -17,6 +17,22 @@ export default class DualityRoll extends D20Roll {
static DefaultDialog = D20RollDialog; static DefaultDialog = D20RollDialog;
/**@inheritdoc */
static instantiateAST(ast) {
/* First two dice are always the DualityDice */
const nodes = CONFIG.Dice.parser.flattenTree(ast);
const dieNodes = nodes.filter(x => x.class === 'DiceTerm');
if (dieNodes.length > 1) {
dieNodes[0].class = 'DualityDie';
dieNodes[1].class = 'DualityDie';
}
return nodes.map(node => {
const cls = foundry.dice.terms[node.class] ?? foundry.dice.terms.RollTerm;
return cls.fromParseNode(node);
});
}
get title() { get title() {
return game.i18n.localize( return game.i18n.localize(
`DAGGERHEART.GENERAL.${this.options?.actionType === 'reaction' ? 'reactionRoll' : 'dualityRoll'}` `DAGGERHEART.GENERAL.${this.options?.actionType === 'reaction' ? 'reactionRoll' : 'dualityRoll'}`
@ -24,31 +40,27 @@ export default class DualityRoll extends D20Roll {
} }
get dHope() { get dHope() {
if (!(this.dice[0] instanceof game.system.api.dice.diceTypes.DualityDie)) this.createBaseDice(); if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
return this.dice[0]; return this.dice[0];
} }
set dHope(faces) { set dHope(faces) {
// TODO this should not be asymmetrical with the getter. updateRollConfiguration() should use dHope.faces if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
this.dHope.faces = this.getFaces(faces); this.dice[0].faces = this.getFaces(faces);
} }
get dFear() { get dFear() {
if (!(this.dice[1] instanceof game.system.api.dice.diceTypes.DualityDie)) this.createBaseDice(); if (!(this.dice[1] instanceof foundry.dice.terms.Die)) this.createBaseDice();
return this.dice[1]; return this.dice[1];
} }
set dFear(faces) { set dFear(faces) {
// TODO this should not be asymmetrical with the getter. updateRollConfiguration() should use dFear.faces if (!(this.dice[1] instanceof foundry.dice.terms.Die)) this.createBaseDice();
this.dFear.faces = this.getFaces(faces); this.dice[1].faces = this.getFaces(faces);
} }
get dAdvantage() { get dAdvantage() {
return this.dice[2] instanceof game.system.api.dice.diceTypes.AdvantageDie ? this.dice[2] : null; return this.dice[2];
}
get dDisadvantage() {
return this.dice[2] instanceof game.system.api.dice.diceTypes.DisadvantageDie ? this.dice[2] : null;
} }
get advantageFaces() { get advantageFaces() {
@ -67,11 +79,6 @@ export default class DualityRoll extends D20Roll {
this._advantageNumber = Number(value); this._advantageNumber = Number(value);
} }
get extraDice() {
const { DualityDie, AdvantageDie, DisadvantageDie } = game.system.api.dice.diceTypes;
return this.dice.filter(x => ![DualityDie, AdvantageDie, DisadvantageDie].some(die => x instanceof die));
}
/* This isn't fullproof, but trying to cover parathetical situations is ridiculously complex */ /* This isn't fullproof, but trying to cover parathetical situations is ridiculously complex */
get modifierTotal() { get modifierTotal() {
let modifierTotal = 0; let modifierTotal = 0;
@ -138,16 +145,6 @@ export default class DualityRoll extends D20Roll {
return [...(hooks ?? []), 'Duality']; return [...(hooks ?? []), 'Duality'];
} }
/** @inheritDoc */
static fromData(data) {
data.terms[0].class = 'DualityDie';
data.terms[2].class = 'DualityDie';
if (data.options.roll.advantage?.type && data.terms[4]?.faces) {
data.terms[4].class = data.options.roll.advantage.type === 1 ? 'AdvantageDie' : 'DisadvantageDie';
}
return super.fromData(data);
}
createBaseDice() { createBaseDice() {
if ( if (
this.dice[0] instanceof game.system.api.dice.diceTypes.DualityDie && this.dice[0] instanceof game.system.api.dice.diceTypes.DualityDie &&

View file

@ -21,8 +21,8 @@ export default class FateRoll extends D20Roll {
} }
set dHope(faces) { set dHope(faces) {
// TODO this should not be asymmetrical with the getter. updateRollConfiguration() should use dHope.faces if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
this.dHope.faces = this.getFaces(faces); this.dice[0].faces = this.getFaces(faces);
} }
get dFear() { get dFear() {
@ -31,8 +31,8 @@ export default class FateRoll extends D20Roll {
} }
set dFear(faces) { set dFear(faces) {
// TODO this should not be asymmetrical with the getter. updateRollConfiguration() should use dFear.faces if (!(this.dice[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
this.dFear.faces = this.getFaces(faces); this.dice[0].faces = this.getFaces(faces);
} }
get isCritical() { get isCritical() {
@ -43,22 +43,6 @@ export default class FateRoll extends D20Roll {
return this.data.fateType; return this.data.fateType;
} }
get withHope() {
if (!this._evaluatedl) return;
return this.dHope.total >= this.dFear.total;
}
get withFear() {
if (!this._evaluated) return;
return this.dHope.total < this.dFear.total;
}
get totalLabel() {
const label = this.withHope ? 'DAGGERHEART.GENERAL.hope' : 'DAGGERHEART.GENERAL.fear';
return game.i18n.localize(label);
}
static getHooks(hooks) { static getHooks(hooks) {
return [...(hooks ?? []), 'Fate']; return [...(hooks ?? []), 'Fate'];
} }

View file

@ -84,8 +84,11 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
} }
if (this.type === 'fateRoll') { if (this.type === 'fateRoll') {
html.classList.add('fate'); html.classList.add('fate');
if (this.system.roll?.fateDie) { if (this.system.roll?.fate.fateDie == 'Hope') {
html.classList.add(this.system.roll.fateDie.toLowerCase()); html.classList.add('hope');
}
if (this.system.roll?.fate.fateDie == 'Fear') {
html.classList.add('fear');
} }
} }

View file

@ -53,14 +53,14 @@
{{#if @root.advantage}} {{#if @root.advantage}}
{{#if (eq @root.advantage 1)}} {{#if (eq @root.advantage 1)}}
<div class="dice-option"> <div class="dice-option">
<img class="dice-icon" src="{{concat 'systems/daggerheart/assets/icons/dice/adv/d' @root.roll.advantageFaces '.svg'}}" alt=""> <img class="dice-icon" src="{{concat 'systems/daggerheart/assets/icons/dice/adv/' @root.roll.dAdvantage.denomination '.svg'}}" alt="">
<div class="dice-select"> <div class="dice-select">
<span class="label">{{localize "DAGGERHEART.GENERAL.Advantage.full"}}</span> <span class="label">{{localize "DAGGERHEART.GENERAL.Advantage.full"}}</span>
</div> </div>
</div> </div>
{{else if (eq @root.advantage -1)}} {{else if (eq @root.advantage -1)}}
<div class="dice-option"> <div class="dice-option">
<img class="dice-icon" src="{{concat 'systems/daggerheart/assets/icons/dice/disadv/d' @root.roll.advantageFaces '.svg'}}" alt=""> <img class="dice-icon" src="{{concat 'systems/daggerheart/assets/icons/dice/disadv/' @root.roll.dAdvantage.denomination '.svg'}}" alt="">
<div class="dice-select"> <div class="dice-select">
<span class="label">{{localize "DAGGERHEART.GENERAL.Disadvantage.full"}}</span> <span class="label">{{localize "DAGGERHEART.GENERAL.Disadvantage.full"}}</span>
</div> </div>
@ -158,7 +158,7 @@
{{/times}} {{/times}}
</select> </select>
<select name="roll.dice.advantageFaces"{{#unless advantage}} disabled{{/unless}}> <select name="roll.dice.advantageFaces"{{#unless advantage}} disabled{{/unless}}>
{{selectOptions diceOptions selected=(concat 'd' @root.roll.advantageFaces)}} {{selectOptions diceOptions selected=@root.roll.dAdvantage.denomination}}
</select> </select>
</div> </div>
{{#if abilities}} {{#if abilities}}

View file

@ -29,20 +29,20 @@
<div class="dice-tooltip"> <div class="dice-tooltip">
<div class="wrapper"> <div class="wrapper">
<div class="roll-dice"> <div class="roll-dice">
{{#if roll.fateDie}} {{#if roll.fate}}
{{#if (eq roll.fateDie "Hope")}} {{#if (eq roll.fate.fateDie "Hope")}}
<div class="roll-die"> <div class="roll-die">
<label>{{localize "DAGGERHEART.GENERAL.hope"}}</label> <label>{{localize "DAGGERHEART.GENERAL.hope"}}</label>
<div class="dice {{roll.dHope.denomination}} color-hope" data-die-index="0" data-type="hope"> <div class="dice {{roll.fate.dice}} color-hope" data-die-index="0" data-type="hope">
{{roll.dHope.total}} {{roll.fate.value}}
</div> </div>
</div> </div>
{{/if}} {{/if}}
{{#if (eq roll.fateDie "Fear")}} {{#if (eq roll.fate.fateDie "Fear")}}
<div class="roll-die"> <div class="roll-die">
<label>{{localize "DAGGERHEART.GENERAL.fear"}}</label> <label>{{localize "DAGGERHEART.GENERAL.fear"}}</label>
<div class="dice {{roll.dFear.denomination}} color-fear" data-die-index="0" data-type="fear"> <div class="dice {{roll.fate.dice}} color-fear" data-die-index="0" data-type="fear">
{{roll.dFear.total}} {{roll.fate.value}}
</div> </div>
</div> </div>
{{/if}} {{/if}}
@ -63,14 +63,14 @@
</div> </div>
</div> </div>
{{#if roll.dAdvantage}} {{#if roll.dAdvantage}}
<div class="roll-die has-plus"> <div class="roll-die {{#if roll.hasAdvantage}}has-plus{{else}}has-minus{{/if}}">
<label>{{localize "DAGGERHEART.GENERAL.Advantage.short"}}</label> {{#if roll.hasAdvantage}}
<div class="dice {{roll.dAdvantage.denomination}} color-adv">{{roll.dAdvantage.total}}</div> <label>{{localize "DAGGERHEART.GENERAL.Advantage.short"}}</label>
</div> <div class="dice {{roll.dAdavantage.denomination}} color-adv">{{roll.dAdvantage.total}}</div>
{{else if roll.dDisadvantage}} {{else}}
<div class="roll-die has-minus"> <label>{{localize "DAGGERHEART.GENERAL.Disadvantage.short"}}</label>
<label>{{localize "DAGGERHEART.GENERAL.Disadvantage.short"}}</label> <div class="dice {{roll.dAdvantage.denomination}} color-dis">{{roll.dAdvantage.total}}</div>
<div class="dice {{roll.dDisadvantage.denomination}} color-dis">{{roll.dDisadvantage.total}}</div> {{/if}}
</div> </div>
{{/if}} {{/if}}
{{#if roll.rally.dice}} {{#if roll.rally.dice}}
@ -79,11 +79,15 @@
<div class="dice {{roll.rally.dice}}">{{roll.rally.value}}</div> <div class="dice {{roll.rally.dice}}">{{roll.rally.value}}</div>
</div> </div>
{{/if}} {{/if}}
{{#each roll.extraDice}} {{#each roll.extra}}
<div class="roll-die has-plus"> {{#each results}}
<label></label> {{#unless discarded}}
<div class="dice {{this.denomination}}">{{this.total}}</div> <div class="roll-die has-plus">
</div> <label></label>
<div class="dice {{../dice}}">{{result}}</div>
</div>
{{/unless}}
{{/each}}
{{/each}} {{/each}}
{{else}} {{else}}
{{#each roll.dice}} {{#each roll.dice}}