mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-22 23:43:37 +02:00
more
This commit is contained in:
parent
43114187b9
commit
f78b4d1789
5 changed files with 370 additions and 57 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import { getCritDamageBonus } from '../../helpers/utils.mjs';
|
||||
import Party from '../sheets/actors/party.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
|
@ -34,7 +35,11 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
startTagTeamRoll: TagTeamDialog.#startTagTeamRoll,
|
||||
makeRoll: TagTeamDialog.#makeRoll,
|
||||
removeRoll: TagTeamDialog.#removeRoll,
|
||||
rerollDice: TagTeamDialog.#rerollDice
|
||||
rerollDice: TagTeamDialog.#rerollDice,
|
||||
makeDamageRoll: TagTeamDialog.#makeDamageRoll,
|
||||
removeDamageRoll: TagTeamDialog.#removeDamageRoll,
|
||||
selectRoll: TagTeamDialog.#selectRoll,
|
||||
finishRoll: TagTeamDialog.#finishRoll
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false }
|
||||
};
|
||||
|
|
@ -83,6 +88,8 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
partContext.rollTypes = CONFIG.DH.GENERAL.tagTeamRollTypes;
|
||||
partContext.traitOptions = CONFIG.DH.ACTOR.abilities;
|
||||
|
||||
const selectedRoll = Object.values(this.party.system.tagTeam.members).find(member => member.selected);
|
||||
const critSelected = !selectedRoll ? undefined : (selectedRoll?.rollData?.options?.isCritical ?? false);
|
||||
partContext.members = Object.keys(this.party.system.tagTeam.members).reduce((acc, actorId) => {
|
||||
const data = this.party.system.tagTeam.members[actorId];
|
||||
const actor = game.actors.get(actorId);
|
||||
|
|
@ -104,17 +111,27 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
return acc;
|
||||
}, []);
|
||||
|
||||
const hitPointsDamage = data.rollData?.options?.damage?.hitPoints;
|
||||
const preCritHitPointsDamage = data.rollData?.options?.damage?.hitPoints?.preCritData?.hitPoints;
|
||||
|
||||
acc[actorId] = {
|
||||
...data,
|
||||
key: actorId,
|
||||
readyToRoll: Boolean(data.rollChoice),
|
||||
hasRolled: Boolean(data.rollData),
|
||||
rollOptions
|
||||
rollOptions,
|
||||
damage: hitPointsDamage,
|
||||
preCritDamage: preCritHitPointsDamage,
|
||||
useCritFallback: selectedRoll !== data && critSelected === false
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const { hint, totalDamage } = await this.getInfoTexts(this.party.system.tagTeam.members, critSelected);
|
||||
partContext.hintText = hint;
|
||||
partContext.totalDamage = totalDamage;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -157,6 +174,38 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
//#endregion
|
||||
//#region Tag Team Roll
|
||||
|
||||
async getInfoTexts(members, critSelected) {
|
||||
let rollsAreFinished = true;
|
||||
let rollIsSelected = false;
|
||||
let totalDamage = null;
|
||||
for (const member of Object.values(members)) {
|
||||
const rollFinished = Boolean(member.rollData);
|
||||
|
||||
const hasDamage = member.rollData?.options?.hasDamage;
|
||||
const damageFinished =
|
||||
member.rollData?.options?.hasDamage !== undefined ? member.rollData.options.damage : true;
|
||||
|
||||
let hitPointDamage =
|
||||
critSelected === false && member.rollData?.options?.isCritical
|
||||
? member.rollData.options.damage?.hitPoints?.preCritData?.hitPoints?.total
|
||||
: member.rollData?.options?.damage?.hitPoints?.total;
|
||||
if (critSelected && member.rollData?.options?.isCritical === false) {
|
||||
hitPointDamage += await getCritDamageBonus(member.rollData.options.damage?.hitPoints?.formula ?? '');
|
||||
}
|
||||
|
||||
if (hasDamage) totalDamage = (totalDamage ?? 0) + (hitPointDamage ?? 0);
|
||||
|
||||
rollsAreFinished = rollsAreFinished && rollFinished && damageFinished;
|
||||
rollIsSelected = rollIsSelected || member.selected;
|
||||
}
|
||||
|
||||
let hint = null;
|
||||
if (!rollsAreFinished) hint = game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.hints.completeRolls');
|
||||
else if (!rollIsSelected) hint = game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.hints.selectRoll');
|
||||
|
||||
return { hint, totalDamage };
|
||||
}
|
||||
|
||||
async updateRollType(event) {
|
||||
await this.party.update({
|
||||
[`system.tagTeam.members.${event.target.dataset.member}`]: {
|
||||
|
|
@ -258,5 +307,187 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
this.render();
|
||||
}
|
||||
|
||||
static async #makeDamageRoll(_, button) {
|
||||
const { memberKey } = button.dataset;
|
||||
const actor = game.actors.find(x => x.id === memberKey);
|
||||
if (!actor) return;
|
||||
|
||||
const memberData = this.party.system.tagTeam.members[memberKey];
|
||||
const action = await foundry.utils.fromUuid(memberData.rollChoice);
|
||||
const config = {
|
||||
source: {},
|
||||
skips: {
|
||||
createMessage: true,
|
||||
resources: true,
|
||||
triggers: true
|
||||
}
|
||||
};
|
||||
|
||||
await action.workflow.get('damage').execute(config, null, true);
|
||||
if (!config.damage) return;
|
||||
|
||||
if (memberData.rollData.options.isCritical && config.damage.hitPoints) {
|
||||
const critBonus = await getCritDamageBonus(config.damage.hitPoints.formula);
|
||||
if (critBonus) {
|
||||
config.damage.hitPoints.preCritData = foundry.utils.deepClone(config.damage);
|
||||
config.damage.hitPoints.total += critBonus;
|
||||
config.damage.hitPoints.formula = `${config.damage.hitPoints.formula} + ${critBonus}`;
|
||||
config.damage.hitPoints.parts[0].total += critBonus;
|
||||
config.damage.hitPoints.parts[0].formula = `${config.damage.hitPoints.parts[0].formula} + ${critBonus}`;
|
||||
}
|
||||
}
|
||||
|
||||
const current = this.party.system.tagTeam.members[memberKey].rollData;
|
||||
await this.party.update({
|
||||
[`system.tagTeam.members.${memberKey}.rollData`]: {
|
||||
...current,
|
||||
options: {
|
||||
...current.options,
|
||||
damage: config.damage
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #removeDamageRoll(_, button) {
|
||||
const { memberKey } = button.dataset;
|
||||
const current = this.party.system.tagTeam.members[memberKey].rollData;
|
||||
await this.party.update({
|
||||
[`system.tagTeam.members.${memberKey}.rollData`]: {
|
||||
...current,
|
||||
options: {
|
||||
...current.options,
|
||||
damage: null
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #selectRoll(_, button) {
|
||||
const { memberKey } = button.dataset;
|
||||
await this.party.update({
|
||||
[`system.tagTeam.members`]: Object.entries(this.party.system.tagTeam.members).reduce(
|
||||
(acc, [key, member]) => {
|
||||
acc[key] = { selected: key === memberKey ? !member.selected : false };
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
)
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #finishRoll() {
|
||||
// const mainRollId = Object.keys(this.data.members).find(key => this.data.members[key].selected);
|
||||
// const mainRoll = game.messages.get(this.data.members[mainRollId].messageId);
|
||||
|
||||
// if (this.data.initiator.cost) {
|
||||
// const initiator = this.party.find(x => x.id === this.data.initiator.id);
|
||||
// if (initiator.system.resources.hope.value < this.data.initiator.cost) {
|
||||
// return ui.notifications.warn(
|
||||
// game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.insufficientHope')
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
let mainRoll = null;
|
||||
let secondaryRoll = null;
|
||||
for (const member of Object.values(this.party.system.tagTeam.members)) {
|
||||
if (member.selected) mainRoll = foundry.utils.deepClone(member.rollData);
|
||||
else secondaryRoll = foundry.utils.deepClone(member.rollData);
|
||||
}
|
||||
|
||||
if (!mainRoll || !secondaryRoll) return;
|
||||
|
||||
const systemData = mainRoll.options;
|
||||
|
||||
const criticalRoll = systemData.roll.isCritical;
|
||||
|
||||
if (secondaryRoll.options.hasDamage && systemData.hasDamage) {
|
||||
for (let key in secondaryRoll.options.damage) {
|
||||
var damage = secondaryRoll.options.damage[key];
|
||||
const damageTotal =
|
||||
!secondaryRoll.options.isCritical && criticalRoll
|
||||
? (await getCritDamageBonus(damage.formula)) + damage.total
|
||||
: damage.total;
|
||||
const updatedDamageParts = damage.parts;
|
||||
if (systemData.damage[key]) {
|
||||
if (!secondaryRoll.options.isCritical && criticalRoll) {
|
||||
for (let part of updatedDamageParts) {
|
||||
const criticalDamage = await getCritDamageBonus(part.formula);
|
||||
if (criticalDamage) {
|
||||
damage.formula = `${damage.formula} + ${criticalDamage}`;
|
||||
part.formula = `${part.formula} + ${criticalDamage}`;
|
||||
part.modifierTotal = part.modifierTotal + criticalDamage;
|
||||
part.total += criticalDamage;
|
||||
part.roll = new Roll(part.formula);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
secondaryRoll.options.isCritical &&
|
||||
!criticalRoll &&
|
||||
secondaryRoll.options.damage.hitPoints.preCritData
|
||||
) {
|
||||
damage = secondaryRoll.options.damage.hitPoints.preCritData[key];
|
||||
}
|
||||
|
||||
systemData.damage[key].formula = `${systemData.damage[key].formula} + ${damage.formula}`;
|
||||
systemData.damage[key].total += damageTotal;
|
||||
systemData.damage[key].parts = [...systemData.damage[key].parts, ...updatedDamageParts];
|
||||
} else {
|
||||
systemData.damage[key] = { ...damage, total: damageTotal, parts: updatedDamageParts };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mainActor = this.party.system.partyMembers.find(x => x.uuid === mainRoll.options.source.actor);
|
||||
systemData.title = game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.chatMessageRollTitle');
|
||||
const cls = getDocumentClass('ChatMessage'),
|
||||
msgData = {
|
||||
type: 'dualityRoll',
|
||||
user: game.user.id,
|
||||
title: game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.title'),
|
||||
speaker: cls.getSpeaker({ actor: mainActor }),
|
||||
system: systemData,
|
||||
rolls: [mainRoll],
|
||||
sound: null,
|
||||
flags: { core: { RollTable: true } }
|
||||
};
|
||||
|
||||
await cls.create(msgData);
|
||||
|
||||
// const fearUpdate = { key: 'fear', value: null, total: null, enabled: true };
|
||||
// for (let memberId of Object.keys(this.data.members)) {
|
||||
// const resourceUpdates = [];
|
||||
// const rollGivesHope = systemData.roll.isCritical || systemData.roll.result.duality === 1;
|
||||
// if (memberId === this.data.initiator.id) {
|
||||
// const value = this.data.initiator.cost
|
||||
// ? rollGivesHope
|
||||
// ? 1 - this.data.initiator.cost
|
||||
// : -this.data.initiator.cost
|
||||
// : 1;
|
||||
// resourceUpdates.push({ key: 'hope', value: value, total: -value, enabled: true });
|
||||
// } else if (rollGivesHope) {
|
||||
// resourceUpdates.push({ key: 'hope', value: 1, total: -1, enabled: true });
|
||||
// }
|
||||
// if (systemData.roll.isCritical) resourceUpdates.push({ key: 'stress', value: -1, total: 1, enabled: true });
|
||||
// if (systemData.roll.result.duality === -1) {
|
||||
// fearUpdate.value = fearUpdate.value === null ? 1 : fearUpdate.value + 1;
|
||||
// fearUpdate.total = fearUpdate.total === null ? -1 : fearUpdate.total - 1;
|
||||
// }
|
||||
|
||||
// this.party.find(x => x.id === memberId).modifyResource(resourceUpdates);
|
||||
// }
|
||||
|
||||
// if (fearUpdate.value) {
|
||||
// this.party.find(x => x.id === mainRollId).modifyResource([fearUpdate]);
|
||||
// }
|
||||
|
||||
/* Clear Party tag Team Data here */
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ class MemberData extends foundry.abstract.DataModel {
|
|||
label: 'Roll Type'
|
||||
}),
|
||||
rollChoice: new fields.StringField({ nullable: true, initial: null }),
|
||||
rollData: new fields.JSONField({ nullable: true, initial: null })
|
||||
rollData: new fields.JSONField({ nullable: true, initial: null }),
|
||||
selected: new fields.BooleanField({ initial: false })
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue