Merge pull request #42 from Foundryborne/#24/Updating-Adversaries

Updating adversaries
This commit is contained in:
Murilo Brito 2025-05-24 17:37:24 -03:00 committed by GitHub
commit ad1e968888
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
87 changed files with 5588 additions and 5069 deletions

View file

@ -1,6 +1,11 @@
export default class DhpChatMesssage extends ChatMessage {
async renderHTML() {
if (this.type === 'dualityRoll' || this.type === 'adversaryRoll' || this.type === 'abilityUse') {
if (
this.type === 'dualityRoll' ||
this.type === 'adversaryRoll' ||
this.type === 'damageRoll' ||
this.type === 'abilityUse'
) {
this.content = await foundry.applications.handlebars.renderTemplate(this.content, this.system);
}

View file

@ -1,7 +1,7 @@
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
export default class DamageSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
constructor(rollString, bonusDamage, hope, resolve) {
constructor(rollString, bonusDamage, resolve, hope = 0) {
super({});
this.data = {
@ -122,64 +122,3 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
this.close();
}
}
// export default class DamageSelectionDialog extends FormApplication {
// constructor(rollString, bonusDamage, resolve){
// super({}, {});
// this.data = {
// rollString,
// bonusDamage: bonusDamage.map(x => ({
// ...x,
// hopeUses: 0
// })),
// }
// this.resolve = resolve;
// }
// get title (){
// return 'Damage Options';
// }
// static get defaultOptions() {
// const defaults = super.defaultOptions;
// const overrides = {
// height: 'auto',
// width: 400,
// id: 'damage-selection',
// template: 'systems/daggerheart/templates/views/damageSelection.hbs',
// closeOnSubmit: false,
// classes: ["daggerheart", "views", "damage-selection"],
// };
// const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
// return mergedOptions;
// }
// async getData(){
// const context = super.getData();
// context.rollString = this.data.rollString;
// context.bonusDamage = this.data.bonusDamage;
// return context;
// }
// activateListeners(html) {
// super.activateListeners(html);
// html.find('.roll-button').click(this.finish.bind(this));
// html.find('.').change();
// }
// // async _updateObject(_, formData) {
// // const data = foundry.utils.expandObject(formData);
// // this.data = foundry.utils.mergeObject(this.data, data);
// // this.render(true);
// // }
// finish(){
// this.resolve(this.data);
// this.close();
// }
// }

View file

@ -1,81 +1,79 @@
export default class NpcRollSelectionDialog extends FormApplication {
constructor(experiences, resolve, isNpc) {
super({}, {});
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
export default class NpcRollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
constructor(experiences, resolve, reject) {
super({});
this.experiences = experiences;
this.resolve = resolve;
this.reject = reject;
this.selectedExperiences = [];
this.data = {
nrDice: 1,
advantage: null
};
}
get title() {
return 'Roll Options';
return game.i18n.localize('DAGGERHEART.Application.Settings.Title');
}
static get defaultOptions() {
const defaults = super.defaultOptions;
const overrides = {
height: 'auto',
width: 400,
id: 'roll-selection',
template: 'systems/daggerheart/templates/views/npcRollSelection.hbs',
closeOnSubmit: false,
submitOnChange: true,
classes: ['daggerheart', 'views', 'npc-roll-selection']
};
static DEFAULT_OPTIONS = {
tag: 'form',
id: 'roll-selection',
classes: ['daggerheart', 'views', 'npc-roll-selection'],
position: { width: '500', height: 'auto' },
actions: {
updateIsAdvantage: this.updateIsAdvantage,
selectExperience: this.selectExperience
},
form: { handler: this.updateData, submitOnChange: false }
};
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
static PARTS = {
main: {
id: 'main',
template: 'systems/daggerheart/templates/views/npcRollSelection.hbs'
}
};
return mergedOptions;
}
async getData() {
const context = super.getData();
context.nrDice = this.data.nrDice;
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
context.advantage = this.data.advantage;
context.experiences = this.experiences.map(x => ({
context.experiences = Object.values(this.experiences).map(x => ({
...x,
selected: this.selectedExperiences.find(selected => selected.id === x.id)
selected: this.selectedExperiences.find(selected => selected.id === x.id),
value: `${x.value >= 0 ? '+' : '-'}${x.value}`
}));
return context;
}
activateListeners(html) {
super.activateListeners(html);
html.find('.increase').click(_ => this.updateNrDice(1));
html.find('.decrease').click(_ => this.updateNrDice(-1));
html.find('.advantage').click(_ => this.updateIsAdvantage(true));
html.find('.disadvantage').click(_ => this.updateIsAdvantage(false));
html.find('.roll-button').click(this.finish.bind(this));
html.find('.roll-dialog-chip').click(this.selectExperience.bind(this));
}
updateNrDice(value) {
this.data.nrDice += value;
this.render();
}
updateIsAdvantage(advantage) {
static updateIsAdvantage(_, button) {
const advantage = Boolean(button.dataset.advantage);
this.data.advantage = this.data.advantage === advantage ? null : advantage;
this.render();
}
selectExperience(event) {
const experience = this.experiences[event.currentTarget.dataset.key];
this.selectedExperiences = this.selectedExperiences.find(x => x.name === experience.name)
? this.selectedExperiences.filter(x => x.name !== experience.name)
static selectExperience(_, button) {
const experience = Object.values(this.experiences).find(experience => experience.id === button.id);
this.selectedExperiences = this.selectedExperiences.find(x => x.id === experience.id)
? this.selectedExperiences.filter(x => x.id !== experience.id)
: [...this.selectedExperiences, experience];
this.render();
}
finish() {
static async updateData() {
this.resolve({ ...this.data, experiences: this.selectedExperiences });
this.close();
this.close({ updateClose: true });
}
async close(options = {}) {
const { updateClose, ...baseOptions } = options;
if (!updateClose) {
this.reject();
}
await super.close(baseOptions);
}
}

View file

@ -62,7 +62,7 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
};
get title() {
return `Roll Options`;
return game.i18n.localize('DAGGERHEART.Application.RollSelection.Title');
}
async _prepareContext(_options) {
@ -157,134 +157,3 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
this.close();
}
}
// V1.3
// const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
// export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
// constructor(experiences, bonusDamage, hopeResource, resolve, isNpc){
// super({}, {});
// this.experiences = experiences;
// this.resolve = resolve;
// this.isNpc;
// this.selectedExperiences = [];
// this.data = {
// diceOptions: [{ name: 'd12', value: 'd12' }, { name: 'd20', value: 'd20' }],
// hope: ['d12'],
// fear: ['d12'],
// advantage: null,
// disadvantage: null,
// bonusDamage: bonusDamage.reduce((acc, x) => {
// if(x.appliesOn === SYSTEM.EFFECTS.applyLocations.attackRoll.id){
// acc.push(({
// ...x,
// hopeUses: 0
// }));
// }
// return acc;
// }, []),
// hopeResource: hopeResource,
// };
// }
// static DEFAULT_OPTIONS = {
// tag: 'form',
// classes: ["daggerheart", "views", "roll-selection"],
// position: {
// width: 400,
// height: "auto"
// },
// actions: {
// selectExperience: this.selectExperience,
// decreaseHopeUse: this.decreaseHopeUse,
// increaseHopeUse: this.increaseHopeUse,
// finish: this.finish,
// },
// form: {
// handler: this.updateSelection,
// submitOnChange: true,
// closeOnSubmit: false,
// }
// };
// /** @override */
// static PARTS = {
// damageSelection: {
// id: "damageSelection",
// template: "systems/daggerheart/templates/views/rollSelection.hbs"
// }
// }
// get title() {
// return `Roll Options`;
// }
// async _prepareContext(_options) {
// const context = await super._prepareContext(_options);
// context.isNpc = this.isNpc;
// context.diceOptions = this.data.diceOptions;
// context.hope = this.data.hope;
// context.fear = this.data.fear;
// context.advantage = this.data.advantage;
// context.disadvantage = this.data.disadvantage;
// context.experiences = this.experiences.map(x => ({ ...x, selected: this.selectedExperiences.find(selected => selected.id === x.id) }));
// context.bonusDamage = this.data.bonusDamage;
// context.hopeResource = this.data.hopeResource+1;
// context.hopeUsed = this.getHopeUsed();
// return context;
// }
// static updateSelection(event, _, formData){
// const { bonusDamage, ...rest } = foundry.utils.expandObject(formData.object);
// for(var index in bonusDamage){
// this.data.bonusDamage[index].initiallySelected = bonusDamage[index].initiallySelected;
// if(bonusDamage[index].hopeUses){
// const value = Number.parseInt(bonusDamage[index].hopeUses);
// if(!Number.isNaN(value)) this.data.bonusDamage[index].hopeUses = value;
// }
// }
// this.data = foundry.utils.mergeObject(this.data, rest);
// this.render(true);
// }
// static selectExperience(_, button){
// if(this.selectedExperiences.find(x => x.id === button.dataset.key)){
// this.selectedExperiences = this.selectedExperiences.filter(x => x.id !== button.dataset.key);
// } else {
// this.selectedExperiences = [...this.selectedExperiences, this.experiences.find(x => x.id === button.dataset.key)];
// }
// this.render();
// }
// getHopeUsed(){
// return this.data.bonusDamage.reduce((acc, x) => acc+x.hopeUses, 0);
// }
// static decreaseHopeUse(_, button){
// const index = Number.parseInt(button.dataset.index);
// if(this.data.bonusDamage[index].hopeUses - 1 >= 0) {
// this.data.bonusDamage[index].hopeUses -= 1;
// this.render(true);
// }
// }
// static increaseHopeUse(_, button){
// const index = Number.parseInt(button.dataset.index);
// if(this.data.bonusDamage[index].hopeUses <= this.data.hopeResource+1) {
// this.data.bonusDamage[index].hopeUses += 1;
// this.render(true);
// }
// }
// static finish(){
// const { diceOptions, ...rest } = this.data;
// this.resolve({ ...rest, experiences: this.selectedExperiences, hopeUsed: this.getHopeUsed(), bonusDamage: this.data.bonusDamage.reduce((acc, x) => acc.concat(` + ${1+x.hopeUses}${x.value}`), "") });
// this.close();
// }
// }

View file

@ -349,7 +349,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
static async attackRoll(event, button) {
const modifier = Number.parseInt(button.dataset.value);
const { roll, diceResults, modifiers } = await this.actor.diceRoll(
const { roll, dice, advantageState, modifiers } = await this.actor.diceRoll(
{ title: `${this.actor.name} - Attack Roll`, value: modifier },
event.shiftKey
);
@ -365,11 +365,15 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
type: 'adversaryRoll',
sound: CONFIG.sounds.dice,
system: {
title: button.dataset.name,
origin: this.document.id,
roll: roll._formula,
advantageState,
total: roll._total,
modifiers: modifiers,
diceResults: diceResults,
dice: dice,
targets: targets,
damage: { value: button.dataset.damage, type: button.dataset.damageType }
},
@ -381,16 +385,15 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
}
static async addExperience() {
const experienceId = foundry.utils.randomID();
await this.document.update({
'system.experiences': [...this.document.system.experiences, { name: 'Experience', value: 1 }]
[`system.experiences.${experienceId}`]: { id: experienceId, name: 'Experience', value: 1 }
});
}
static async removeExperience(_, button) {
await this.document.update({
'system.experiences': this.document.system.experiences.filter(
(_, index) => index !== Number.parseInt(button.dataset.experience)
)
[`system.experiences.-=${button.dataset.experience}`]: null
});
}

View file

@ -4,6 +4,7 @@ import DhpDowntime from '../downtime.mjs';
import DhpLevelup from '../levelup.mjs';
import AncestrySelectionDialog from '../ancestrySelectionDialog.mjs';
import DaggerheartSheet from './daggerheart-sheet.mjs';
import { abilities } from '../../config/actorConfig.mjs';
const { ActorSheetV2 } = foundry.applications.sheets;
const { TextEditor } = foundry.applications.ux;
@ -481,9 +482,9 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
this.render();
}
static async rollAttribute(event, target) {
static async rollAttribute(event, button) {
const { roll, hope, fear, advantage, disadvantage, modifiers } = await this.document.dualityRoll(
{ title: 'Attribute Bonus', value: event.target.dataset.value },
{ title: 'Attribute Bonus', value: button.dataset.value },
event.shiftKey
);
@ -491,6 +492,10 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const msgData = {
type: 'dualityRoll',
system: {
title: game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
ability: game.i18n.localize(abilities[button.dataset.attribute].label)
}),
origin: this.document.id,
roll: roll._formula,
modifiers: modifiers,
hope: hope,
@ -551,8 +556,8 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
await this.document.update({ [update]: newValue });
}
static async attackRoll(_, event) {
const weapon = await fromUuid(event.currentTarget.dataset.weapon);
static async attackRoll(event, button) {
const weapon = await fromUuid(button.dataset.weapon);
const damage = {
value: `${this.document.system.proficiency.value}${weapon.system.damage.value}`,
type: weapon.system.damage.type,
@ -580,7 +585,10 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
type: 'dualityRoll',
sound: CONFIG.sounds.dice,
system: {
title: weapon.name,
origin: this.document.id,
roll: roll._formula,
modifiers: modifiers,
hope: hope,