mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 23:49:02 +01:00
Fixed up dice
This commit is contained in:
parent
e37fc83c59
commit
132d9ee6c8
20 changed files with 417 additions and 68 deletions
|
|
@ -7,3 +7,4 @@ export { default as DamageSelectionDialog } from './damageSelectionDialog.mjs';
|
|||
export { default as DeathMove } from './deathMove.mjs';
|
||||
export { default as Downtime } from './downtime.mjs';
|
||||
export { default as OwnershipSelection } from './ownershipSelection.mjs';
|
||||
export { default as ResourceDiceDialog } from './resourceDiceDialog.mjs';
|
||||
|
|
|
|||
76
module/applications/dialogs/resourceDiceDialog.mjs
Normal file
76
module/applications/dialogs/resourceDiceDialog.mjs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
|
||||
export default class ResourceDiceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(name, actorName, resource, options = {}) {
|
||||
super(options);
|
||||
|
||||
this.name = name;
|
||||
this.actorName = actorName;
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'resource-dice'],
|
||||
window: {
|
||||
icon: 'fa-solid fa-dice'
|
||||
},
|
||||
actions: {
|
||||
rerollDice: this.rerollDice
|
||||
},
|
||||
form: {
|
||||
handler: this.updateResourceDice,
|
||||
submitOnChange: true,
|
||||
submitOnClose: false
|
||||
}
|
||||
};
|
||||
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
resourceDice: {
|
||||
id: 'resourceDice',
|
||||
template: 'systems/daggerheart/templates/dialogs/dice-roll/resourceDice.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
get title() {
|
||||
return game.i18n.format('DAGGERHEART.APPLICATIONS.ResourceDice.title', { name: this.name });
|
||||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.resource = this.resource;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static async rerollDice() {
|
||||
const diceFormula = `${this.resource.max}d${this.resource.dieFaces}`;
|
||||
const roll = await new Roll(diceFormula).evaluate();
|
||||
if (game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true);
|
||||
this.rollValues = roll.terms[0].results.map(x => x.result);
|
||||
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const msg = new cls({
|
||||
user: game.user.id,
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/ui/chat/resource-roll.hbs',
|
||||
{
|
||||
user: this.actorName,
|
||||
name: this.name
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
cls.create(msg.toObject());
|
||||
this.close();
|
||||
}
|
||||
|
||||
static async create(name, actorName, resource, options = {}) {
|
||||
return new Promise(resolve => {
|
||||
const app = new this(name, actorName, resource, options);
|
||||
app.addEventListener('close', () => resolve(app.rollValues), { once: true });
|
||||
app.render({ force: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
toggleEquipItem: CharacterSheet.#toggleEquipItem,
|
||||
useItem: this.useItem, //TODO Fix this
|
||||
useAction: this.useAction,
|
||||
toggleResourceDice: this.toggleResourceDice,
|
||||
handleResourceDice: this.handleResourceDice,
|
||||
toChat: this.toChat
|
||||
},
|
||||
window: {
|
||||
|
|
@ -668,6 +670,45 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
action.use(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the used state of a resource dice.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async toggleResourceDice(event) {
|
||||
const target = event.target.closest('.item-resource');
|
||||
const item = this.getItem(event);
|
||||
if (!item) return;
|
||||
|
||||
const diceState = item.system.resource.diceStates[target.dataset.dice];
|
||||
await item.update({
|
||||
[`system.resource.diceStates.${target.dataset.dice}.used`]: diceState?.used ? !diceState.used : true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the roll values of resource dice.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async handleResourceDice(event) {
|
||||
const item = this.getItem(event);
|
||||
if (!item) return;
|
||||
|
||||
const rollValues = await game.system.api.applications.dialogs.ResourceDiceDialog.create(
|
||||
item.name,
|
||||
this.document.name,
|
||||
item.system.resource
|
||||
);
|
||||
if (!rollValues) return;
|
||||
|
||||
await item.update({
|
||||
'system.resource.diceStates': rollValues.reduce((acc, value, index) => {
|
||||
acc[index] = { value, used: false };
|
||||
return acc;
|
||||
}, {})
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send item to Chat
|
||||
* @type {ApplicationClickAction}
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
*/
|
||||
static async #addResource() {
|
||||
await this.document.update({
|
||||
'system.resource': { value: 0 }
|
||||
'system.resource': { type: 'simple', value: 0 }
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,16 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
await this.document.update({
|
||||
'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (item.type === 'feature') {
|
||||
if (target.classList.contains('hope-feature')) {
|
||||
await this.document.update({
|
||||
'system.hopeFeatures': [...this.document.system.hopeFeatures.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.classList.contains('class-feature')) {
|
||||
await this.document.update({
|
||||
'system.classFeatures': [...this.document.system.classFeatures.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'weapon') {
|
||||
if (target.classList.contains('primary-weapon-section')) {
|
||||
if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary)
|
||||
|
|
@ -144,7 +154,7 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
static async #removeItemFromCollection(_event, element) {
|
||||
const { uuid, target } = element.dataset;
|
||||
const prop = foundry.utils.getProperty(this.document.system, target);
|
||||
await this.document.update({ [target]: prop.filter(i => i.uuid !== uuid) });
|
||||
await this.document.update({ [`system.${target}`]: prop.filter(i => i.uuid !== uuid) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1334,3 +1334,14 @@ export const actionTypes = {
|
|||
label: 'DAGGERHEART.CONFIG.ActionType.reaction'
|
||||
}
|
||||
};
|
||||
|
||||
export const itemResourceTypes = {
|
||||
simple: {
|
||||
id: 'simple',
|
||||
label: 'DAGGERHEART.CONFIG.ItemResourceType.simple'
|
||||
},
|
||||
diceValue: {
|
||||
id: 'diceValue',
|
||||
label: 'DAGGERHEART.CONFIG.ItemResourceType.diceValue'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
if (this.metadata.hasResource) {
|
||||
schema.resource = new fields.SchemaField(
|
||||
{
|
||||
type: new fields.StringField({
|
||||
choices: CONFIG.DH.ITEM.itemResourceTypes,
|
||||
initial: CONFIG.DH.ITEM.itemResourceTypes.simple
|
||||
}),
|
||||
value: new fields.NumberField({ integer: true, min: 0, initial: 0 }),
|
||||
max: new fields.NumberField({ nullable: true, initial: null }),
|
||||
icon: new fields.StringField(),
|
||||
|
|
@ -46,7 +50,14 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
choices: CONFIG.DH.GENERAL.refreshTypes,
|
||||
initial: null,
|
||||
nullable: true
|
||||
})
|
||||
}),
|
||||
diceStates: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ integer: true, nullable: true, initial: null }),
|
||||
used: new fields.BooleanField({ initial: false })
|
||||
})
|
||||
),
|
||||
dieFaces: new fields.StringField({ initial: '4' })
|
||||
},
|
||||
{ nullable: true, initial: null }
|
||||
);
|
||||
|
|
@ -81,7 +92,6 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
return data;
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _preCreate(data, options, user) {
|
||||
// Skip if no initial action is required or actions already exist
|
||||
if (!this.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return;
|
||||
|
|
@ -122,6 +132,23 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
);
|
||||
}
|
||||
|
||||
async _preUpdate(data) {
|
||||
if (data.system?.resource?.max) {
|
||||
const diceStatesKeys = Object.keys(this.resource.diceStates);
|
||||
const resourceDiff = Math.abs(data.system.resource.max - diceStatesKeys.length);
|
||||
if (!resourceDiff) return;
|
||||
|
||||
const diceStates = {};
|
||||
const deleting = data.system.resource.max < diceStatesKeys.length;
|
||||
[...Array(resourceDiff).keys()].forEach(nr => {
|
||||
const key = deleting ? diceStatesKeys.length - 1 - nr : diceStatesKeys.length + nr;
|
||||
diceStates[`${deleting ? '-=' : ''}${key}`] = deleting ? null : { value: null };
|
||||
});
|
||||
|
||||
foundry.utils.setProperty(data, 'system.resource.diceStates', diceStates);
|
||||
}
|
||||
}
|
||||
|
||||
async _preDelete() {
|
||||
if (!this.actor || this.actor.type !== 'character') return;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ export const preloadHandlebarsTemplates = async function () {
|
|||
'systems/daggerheart/templates/sheets/global/partials/action-item.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/item-resource.hbs',
|
||||
'systems/daggerheart/templates/sheets/global/partials/resource-section.hbs',
|
||||
'systems/daggerheart/templates/components/card-preview.hbs',
|
||||
'systems/daggerheart/templates/levelup/parts/selectable-card-preview.hbs',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue