mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-09 12:41:20 +01:00
Merge branch 'main' into bug/229-Narrative-Countdown-Window
This commit is contained in:
commit
939712f8f8
91 changed files with 3499 additions and 1423 deletions
|
|
@ -1,6 +1,6 @@
|
|||
export { default as DhCharacterSheet } from './sheets/character.mjs';
|
||||
export { default as DhCharacterSheet } from './sheets/actors/character.mjs';
|
||||
export { default as DhpAdversarySheet } from './sheets/actors/adversary.mjs';
|
||||
export { default as DhCompanionSheet } from './sheets/companion.mjs';
|
||||
export { default as DhpAdversarySheet } from './sheets/adversary.mjs';
|
||||
export { default as DhpClassSheet } from './sheets/items/class.mjs';
|
||||
export { default as DhpSubclass } from './sheets/items/subclass.mjs';
|
||||
export { default as DhpFeatureSheet } from './sheets/items/feature.mjs';
|
||||
|
|
@ -12,8 +12,9 @@ export { default as DhpConsumable } from './sheets/items/consumable.mjs';
|
|||
export { default as DhpWeapon } from './sheets/items/weapon.mjs';
|
||||
export { default as DhpArmor } from './sheets/items/armor.mjs';
|
||||
export { default as DhpChatMessage } from './chatMessage.mjs';
|
||||
export { default as DhpEnvironment } from './sheets/environment.mjs';
|
||||
export { default as DhpEnvironment } from './sheets/actors/environment.mjs';
|
||||
export { default as DhActiveEffectConfig } from './sheets/activeEffectConfig.mjs';
|
||||
export { default as DhContextMenu } from './contextMenu.mjs';
|
||||
export { default as DhTooltipManager } from './tooltipManager.mjs';
|
||||
|
||||
export * as api from './sheets/api/_modules.mjs';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
/** NOT USED ANYMORE - TO BE DELETED **/
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class NpcRollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import DamageDialog from '../dialogs/damageDialog.mjs';
|
|||
*/
|
||||
|
||||
export class DHRoll extends Roll {
|
||||
baseTerms = [];
|
||||
constructor(formula, data, options) {
|
||||
super(formula, data, options);
|
||||
}
|
||||
|
|
@ -37,6 +38,7 @@ export class DHRoll extends Roll {
|
|||
if (config.dialog.configure !== false) {
|
||||
// Open Roll Dialog
|
||||
const DialogClass = config.dialog?.class ?? this.DefaultDialog;
|
||||
console.log(roll, config)
|
||||
const configDialog = await DialogClass.configure(roll, config, message);
|
||||
if (!configDialog) return;
|
||||
}
|
||||
|
|
@ -97,9 +99,27 @@ export class DHRoll extends Roll {
|
|||
config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey);
|
||||
}
|
||||
|
||||
formatModifier(modifier) {
|
||||
const numTerm = modifier < 0 ? '-' : '+';
|
||||
return [
|
||||
new foundry.dice.terms.OperatorTerm({ operator: numTerm }),
|
||||
new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) })
|
||||
];
|
||||
}
|
||||
|
||||
getFaces(faces) {
|
||||
return Number((faces.startsWith('d') ? faces.replace('d', '') : faces));
|
||||
}
|
||||
|
||||
constructFormula(config) {
|
||||
// const formula = Roll.replaceFormulaData(this.options.roll.formula, config.data);
|
||||
this.terms = Roll.parse(this.options.roll.formula, config.data);
|
||||
|
||||
if (this.options.extraFormula) {
|
||||
this.terms.push(
|
||||
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
|
||||
...this.constructor.parse(this.options.extraFormula, this.options.data)
|
||||
);
|
||||
}
|
||||
return (this._formula = this.constructor.getFormula(this.terms));
|
||||
}
|
||||
}
|
||||
|
|
@ -111,12 +131,9 @@ export class DualityDie extends foundry.dice.terms.Die {
|
|||
}
|
||||
|
||||
export class D20Roll extends DHRoll {
|
||||
|
||||
constructor(formula, data = {}, options = {}) {
|
||||
super(formula, data, options);
|
||||
// this.createBaseDice();
|
||||
// this.configureModifiers();
|
||||
|
||||
// this._formula = this.resetFormula();
|
||||
this.constructFormula();
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +156,7 @@ export class D20Roll extends DHRoll {
|
|||
|
||||
set d20(faces) {
|
||||
if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
|
||||
this.terms[0].faces = faces;
|
||||
this.terms[0].faces = this.getFaces(faces);
|
||||
}
|
||||
|
||||
get dAdvantage() {
|
||||
|
|
@ -152,11 +169,11 @@ export class D20Roll extends DHRoll {
|
|||
}
|
||||
|
||||
get hasAdvantage() {
|
||||
return this.options.advantage === this.constructor.ADV_MODE.ADVANTAGE;
|
||||
return this.options.roll.advantage === this.constructor.ADV_MODE.ADVANTAGE;
|
||||
}
|
||||
|
||||
get hasDisadvantage() {
|
||||
return this.options.advantage === this.constructor.ADV_MODE.DISADVANTAGE;
|
||||
return this.options.roll.advantage === this.constructor.ADV_MODE.DISADVANTAGE;
|
||||
}
|
||||
|
||||
static applyKeybindings(config) {
|
||||
|
|
@ -170,18 +187,55 @@ export class D20Roll extends DHRoll {
|
|||
config.dialog.configure ??= !Object.values(keys).some(k => k);
|
||||
|
||||
// Determine advantage mode
|
||||
const advantage = config.advantage || keys.advantage;
|
||||
const disadvantage = config.disadvantage || keys.disadvantage;
|
||||
if (advantage && !disadvantage) config.advantage = this.ADV_MODE.ADVANTAGE;
|
||||
else if (!advantage && disadvantage) config.advantage = this.ADV_MODE.DISADVANTAGE;
|
||||
else config.advantage = this.ADV_MODE.NORMAL;
|
||||
const advantage = config.roll.advantage === this.ADV_MODE.ADVANTAGE || keys.advantage;
|
||||
const disadvantage = config.roll.advantage === this.ADV_MODE.DISADVANTAGE || keys.disadvantage;
|
||||
if (advantage && !disadvantage) config.roll.advantage = this.ADV_MODE.ADVANTAGE;
|
||||
else if (!advantage && disadvantage) config.roll.advantage = this.ADV_MODE.DISADVANTAGE;
|
||||
else config.roll.advantage = this.ADV_MODE.NORMAL;
|
||||
}
|
||||
|
||||
constructFormula(config) {
|
||||
// this.terms = [];
|
||||
this.createBaseDice();
|
||||
this.configureModifiers();
|
||||
this.resetFormula();
|
||||
return this._formula;
|
||||
}
|
||||
|
||||
createBaseDice() {
|
||||
if (this.terms[0] instanceof foundry.dice.terms.Die) return;
|
||||
if (this.terms[0] instanceof foundry.dice.terms.Die) {
|
||||
this.terms = [this.terms[0]];
|
||||
return;
|
||||
}
|
||||
this.terms[0] = new foundry.dice.terms.Die({ faces: 20 });
|
||||
}
|
||||
|
||||
configureModifiers() {
|
||||
this.applyAdvantage();
|
||||
this.applyBaseBonus();
|
||||
|
||||
this.options.experiences?.forEach(m => {
|
||||
if (this.options.data.experiences?.[m])
|
||||
this.options.roll.modifiers.push({
|
||||
label: this.options.data.experiences[m].name,
|
||||
value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value
|
||||
});
|
||||
});
|
||||
|
||||
this.options.roll.modifiers?.forEach(m => {
|
||||
this.terms.push(...this.formatModifier(m.value));
|
||||
});
|
||||
|
||||
this.baseTerms = foundry.utils.deepClone(this.terms);
|
||||
|
||||
if (this.options.extraFormula) {
|
||||
this.terms.push(
|
||||
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
|
||||
...this.constructor.parse(this.options.extraFormula, this.options.data)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
applyAdvantage() {
|
||||
this.d20.modifiers.findSplice(m => ['kh', 'kl'].includes(m));
|
||||
if (!this.hasAdvantage && !this.hasDisadvantage) this.number = 1;
|
||||
|
|
@ -191,47 +245,16 @@ export class D20Roll extends DHRoll {
|
|||
}
|
||||
}
|
||||
|
||||
// Trait bonus != Adversary
|
||||
configureModifiers() {
|
||||
this.applyAdvantage();
|
||||
// this.options.roll.modifiers = [];
|
||||
this.applyBaseBonus();
|
||||
|
||||
this.options.experiences?.forEach(m => {
|
||||
if (this.options.data.experiences?.[m])
|
||||
this.options.roll.modifiers.push({
|
||||
label: this.options.data.experiences[m].name,
|
||||
value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value
|
||||
});
|
||||
});
|
||||
this.options.roll.modifiers?.forEach(m => {
|
||||
this.terms.push(...this.formatModifier(m.value));
|
||||
});
|
||||
|
||||
if (this.options.extraFormula) {
|
||||
this.terms.push(
|
||||
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
|
||||
...this.constructor.parse(this.options.extraFormula, this.getRollData())
|
||||
);
|
||||
}
|
||||
// this.resetFormula();
|
||||
}
|
||||
|
||||
constructFormula(config) {
|
||||
this.terms = [];
|
||||
this.createBaseDice();
|
||||
this.configureModifiers();
|
||||
this.resetFormula();
|
||||
return this._formula;
|
||||
}
|
||||
|
||||
applyBaseBonus() {
|
||||
this.options.roll.modifiers = [
|
||||
this.options.roll.modifiers = [];
|
||||
if(!this.options.roll.bonus) return;
|
||||
this.options.roll.modifiers.push(
|
||||
{
|
||||
label: 'Bonus to Hit',
|
||||
value: Roll.replaceFormulaData('@attackBonus', this.data)
|
||||
value: this.options.roll.bonus
|
||||
// value: Roll.replaceFormulaData('@attackBonus', this.data)
|
||||
}
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
static postEvaluate(roll, config = {}) {
|
||||
|
|
@ -241,26 +264,22 @@ export class D20Roll extends DHRoll {
|
|||
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion;
|
||||
target.hit = this.isCritical || roll.total >= difficulty;
|
||||
});
|
||||
} else if (config.roll.difficulty)
|
||||
config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty;
|
||||
} else if (config.roll.difficulty) config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty;
|
||||
config.roll.advantage = {
|
||||
type: config.advantage,
|
||||
type: config.roll.advantage,
|
||||
dice: roll.dAdvantage?.denomination,
|
||||
value: roll.dAdvantage?.total
|
||||
};
|
||||
config.roll.modifierTotal = config.roll.modifiers.reduce((a, c) => a + Number(c.value), 0);
|
||||
}
|
||||
|
||||
getRollData() {
|
||||
return this.options.data;
|
||||
}
|
||||
|
||||
formatModifier(modifier) {
|
||||
const numTerm = modifier < 0 ? '-' : '+';
|
||||
return [
|
||||
new foundry.dice.terms.OperatorTerm({ operator: numTerm }),
|
||||
new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) })
|
||||
];
|
||||
config.roll.extra = roll.dice.filter(d => !roll.baseTerms.includes(d)).map(d => {
|
||||
return {
|
||||
dice: d.denomination,
|
||||
value: d.total
|
||||
}
|
||||
})
|
||||
config.roll.modifierTotal = 0;
|
||||
for(let i = 0; i < roll.terms.length; i++) {
|
||||
if(roll.terms[i] instanceof foundry.dice.terms.NumericTerm && !!roll.terms[i-1] && roll.terms[i-1] instanceof foundry.dice.terms.OperatorTerm) config.roll.modifierTotal += Number(`${roll.terms[i-1].operator}${roll.terms[i].total}`);
|
||||
}
|
||||
}
|
||||
|
||||
resetFormula() {
|
||||
|
|
@ -269,6 +288,8 @@ export class D20Roll extends DHRoll {
|
|||
}
|
||||
|
||||
export class DualityRoll extends D20Roll {
|
||||
_advantageFaces = 6;
|
||||
|
||||
constructor(formula, data = {}, options = {}) {
|
||||
super(formula, data, options);
|
||||
}
|
||||
|
|
@ -286,7 +307,7 @@ export class DualityRoll extends D20Roll {
|
|||
|
||||
set dHope(faces) {
|
||||
if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
||||
this.terms[0].faces = faces;
|
||||
this.terms[0].faces = this.getFaces(faces);
|
||||
// this.#hopeDice = `d${face}`;
|
||||
}
|
||||
|
||||
|
|
@ -299,7 +320,7 @@ export class DualityRoll extends D20Roll {
|
|||
|
||||
set dFear(faces) {
|
||||
if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
|
||||
this.dice[1].faces = faces;
|
||||
this.dice[1].faces = this.getFaces(faces);
|
||||
// this.#fearDice = `d${face}`;
|
||||
}
|
||||
|
||||
|
|
@ -307,6 +328,14 @@ export class DualityRoll extends D20Roll {
|
|||
return this.dice[2];
|
||||
}
|
||||
|
||||
get advantageFaces() {
|
||||
return this._advantageFaces;
|
||||
}
|
||||
|
||||
set advantageFaces(faces) {
|
||||
this._advantageFaces = this.getFaces(faces);
|
||||
}
|
||||
|
||||
get isCritical() {
|
||||
if (!this.dHope._evaluated || !this.dFear._evaluated) return;
|
||||
return this.dHope.total === this.dFear.total;
|
||||
|
|
@ -336,25 +365,25 @@ export class DualityRoll extends D20Roll {
|
|||
return game.i18n.localize(label);
|
||||
}
|
||||
|
||||
updateFormula() {
|
||||
|
||||
}
|
||||
|
||||
createBaseDice() {
|
||||
if (
|
||||
this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie &&
|
||||
this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie
|
||||
)
|
||||
if (this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie && this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie) {
|
||||
this.terms = [this.terms[0], this.terms[1], this.terms[2]];
|
||||
return;
|
||||
if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie))
|
||||
this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie();
|
||||
}
|
||||
this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie();
|
||||
this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' });
|
||||
if (!(this.dice[2] instanceof CONFIG.Dice.daggerheart.DualityDie))
|
||||
this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie();
|
||||
this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie();
|
||||
}
|
||||
|
||||
applyAdvantage() {
|
||||
const dieFaces = 6,
|
||||
const dieFaces = this.advantageFaces,
|
||||
bardRallyFaces = this.hasBarRally,
|
||||
advDie = new foundry.dice.terms.Die({ faces: dieFaces });
|
||||
if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces)
|
||||
this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' }));
|
||||
if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces) this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' }));
|
||||
if (bardRallyFaces) {
|
||||
const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces });
|
||||
if (this.hasAdvantage) {
|
||||
|
|
@ -371,12 +400,14 @@ export class DualityRoll extends D20Roll {
|
|||
}
|
||||
|
||||
applyBaseBonus() {
|
||||
this.options.roll.modifiers = [
|
||||
this.options.roll.modifiers = [];
|
||||
if(!this.options.roll.trait) return;
|
||||
this.options.roll.modifiers.push(
|
||||
{
|
||||
label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
|
||||
value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data)
|
||||
}
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
static postEvaluate(roll, config = {}) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
/** NOT USED ANYMORE - TO BE DELETED **/
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
|
||||
export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,23 @@
|
|||
import DHActionConfig from '../config/Action.mjs';
|
||||
import DaggerheartSheet from './daggerheart-sheet.mjs';
|
||||
import DHActionConfig from '../../config/Action.mjs';
|
||||
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
||||
import DHAdversarySettings from '../applications/adversary-settings.mjs';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'sheet', 'actor', 'dh-style', 'adversary'],
|
||||
position: { width: 450, height: 1000 },
|
||||
position: { width: 660, height: 766 },
|
||||
actions: {
|
||||
reactionRoll: this.reactionRoll,
|
||||
attackRoll: this.attackRoll,
|
||||
useItem: this.useItem,
|
||||
toChat: this.toChat,
|
||||
attackConfigure: this.attackConfigure,
|
||||
addExperience: this.addExperience,
|
||||
removeExperience: this.removeExperience,
|
||||
toggleHP: this.toggleHP,
|
||||
toggleStress: this.toggleStress
|
||||
toggleStress: this.toggleStress,
|
||||
openSettings: this.openSettings
|
||||
},
|
||||
form: {
|
||||
handler: this.updateForm,
|
||||
|
|
@ -24,28 +27,37 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
};
|
||||
|
||||
static PARTS = {
|
||||
sidebar: { template: 'systems/daggerheart/templates/sheets/actors/adversary/sidebar.hbs' },
|
||||
header: { template: 'systems/daggerheart/templates/sheets/actors/adversary/header.hbs' },
|
||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||
main: { template: 'systems/daggerheart/templates/sheets/actors/adversary/main.hbs' },
|
||||
information: { template: 'systems/daggerheart/templates/sheets/actors/adversary/information.hbs' }
|
||||
actions: { template: 'systems/daggerheart/templates/sheets/actors/adversary/actions.hbs' },
|
||||
notes: { template: 'systems/daggerheart/templates/sheets/actors/adversary/notes.hbs' },
|
||||
effects: { template: 'systems/daggerheart/templates/sheets/actors/adversary/effects.hbs' }
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
main: {
|
||||
actions: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'main',
|
||||
id: 'actions',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Sheets.Adversary.Tabs.Main'
|
||||
label: 'DAGGERHEART.General.tabs.actions'
|
||||
},
|
||||
information: {
|
||||
notes: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'information',
|
||||
id: 'notes',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Sheets.Adversary.Tabs.Information'
|
||||
label: 'DAGGERHEART.Sheets.Adversary.Tabs.notes'
|
||||
},
|
||||
effects: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'effects',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Sheets.Adversary.Tabs.effects'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -56,10 +68,15 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
context.systemFields.attack.fields = this.document.system.attack.schema.fields;
|
||||
context.getEffectDetails = this.getEffectDetails.bind(this);
|
||||
context.isNPC = true;
|
||||
console.log(context)
|
||||
return context;
|
||||
}
|
||||
|
||||
getAction(element) {
|
||||
const itemId = (element.target ?? element).closest('[data-item-id]').dataset.itemId,
|
||||
item = this.document.system.actions.find(x => x.id === itemId);
|
||||
return item;
|
||||
}
|
||||
|
||||
static async updateForm(event, _, formData) {
|
||||
await this.document.update(formData.object);
|
||||
this.render();
|
||||
|
|
@ -70,7 +87,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
event: event,
|
||||
title: `${this.actor.name} - Reaction Roll`,
|
||||
roll: {
|
||||
modifier: null,
|
||||
// modifier: null,
|
||||
type: 'reaction'
|
||||
},
|
||||
chatMessage: {
|
||||
|
|
@ -86,8 +103,40 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
return {};
|
||||
}
|
||||
|
||||
static async attackRoll(event) {
|
||||
this.actor.system.attack.use(event);
|
||||
static async openSettings() {
|
||||
await new DHAdversarySettings(this.document).render(true);
|
||||
}
|
||||
|
||||
static async useItem(event) {
|
||||
const action = this.getAction(event) ?? this.actor.system.attack;
|
||||
action.use(event);
|
||||
}
|
||||
|
||||
static async toChat(event, button) {
|
||||
if (button?.dataset?.type === 'experience') {
|
||||
const experience = this.document.system.experiences[button.dataset.uuid];
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const systemData = {
|
||||
name: game.i18n.localize('DAGGERHEART.General.Experience.Single'),
|
||||
description: `${experience.name} ${
|
||||
experience.modifier < 0 ? experience.modifier : `+${experience.modifier}`
|
||||
}`
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
user: game.user.id,
|
||||
system: systemData,
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
||||
systemData
|
||||
)
|
||||
});
|
||||
|
||||
cls.create(msg.toObject());
|
||||
} else {
|
||||
const item = this.getAction(event) ?? this.document.system.attack;
|
||||
item.toChat(this.document.id);
|
||||
}
|
||||
}
|
||||
|
||||
static async attackConfigure(event) {
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import { capitalize } from '../../helpers/utils.mjs';
|
||||
import DhpDeathMove from '../deathMove.mjs';
|
||||
import DhpDowntime from '../downtime.mjs';
|
||||
import AncestrySelectionDialog from '../ancestrySelectionDialog.mjs';
|
||||
import DaggerheartSheet from './daggerheart-sheet.mjs';
|
||||
import { abilities } from '../../config/actorConfig.mjs';
|
||||
import DhCharacterlevelUp from '../levelup/characterLevelup.mjs';
|
||||
import DhCharacterCreation from '../characterCreation.mjs';
|
||||
import { capitalize } from '../../../helpers/utils.mjs';
|
||||
import DhpDeathMove from '../../deathMove.mjs';
|
||||
import DhpDowntime from '../../downtime.mjs';
|
||||
import AncestrySelectionDialog from '../../ancestrySelectionDialog.mjs';
|
||||
import DaggerheartSheet from '.././daggerheart-sheet.mjs';
|
||||
import { abilities } from '../../../config/actorConfig.mjs';
|
||||
import DhCharacterlevelUp from '../../levelup/characterLevelup.mjs';
|
||||
import DhCharacterCreation from '../../characterCreation.mjs';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
const { TextEditor } = foundry.applications.ux;
|
||||
|
|
@ -727,9 +727,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const cls = getDocumentClass('ChatMessage');
|
||||
const systemData = {
|
||||
name: game.i18n.localize('DAGGERHEART.General.Experience.Single'),
|
||||
description: `${experience.description} ${
|
||||
experience.total < 0 ? experience.total : `+${experience.total}`
|
||||
}`
|
||||
description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}`
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
131
module/applications/sheets/actors/environment.mjs
Normal file
131
module/applications/sheets/actors/environment.mjs
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
import DaggerheartSheet from '../daggerheart-sheet.mjs';
|
||||
import DHEnvironmentSettings from '../applications/environment-settings.mjs';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'sheet', 'actor', 'dh-style', 'environment'],
|
||||
position: {
|
||||
width: 500
|
||||
},
|
||||
actions: {
|
||||
addAdversary: this.addAdversary,
|
||||
deleteProperty: this.deleteProperty,
|
||||
viewAdversary: this.viewAdversary,
|
||||
openSettings: this.openSettings,
|
||||
useItem: this.useItem,
|
||||
toChat: this.toChat
|
||||
},
|
||||
form: {
|
||||
handler: this._updateForm,
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false
|
||||
},
|
||||
dragDrop: [{ dragSelector: '.action-section .inventory-item', dropSelector: null }]
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
header: { template: 'systems/daggerheart/templates/sheets/actors/environment/header.hbs' },
|
||||
actions: { template: 'systems/daggerheart/templates/sheets/actors/environment/actions.hbs' },
|
||||
potentialAdversaries: {
|
||||
template: 'systems/daggerheart/templates/sheets/actors/environment/potentialAdversaries.hbs'
|
||||
},
|
||||
notes: { template: 'systems/daggerheart/templates/sheets/actors/environment/notes.hbs' }
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
actions: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'actions',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.actions'
|
||||
},
|
||||
potentialAdversaries: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'potentialAdversaries',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.potentialAdversaries'
|
||||
},
|
||||
notes: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'notes',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Sheets.Adversary.Tabs.notes'
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.document = this.document;
|
||||
context.tabs = super._getTabs(this.constructor.TABS);
|
||||
context.getEffectDetails = this.getEffectDetails.bind(this);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
getAction(element) {
|
||||
const itemId = (element.target ?? element).closest('[data-item-id]').dataset.itemId,
|
||||
item = this.document.system.actions.find(x => x.id === itemId);
|
||||
return item;
|
||||
}
|
||||
|
||||
static async openSettings() {
|
||||
await new DHEnvironmentSettings(this.document).render(true);
|
||||
}
|
||||
|
||||
static async _updateForm(event, _, formData) {
|
||||
await this.document.update(formData.object);
|
||||
this.render();
|
||||
}
|
||||
|
||||
getEffectDetails(id) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static async addAdversary() {
|
||||
await this.document.update({
|
||||
[`system.potentialAdversaries.${foundry.utils.randomID()}.label`]: game.i18n.localize(
|
||||
'DAGGERHEART.Sheets.Environment.newAdversary'
|
||||
)
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async deleteProperty(_, target) {
|
||||
await this.document.update({ [`${target.dataset.path}.-=${target.id}`]: null });
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async viewAdversary(_, button) {
|
||||
const adversary = await foundry.utils.fromUuid(button.dataset.adversary);
|
||||
adversary.sheet.render(true);
|
||||
}
|
||||
|
||||
static async useItem(event) {
|
||||
const action = this.getAction(event);
|
||||
action.use(event);
|
||||
}
|
||||
|
||||
static async toChat(event) {
|
||||
const item = this.getAction(event);
|
||||
item.toChat(this.document.id);
|
||||
}
|
||||
|
||||
async _onDragStart(event) {
|
||||
const item = event.currentTarget.closest('.inventory-item');
|
||||
|
||||
if (item) {
|
||||
const adversary = game.actors.find(x => x.type === 'adversary' && x.id === item.dataset.itemId);
|
||||
const adversaryData = { type: 'Actor', uuid: adversary.uuid };
|
||||
event.dataTransfer.setData('text/plain', JSON.stringify(adversaryData));
|
||||
event.dataTransfer.setDragImage(item, 60, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
181
module/applications/sheets/applications/adversary-settings.mjs
Normal file
181
module/applications/sheets/applications/adversary-settings.mjs
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
import DHActionConfig from '../../config/Action.mjs';
|
||||
import DHBaseItemSheet from '../api/base-item.mjs';
|
||||
import { actionsTypes } from '../../../data/_module.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class DHAdversarySettings extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(actor) {
|
||||
super({});
|
||||
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return `${game.i18n.localize('DAGGERHEART.Sheets.TABS.settings')}`;
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'dh-style', 'dialog', 'adversary-settings'],
|
||||
window: {
|
||||
icon: 'fa-solid fa-wrench',
|
||||
resizable: false
|
||||
},
|
||||
position: { width: 455, height: 'auto' },
|
||||
actions: {
|
||||
addExperience: this.#addExperience,
|
||||
removeExperience: this.#removeExperience,
|
||||
addAction: this.#addAction,
|
||||
editAction: this.#editAction,
|
||||
removeAction: this.#removeAction
|
||||
},
|
||||
form: {
|
||||
handler: this.updateForm,
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false
|
||||
}
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
header: {
|
||||
id: 'header',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/header.hbs'
|
||||
},
|
||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||
details: {
|
||||
id: 'details',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/details.hbs'
|
||||
},
|
||||
attack: {
|
||||
id: 'attack',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/attack.hbs'
|
||||
},
|
||||
experiences: {
|
||||
id: 'experiences',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/experiences.hbs'
|
||||
},
|
||||
actions: {
|
||||
id: 'actions',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/actions.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
details: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'details',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.details'
|
||||
},
|
||||
attack: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'attack',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.attack'
|
||||
},
|
||||
experiences: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'experiences',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.experiences'
|
||||
},
|
||||
actions: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'actions',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.actions'
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.document = this.actor;
|
||||
context.tabs = this._getTabs(this.constructor.TABS);
|
||||
context.systemFields = this.actor.system.schema.fields;
|
||||
context.systemFields.attack.fields = this.actor.system.attack.schema.fields;
|
||||
context.isNPC = true;
|
||||
console.log(context)
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
_getTabs(tabs) {
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
|
||||
v.cssClass = v.active ? 'active' : '';
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
static async #addExperience() {
|
||||
const newExperience = {
|
||||
name: 'Experience',
|
||||
modifier: 0
|
||||
};
|
||||
await this.actor.update({ [`system.experiences.${foundry.utils.randomID()}`]: newExperience });
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #removeExperience(_, target) {
|
||||
await this.actor.update({ [`system.experiences.-=${target.dataset.experience}`]: null });
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #addAction(_event, _button) {
|
||||
const actionType = await DHBaseItemSheet.selectActionType();
|
||||
if (!actionType) return;
|
||||
try {
|
||||
const cls = actionsTypes[actionType] ?? actionsTypes.attack,
|
||||
action = new cls(
|
||||
{
|
||||
_id: foundry.utils.randomID(),
|
||||
type: actionType,
|
||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name),
|
||||
...cls.getSourceConfig(this.actor)
|
||||
},
|
||||
{
|
||||
parent: this.actor
|
||||
}
|
||||
);
|
||||
await this.actor.update({ 'system.actions': [...this.actor.system.actions, action] });
|
||||
await new DHActionConfig(this.actor.system.actions[this.actor.system.actions.length - 1]).render({
|
||||
force: true
|
||||
});
|
||||
this.render();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
static async #editAction(event, target) {
|
||||
event.stopPropagation();
|
||||
const actionIndex = target.dataset.index;
|
||||
await new DHActionConfig(this.actor.system.actions[actionIndex]).render({
|
||||
force: true
|
||||
});
|
||||
}
|
||||
|
||||
static async #removeAction(event, target) {
|
||||
event.stopPropagation();
|
||||
const actionIndex = target.dataset.index;
|
||||
await this.actor.update({
|
||||
'system.actions': this.actor.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex))
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async updateForm(event, _, formData) {
|
||||
await this.actor.update(formData.object);
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
213
module/applications/sheets/applications/environment-settings.mjs
Normal file
213
module/applications/sheets/applications/environment-settings.mjs
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
import DHActionConfig from '../../config/Action.mjs';
|
||||
import DHBaseItemSheet from '../api/base-item.mjs';
|
||||
import { actionsTypes } from '../../../data/_module.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(actor) {
|
||||
super({});
|
||||
|
||||
this.actor = actor;
|
||||
this._dragDrop = this._createDragDropHandlers();
|
||||
}
|
||||
|
||||
get title() {
|
||||
return `${game.i18n.localize('DAGGERHEART.Sheets.TABS.settings')}`;
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'dh-style', 'dialog', 'environment-settings'],
|
||||
window: {
|
||||
icon: 'fa-solid fa-wrench',
|
||||
resizable: false
|
||||
},
|
||||
position: { width: 455, height: 'auto' },
|
||||
actions: {
|
||||
addAction: this.#addAction,
|
||||
editAction: this.#editAction,
|
||||
removeAction: this.#removeAction,
|
||||
addCategory: this.#addCategory,
|
||||
deleteProperty: this.#deleteProperty,
|
||||
viewAdversary: this.#viewAdversary,
|
||||
deleteAdversary: this.#deleteAdversary
|
||||
},
|
||||
form: {
|
||||
handler: this.updateForm,
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false
|
||||
},
|
||||
dragDrop: [{ dragSelector: null, dropSelector: '.category-container' }]
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
header: {
|
||||
id: 'header',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/header.hbs'
|
||||
},
|
||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||
details: {
|
||||
id: 'details',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/details.hbs'
|
||||
},
|
||||
actions: {
|
||||
id: 'actions',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/actions.hbs'
|
||||
},
|
||||
adversaries: {
|
||||
id: 'adversaries',
|
||||
template: 'systems/daggerheart/templates/sheets/applications/environment-settings/adversaries.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
details: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'details',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.details'
|
||||
},
|
||||
actions: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'actions',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.actions'
|
||||
},
|
||||
adversaries: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'adversaries',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.General.tabs.adversaries'
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.document = this.actor;
|
||||
context.tabs = this._getTabs(this.constructor.TABS);
|
||||
context.systemFields = this.actor.system.schema.fields;
|
||||
context.isNPC = true;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
|
||||
this._dragDrop.forEach(d => d.bind(htmlElement));
|
||||
}
|
||||
|
||||
_createDragDropHandlers() {
|
||||
return this.options.dragDrop.map(d => {
|
||||
d.callbacks = {
|
||||
drop: this._onDrop.bind(this)
|
||||
};
|
||||
return new foundry.applications.ux.DragDrop.implementation(d);
|
||||
});
|
||||
}
|
||||
|
||||
_getTabs(tabs) {
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
|
||||
v.cssClass = v.active ? 'active' : '';
|
||||
}
|
||||
|
||||
return tabs;
|
||||
}
|
||||
|
||||
static async #addAction(_event, _button) {
|
||||
const actionType = await DHBaseItemSheet.selectActionType();
|
||||
if (!actionType) return;
|
||||
try {
|
||||
const cls = actionsTypes[actionType] ?? actionsTypes.attack,
|
||||
action = new cls(
|
||||
{
|
||||
_id: foundry.utils.randomID(),
|
||||
type: actionType,
|
||||
name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name),
|
||||
...cls.getSourceConfig(this.actor)
|
||||
},
|
||||
{
|
||||
parent: this.actor
|
||||
}
|
||||
);
|
||||
await this.actor.update({ 'system.actions': [...this.actor.system.actions, action] });
|
||||
await new DHActionConfig(this.actor.system.actions[this.actor.system.actions.length - 1]).render({
|
||||
force: true
|
||||
});
|
||||
this.render();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
static async #editAction(event, target) {
|
||||
event.stopPropagation();
|
||||
const actionIndex = target.dataset.index;
|
||||
await new DHActionConfig(this.actor.system.actions[actionIndex]).render({
|
||||
force: true
|
||||
});
|
||||
}
|
||||
|
||||
static async #removeAction(event, target) {
|
||||
event.stopPropagation();
|
||||
const actionIndex = target.dataset.index;
|
||||
await this.actor.update({
|
||||
'system.actions': this.actor.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex))
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #addCategory() {
|
||||
await this.actor.update({
|
||||
[`system.potentialAdversaries.${foundry.utils.randomID()}.label`]: game.i18n.localize(
|
||||
'DAGGERHEART.Sheets.Environment.newAdversary'
|
||||
)
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #deleteProperty(_, target) {
|
||||
await this.actor.update({ [`${target.dataset.path}.-=${target.id}`]: null });
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #viewAdversary(_, button) {
|
||||
const adversary = await foundry.utils.fromUuid(button.dataset.adversary);
|
||||
adversary.sheet.render(true);
|
||||
}
|
||||
|
||||
static async #deleteAdversary(event, target) {
|
||||
const adversaryKey = target.dataset.adversary;
|
||||
const path = `system.potentialAdversaries.${target.dataset.potentialAdversary}.adversaries`;
|
||||
const newAdversaries = foundry.utils.getProperty(this.actor, path).filter(x => x.uuid !== adversaryKey);
|
||||
await this.actor.update({ [path]: newAdversaries });
|
||||
this.render();
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = TextEditor.getDragEventData(event);
|
||||
const item = await fromUuid(data.uuid);
|
||||
if (item.type === 'adversary') {
|
||||
const target = event.target.closest('.category-container');
|
||||
const path = `system.potentialAdversaries.${target.dataset.potentialAdversary}.adversaries`;
|
||||
const current = foundry.utils.getProperty(this.actor, path).map(x => x.uuid);
|
||||
await this.actor.update({
|
||||
[path]: [...current, item.uuid]
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
static async updateForm(event, _, formData) {
|
||||
await this.actor.update(formData.object);
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ export default function DhpApplicationMixin(Base) {
|
|||
// drop: this._canDragDrop.bind(this)
|
||||
// };
|
||||
d.callbacks = {
|
||||
// dragstart: this._onDragStart.bind(this),
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
// dragover: this._onDragOver.bind(this),
|
||||
drop: this._onDrop.bind(this)
|
||||
};
|
||||
|
|
@ -68,6 +68,7 @@ export default function DhpApplicationMixin(Base) {
|
|||
});
|
||||
}
|
||||
|
||||
async _onDragStart(event) {}
|
||||
_onDrop(event) {}
|
||||
|
||||
_getTabs(tabs) {
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
import DaggerheartSheet from './daggerheart-sheet.mjs';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'sheet', 'actor', 'dh-style', 'environment'],
|
||||
position: {
|
||||
width: 450,
|
||||
height: 1000
|
||||
},
|
||||
actions: {
|
||||
addAdversary: this.addAdversary,
|
||||
addFeature: this.addFeature,
|
||||
deleteProperty: this.deleteProperty,
|
||||
viewAdversary: this.viewAdversary
|
||||
},
|
||||
form: {
|
||||
handler: this._updateForm,
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false
|
||||
},
|
||||
dragDrop: [{ dragSelector: null, dropSelector: '.adversary-container' }]
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
header: { template: 'systems/daggerheart/templates/sheets/actors/environment/header.hbs' },
|
||||
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
|
||||
main: { template: 'systems/daggerheart/templates/sheets/actors/environment/main.hbs' },
|
||||
information: { template: 'systems/daggerheart/templates/sheets/actors/environment/information.hbs' }
|
||||
};
|
||||
|
||||
static TABS = {
|
||||
main: {
|
||||
active: true,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'main',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Sheets.Environment.Tabs.Main'
|
||||
},
|
||||
information: {
|
||||
active: false,
|
||||
cssClass: '',
|
||||
group: 'primary',
|
||||
id: 'information',
|
||||
icon: null,
|
||||
label: 'DAGGERHEART.Sheets.Environment.Tabs.Information'
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.document = this.document;
|
||||
context.tabs = super._getTabs(this.constructor.TABS);
|
||||
context.getEffectDetails = this.getEffectDetails.bind(this);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static async _updateForm(event, _, formData) {
|
||||
await this.document.update(formData.object);
|
||||
this.render();
|
||||
}
|
||||
|
||||
getEffectDetails(id) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static async addAdversary() {
|
||||
await this.document.update({
|
||||
[`system.potentialAdversaries.${foundry.utils.randomID()}.label`]: game.i18n.localize(
|
||||
'DAGGERHEART.Sheets.Environment.newAdversary'
|
||||
)
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async addFeature() {
|
||||
ui.notifications.error('Not Implemented yet. Awaiting datamodel rework');
|
||||
}
|
||||
|
||||
static async deleteProperty(_, target) {
|
||||
await this.document.update({ [`${target.dataset.path}.-=${target.id}`]: null });
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async viewAdversary(_, button) {
|
||||
const adversary = foundry.utils.getProperty(
|
||||
this.document.system.potentialAdversaries,
|
||||
`${button.dataset.potentialAdversary}.adversaries.${button.dataset.adversary}`
|
||||
);
|
||||
adversary.sheet.render(true);
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = TextEditor.getDragEventData(event);
|
||||
const item = await fromUuid(data.uuid);
|
||||
if (item.type === 'adversary') {
|
||||
const target = event.target.closest('.adversary-container');
|
||||
const path = `system.potentialAdversaries.${target.dataset.potentialAdversary}.adversaries.${item.id}`;
|
||||
await this.document.update({
|
||||
[path]: item.uuid
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
16
module/applications/tooltipManager.mjs
Normal file
16
module/applications/tooltipManager.mjs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
export default class DhTooltipManager extends TooltipManager {
|
||||
async activate(element, options = {}) {
|
||||
let html = options.html;
|
||||
if (element.dataset.tooltip.startsWith('#item#')) {
|
||||
const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6));
|
||||
if (item) {
|
||||
html = await foundry.applications.handlebars.renderTemplate(
|
||||
`systems/daggerheart/templates/tooltip/${item.type}.hbs`,
|
||||
item
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
super.activate(element, { ...options, html: html });
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +1,42 @@
|
|||
export const actionTypes = {
|
||||
attack: {
|
||||
id: 'attack',
|
||||
name: 'DAGGERHEART.Actions.Types.Attack.Name',
|
||||
name: 'DAGGERHEART.Actions.Types.attack.name',
|
||||
icon: 'fa-swords'
|
||||
},
|
||||
// spellcast: {
|
||||
// id: 'spellcast',
|
||||
// name: 'DAGGERHEART.Actions.Types.Spellcast.Name',
|
||||
// name: 'DAGGERHEART.Actions.Types.spellcast.name',
|
||||
// icon: 'fa-book-sparkles'
|
||||
// },
|
||||
healing: {
|
||||
id: 'healing',
|
||||
name: 'DAGGERHEART.Actions.Types.Healing.Name',
|
||||
name: 'DAGGERHEART.Actions.Types.healing.name',
|
||||
icon: 'fa-kit-medical'
|
||||
},
|
||||
// resource: {
|
||||
// id: 'resource',
|
||||
// name: 'DAGGERHEART.Actions.Types.Resource.Name',
|
||||
// name: 'DAGGERHEART.Actions.Types.resource.name',
|
||||
// icon: 'fa-honey-pot'
|
||||
// },
|
||||
damage: {
|
||||
id: 'damage',
|
||||
name: 'DAGGERHEART.Actions.Types.Damage.Name',
|
||||
name: 'DAGGERHEART.Actions.Types.damage.name',
|
||||
icon: 'fa-bone-break'
|
||||
},
|
||||
summon: {
|
||||
id: 'summon',
|
||||
name: 'DAGGERHEART.Actions.Types.Summon.Name',
|
||||
name: 'DAGGERHEART.Actions.Types.summon.name',
|
||||
icon: 'fa-ghost'
|
||||
},
|
||||
effect: {
|
||||
id: 'effect',
|
||||
name: 'DAGGERHEART.Actions.Types.Effect.Name',
|
||||
name: 'DAGGERHEART.Actions.Types.effect.name',
|
||||
icon: 'fa-person-rays'
|
||||
},
|
||||
macro: {
|
||||
id: 'macro',
|
||||
name: 'DAGGERHEART.Actions.Types.Macro.Name',
|
||||
name: 'DAGGERHEART.Actions.Types.macro.name',
|
||||
icon: 'fa-scroll'
|
||||
}
|
||||
};
|
||||
|
|
@ -105,3 +105,18 @@ export const diceCompare = {
|
|||
operator: '>'
|
||||
}
|
||||
};
|
||||
|
||||
export const advandtageState = {
|
||||
disadvantage: {
|
||||
label: 'DAGGERHEART.General.Disadvantage.Full',
|
||||
value: -1
|
||||
},
|
||||
neutral: {
|
||||
label: 'DAGGERHEART.General.Neutral.Full',
|
||||
value: 0
|
||||
},
|
||||
advantage: {
|
||||
label: 'DAGGERHEART.General.Advantage.Full',
|
||||
value: 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,72 +83,72 @@ export const featureProperties = {
|
|||
export const adversaryTypes = {
|
||||
bruiser: {
|
||||
id: 'bruiser',
|
||||
label: 'DAGGERHEART.Adversary.Type.Bruiser.label',
|
||||
description: 'DAGGERHEART.Adversary.Bruiser.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.bruiser.label',
|
||||
description: 'DAGGERHEART.Adversary.bruiser.description'
|
||||
},
|
||||
horde: {
|
||||
id: 'horde',
|
||||
label: 'DAGGERHEART.Adversary.Type.Horde.label',
|
||||
description: 'DAGGERHEART.Adversary.Horde.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.horde.label',
|
||||
description: 'DAGGERHEART.Adversary.horde.description'
|
||||
},
|
||||
leader: {
|
||||
id: 'leader',
|
||||
label: 'DAGGERHEART.Adversary.Type.Leader.label',
|
||||
description: 'DAGGERHEART.Adversary.Leader.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.leader.label',
|
||||
description: 'DAGGERHEART.Adversary.leader.description'
|
||||
},
|
||||
minion: {
|
||||
id: 'minion',
|
||||
label: 'DAGGERHEART.Adversary.Type.Minion.label',
|
||||
description: 'DAGGERHEART.Adversary.Minion.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.minion.label',
|
||||
description: 'DAGGERHEART.Adversary.minion.description'
|
||||
},
|
||||
ranged: {
|
||||
id: 'ranged',
|
||||
label: 'DAGGERHEART.Adversary.Type.Ranged.label',
|
||||
description: 'DAGGERHEART.Adversary.Ranged.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.ranged.label',
|
||||
description: 'DAGGERHEART.Adversary.ranged.description'
|
||||
},
|
||||
skulk: {
|
||||
id: 'skulk',
|
||||
label: 'DAGGERHEART.Adversary.Type.Skulk.label',
|
||||
description: 'DAGGERHEART.Adversary.Skulk.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.skulk.label',
|
||||
description: 'DAGGERHEART.Adversary.skulk.description'
|
||||
},
|
||||
social: {
|
||||
id: 'social',
|
||||
label: 'DAGGERHEART.Adversary.Type.Social.label',
|
||||
description: 'DAGGERHEART.Adversary.Social.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.social.label',
|
||||
description: 'DAGGERHEART.Adversary.social.description'
|
||||
},
|
||||
solo: {
|
||||
id: 'solo',
|
||||
label: 'DAGGERHEART.Adversary.Type.Solo.label',
|
||||
description: 'DAGGERHEART.Adversary.Solo.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.solo.label',
|
||||
description: 'DAGGERHEART.Adversary.solo.description'
|
||||
},
|
||||
standard: {
|
||||
id: 'standard',
|
||||
label: 'DAGGERHEART.Adversary.Type.Standard.label',
|
||||
description: 'DAGGERHEART.Adversary.Standard.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.standard.label',
|
||||
description: 'DAGGERHEART.Adversary.standard.description'
|
||||
},
|
||||
support: {
|
||||
id: 'support',
|
||||
label: 'DAGGERHEART.Adversary.Type.Support.label',
|
||||
description: 'DAGGERHEART.Adversary.Support.Description'
|
||||
label: 'DAGGERHEART.Adversary.Type.support.label',
|
||||
description: 'DAGGERHEART.Adversary.support.description'
|
||||
}
|
||||
};
|
||||
|
||||
export const environmentTypes = {
|
||||
exploration: {
|
||||
label: 'DAGGERHEART.Environment.Type.Exploration.label',
|
||||
description: 'DAGGERHEART.Environment.Type.Exploration.description'
|
||||
label: 'DAGGERHEART.Environment.Type.exploration.label',
|
||||
description: 'DAGGERHEART.Environment.Type.exploration.description'
|
||||
},
|
||||
social: {
|
||||
label: 'DAGGERHEART.Environment.Type.Social.label',
|
||||
description: 'DAGGERHEART.Environment.Type.Social.description'
|
||||
label: 'DAGGERHEART.Environment.Type.social.label',
|
||||
description: 'DAGGERHEART.Environment.Type.social.description'
|
||||
},
|
||||
traversal: {
|
||||
label: 'DAGGERHEART.Environment.Type.Traversal.label',
|
||||
description: 'DAGGERHEART.Environment.Type.Traversal.description'
|
||||
label: 'DAGGERHEART.Environment.Type.traversal.label',
|
||||
description: 'DAGGERHEART.Environment.Type.traversal.description'
|
||||
},
|
||||
event: {
|
||||
label: 'DAGGERHEART.Environment.Type.Event.label',
|
||||
description: 'DAGGERHEART.Environment.Type.Event.description'
|
||||
label: 'DAGGERHEART.Environment.Type.event.label',
|
||||
description: 'DAGGERHEART.Environment.Type.event.description'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -712,14 +712,14 @@ export const valueTypes = {
|
|||
export const actionTypes = {
|
||||
passive: {
|
||||
id: 'passive',
|
||||
label: 'DAGGERHEART.ActionType.Passive'
|
||||
label: 'DAGGERHEART.ActionType.passive'
|
||||
},
|
||||
action: {
|
||||
id: 'action',
|
||||
label: 'DAGGERHEART.ActionType.Action'
|
||||
label: 'DAGGERHEART.ActionType.action'
|
||||
},
|
||||
reaction: {
|
||||
id: 'reaction',
|
||||
label: 'DAGGERHEART.ActionType.Reaction'
|
||||
label: 'DAGGERHEART.ActionType.reaction'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import CostSelectionDialog from '../../applications/costSelectionDialog.mjs';
|
||||
import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
||||
import DhpActor from '../../documents/actor.mjs';
|
||||
import D20RollDialog from '../../dialogs/d20RollDialog.mjs';
|
||||
|
|
@ -343,7 +342,9 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
label: 'Attack',
|
||||
type: this.actionType,
|
||||
difficulty: this.roll?.difficulty,
|
||||
formula: this.roll.getFormula()
|
||||
formula: this.roll.getFormula(),
|
||||
bonus: this.roll.bonus,
|
||||
advantage: SYSTEM.ACTIONS.advandtageState[this.roll.advState].value
|
||||
};
|
||||
if (this.roll?.type === 'diceSet') roll.lite = true;
|
||||
|
||||
|
|
@ -372,7 +373,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
|
||||
/* ROLL */
|
||||
get hasRoll() {
|
||||
return !!this.roll?.type;
|
||||
return !!this.roll?.type || !!this.roll?.bonus;
|
||||
}
|
||||
/* ROLL */
|
||||
|
||||
|
|
@ -544,6 +545,29 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
}
|
||||
/* SAVE */
|
||||
|
||||
async toChat(origin) {
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const systemData = {
|
||||
title: game.i18n.localize('DAGGERHEART.ActionType.action'),
|
||||
origin: origin,
|
||||
img: this.img,
|
||||
name: this.name,
|
||||
description: this.description,
|
||||
actions: []
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
user: game.user.id,
|
||||
system: systemData,
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/chat/ability-use.hbs',
|
||||
systemData
|
||||
)
|
||||
});
|
||||
|
||||
cls.create(msg.toObject());
|
||||
}
|
||||
}
|
||||
|
||||
export class DHDamageAction extends DHBaseAction {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ export class DHActionRollData extends foundry.abstract.DataModel {
|
|||
type: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.GENERAL.rollTypes }),
|
||||
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
||||
difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }),
|
||||
bonus: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }),
|
||||
bonus: new fields.NumberField({ nullable: true, initial: null, integer: true }),
|
||||
advState: new fields.StringField({ choices: SYSTEM.ACTIONS.advandtageState, initial: 'neutral' }),
|
||||
diceRolling: new fields.SchemaField({
|
||||
multiplier: new fields.StringField({
|
||||
choices: SYSTEM.GENERAL.diceSetNumbers,
|
||||
|
|
@ -62,7 +63,7 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
|||
label: 'Multiplier'
|
||||
}),
|
||||
flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
||||
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Formula' }),
|
||||
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Dice' }),
|
||||
bonus: new fields.NumberField({ nullable: true, initial: null, label: 'Bonus' }),
|
||||
custom: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({ label: 'Custom Formula' }),
|
||||
|
|
|
|||
|
|
@ -30,8 +30,11 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
choices: SYSTEM.ACTOR.adversaryTypes,
|
||||
initial: SYSTEM.ACTOR.adversaryTypes.standard.id
|
||||
}),
|
||||
motivesAndTactics: new fields.HTMLField(),
|
||||
description: new fields.StringField(),
|
||||
motivesAndTactics: new fields.StringField(),
|
||||
notes: new fields.HTMLField(),
|
||||
difficulty: new fields.NumberField({ required: true, initial: 1, integer: true }),
|
||||
hordeHp: new fields.NumberField({ required: true, initial: 1, integer: true }),
|
||||
damageThresholds: new fields.SchemaField({
|
||||
major: new fields.NumberField({ required: true, initial: 0, integer: true }),
|
||||
severe: new fields.NumberField({ required: true, initial: 0, integer: true })
|
||||
|
|
@ -40,6 +43,7 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
hitPoints: resourceField(),
|
||||
stress: resourceField()
|
||||
}),
|
||||
actions: new fields.ArrayField(new ActionField()),
|
||||
attack: new ActionField({
|
||||
initial: {
|
||||
name: 'Attack',
|
||||
|
|
@ -66,7 +70,7 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
experiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
name: new fields.StringField(),
|
||||
value: new fields.NumberField({ required: true, integer: true, initial: 1 })
|
||||
modifier: new fields.NumberField({ required: true, integer: true, initial: 1 })
|
||||
})
|
||||
),
|
||||
bonuses: new fields.SchemaField({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { environmentTypes } from '../../config/actorConfig.mjs';
|
||||
import BaseDataActor from './base.mjs';
|
||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||
import ActionField from '../fields/actionField.mjs';
|
||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
|
||||
export default class DhEnvironment extends BaseDataActor {
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.Sheets.Environment'];
|
||||
|
|
@ -21,15 +23,17 @@ export default class DhEnvironment extends BaseDataActor {
|
|||
initial: SYSTEM.GENERAL.tiers.tier1.id
|
||||
}),
|
||||
type: new fields.StringField({ choices: environmentTypes }),
|
||||
impulses: new fields.HTMLField(),
|
||||
description: new fields.StringField(),
|
||||
impulses: new fields.StringField(),
|
||||
difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }),
|
||||
potentialAdversaries: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
label: new fields.StringField(),
|
||||
adversaries: new fields.TypedObjectField(new ForeignDocumentUUIDField({ type: 'Actor' }))
|
||||
adversaries: new ForeignDocumentUUIDArrayField({ type: 'Actor' })
|
||||
})
|
||||
)
|
||||
/* Features pending datamodel rework */
|
||||
),
|
||||
actions: new fields.ArrayField(new ActionField()),
|
||||
notes: new fields.HTMLField()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { actionsTypes } from '../action/_module.mjs';
|
||||
// import { actionsTypes } from '../action/_module.mjs';
|
||||
|
||||
// Temporary Solution
|
||||
export default class ActionField extends foundry.data.fields.ObjectField {
|
||||
getModel(value) {
|
||||
return actionsTypes[value.type] ?? actionsTypes.attack;
|
||||
return game.system.api.models.actionsTypes[value.type] ?? game.system.api.models.actionsTypes.attack;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { actionsTypes } from '../action/_module.mjs';
|
||||
// import { actionsTypes } from '../action/_module.mjs';
|
||||
|
||||
/**
|
||||
* Describes metadata about the item data model type
|
||||
|
|
@ -60,7 +60,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
const actionType = {
|
||||
weapon: 'attack'
|
||||
}[this.constructor.metadata.type],
|
||||
cls = actionsTypes.attack,
|
||||
cls = game.system.api.models.actionsTypes[actionType],
|
||||
// cls = actionsTypes.attack,
|
||||
action = new cls(
|
||||
{
|
||||
_id: foundry.utils.randomID(),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
this.config.experiences = [];
|
||||
|
||||
if (config.source?.action) {
|
||||
this.item = config.data.parent.items.get(config.source.item);
|
||||
console.log(config)
|
||||
this.item = config.data.parent.items.get(config.source.item) ?? config.data.parent;
|
||||
this.action =
|
||||
config.data.attack?._id == config.source.action
|
||||
? config.data.attack
|
||||
|
|
@ -50,15 +51,18 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
console.log(this.config, this.roll)
|
||||
const context = await super._prepareContext(_options);
|
||||
context.hasRoll = !!this.config.roll;
|
||||
context.roll = this.roll;
|
||||
context.rollType = this.roll?.constructor.name;
|
||||
context.experiences = Object.keys(this.config.data.experiences).map(id => ({
|
||||
id,
|
||||
...this.config.data.experiences[id]
|
||||
}));
|
||||
context.selectedExperiences = this.config.experiences;
|
||||
context.advantage = this.config.advantage;
|
||||
/* context.diceOptions = this.diceOptions; */
|
||||
context.advantage = this.config.roll?.advantage;
|
||||
context.diceOptions = SYSTEM.GENERAL.diceTypes;
|
||||
context.canRoll = true;
|
||||
context.isLite = this.config.roll?.lite;
|
||||
if (this.config.costs?.length) {
|
||||
|
|
@ -71,7 +75,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
context.uses = this.action.calcUses(this.config.uses);
|
||||
context.canRoll = context.canRoll && this.action.hasUses(context.uses);
|
||||
}
|
||||
context.extraFormula = this.config.extraFormula;
|
||||
context.formula = this.roll.constructFormula(this.config);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
@ -81,12 +87,18 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
this.config.costs = foundry.utils.mergeObject(this.config.costs, rest.costs);
|
||||
}
|
||||
if (this.config.uses) this.config.uses = foundry.utils.mergeObject(this.config.uses, rest.uses);
|
||||
if(rest.roll?.dice) {
|
||||
Object.entries(rest.roll.dice).forEach(([key, value]) => {
|
||||
this.roll[key] = value;
|
||||
})
|
||||
}
|
||||
this.config.extraFormula = rest.extraFormula;
|
||||
this.render();
|
||||
}
|
||||
|
||||
static updateIsAdvantage(_, button) {
|
||||
const advantage = Number(button.dataset.advantage);
|
||||
this.config.advantage = this.config.advantage === advantage ? 0 : advantage;
|
||||
this.config.roll.advantage = this.config.roll.advantage === advantage ? 0 : advantage;
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,17 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application
|
|||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.title = this.config.title;
|
||||
context.formula = this.config.roll.formula;
|
||||
context.extraFormula = this.config.extraFormula;
|
||||
context.formula = this.roll.constructFormula(this.config);;
|
||||
return context;
|
||||
}
|
||||
|
||||
static updateRollConfiguration(event, _, formData) {
|
||||
const { ...rest } = foundry.utils.expandObject(formData.object);
|
||||
this.config.extraFormula = rest.extraFormula;
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async submitRoll() {
|
||||
await this.close({ submitted: true });
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue