mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 19:51:08 +01:00
merged with main
This commit is contained in:
commit
0aa08deaa3
41 changed files with 805 additions and 446 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import CostSelectionDialog from '../../applications/costSelectionDialog.mjs';
|
||||
import { DHActionDiceData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
||||
import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
||||
import DhpActor from '../../documents/actor.mjs';
|
||||
import D20RollDialog from '../../dialogs/d20RollDialog.mjs';
|
||||
|
||||
|
|
@ -69,16 +69,14 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
static defineExtraSchema() {
|
||||
const extraFields = {
|
||||
damage: new DHDamageField(),
|
||||
roll: new fields.SchemaField({
|
||||
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 })
|
||||
}),
|
||||
roll: new fields.EmbeddedDataField(DHActionRollData),
|
||||
save: new fields.SchemaField({
|
||||
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
||||
difficulty: new fields.NumberField({ nullable: true, initial: 10, integer: true, min: 0 }),
|
||||
damageMod: new fields.StringField({ initial: SYSTEM.ACTIONS.damageOnSave.none.id, choices: SYSTEM.ACTIONS.damageOnSave })
|
||||
damageMod: new fields.StringField({
|
||||
initial: SYSTEM.ACTIONS.damageOnSave.none.id,
|
||||
choices: SYSTEM.ACTIONS.damageOnSave
|
||||
})
|
||||
}),
|
||||
target: new fields.SchemaField({
|
||||
type: new fields.StringField({
|
||||
|
|
@ -103,9 +101,12 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
initial: SYSTEM.GENERAL.healingTypes.hitPoints.id,
|
||||
label: 'Healing'
|
||||
}),
|
||||
resultBased: new fields.BooleanField({ initial: false, label: "DAGGERHEART.Actions.Settings.ResultBased.label" }),
|
||||
resultBased: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.Actions.Settings.ResultBased.label'
|
||||
}),
|
||||
value: new fields.EmbeddedDataField(DHActionDiceData),
|
||||
valueAlt: new fields.EmbeddedDataField(DHActionDiceData),
|
||||
valueAlt: new fields.EmbeddedDataField(DHActionDiceData)
|
||||
})
|
||||
},
|
||||
extraSchemas = {};
|
||||
|
|
@ -158,19 +159,23 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
return updateSource;
|
||||
}
|
||||
|
||||
getRollData() {
|
||||
getRollData(data = {}) {
|
||||
const actorData = this.actor.getRollData(false);
|
||||
|
||||
// Remove when included directly in Actor getRollData
|
||||
actorData.prof = actorData.proficiency?.value ?? 1,
|
||||
actorData.cast = actorData.spellcast?.value ?? 1,
|
||||
actorData.scale = this.cost.length
|
||||
? this.cost.reduce((a, c) => {
|
||||
actorData.prof = actorData.proficiency?.value ?? 1;
|
||||
actorData.cast = actorData.spellcast?.value ?? 1;
|
||||
actorData.result = data.roll?.total ?? 1;
|
||||
/* actorData.scale = data.costs?.length
|
||||
? data.costs.reduce((a, c) => {
|
||||
a[c.type] = c.value;
|
||||
return a;
|
||||
}, {})
|
||||
: 1,
|
||||
actorData.roll = {}
|
||||
: 1; */
|
||||
actorData.scale = data.costs?.length // Right now only return the first scalable cost.
|
||||
? (data.costs.find(c => c.scalable)?.total ?? 1)
|
||||
: 1;
|
||||
actorData.roll = {};
|
||||
|
||||
return actorData;
|
||||
}
|
||||
|
|
@ -192,12 +197,14 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
|
||||
// Prepare Costs
|
||||
const costsConfig = this.prepareCost();
|
||||
if(isFastForward && !this.hasCost(costsConfig)) return ui.notifications.warn("You don't have the resources to use that action.");
|
||||
if (isFastForward && !this.hasCost(costsConfig))
|
||||
return ui.notifications.warn("You don't have the resources to use that action.");
|
||||
// config = this.prepareUseCost(config)
|
||||
|
||||
// Prepare Uses
|
||||
const usesConfig = this.prepareUse();
|
||||
if(isFastForward && !this.hasUses(usesConfig)) return ui.notifications.warn("That action doesn't have remaining uses.");
|
||||
if (isFastForward && !this.hasUses(usesConfig))
|
||||
return ui.notifications.warn("That action doesn't have remaining uses.");
|
||||
// config = this.prepareUseCost(config)
|
||||
|
||||
// Prepare Roll Data
|
||||
|
|
@ -210,24 +217,24 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
costs: costsConfig,
|
||||
uses: usesConfig,
|
||||
data: actorData
|
||||
}
|
||||
|
||||
if ( Hooks.call(`${SYSTEM.id}.preUseAction`, this, config) === false ) return;
|
||||
};
|
||||
|
||||
if (Hooks.call(`${SYSTEM.id}.preUseAction`, this, config) === false) return;
|
||||
|
||||
// Display configuration window if necessary
|
||||
if ( config.dialog.configure && this.requireConfigurationDialog(config) ) {
|
||||
if (config.dialog?.configure && this.requireConfigurationDialog(config)) {
|
||||
config = await D20RollDialog.configure(config);
|
||||
if (!config) return;
|
||||
}
|
||||
|
||||
if ( this.hasRoll ) {
|
||||
if (this.hasRoll) {
|
||||
const rollConfig = this.prepareRoll(config);
|
||||
config.roll = rollConfig;
|
||||
config = await this.actor.diceRoll(config);
|
||||
if (!config) return;
|
||||
}
|
||||
|
||||
if( this.hasSave ) {
|
||||
if (this.hasSave) {
|
||||
/* config.targets.forEach((t) => {
|
||||
if(t.hit) {
|
||||
const target = game.canvas.tokens.get(t.id),
|
||||
|
|
@ -259,16 +266,16 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}) */
|
||||
}
|
||||
|
||||
if ( this.doFollowUp() ) {
|
||||
if(this.rollDamage) await this.rollDamage(event, config);
|
||||
if(this.rollHealing) await this.rollHealing(event, config);
|
||||
if(this.trigger) await this.trigger(event, config);
|
||||
if (this.doFollowUp()) {
|
||||
if (this.rollDamage) await this.rollDamage(event, config);
|
||||
if (this.rollHealing) await this.rollHealing(event, config);
|
||||
if (this.trigger) await this.trigger(event, config);
|
||||
}
|
||||
|
||||
// Consume resources
|
||||
await this.consume(config);
|
||||
|
||||
if ( Hooks.call(`${SYSTEM.id}.postUseAction`, this, config) === false ) return;
|
||||
|
||||
if (Hooks.call(`${SYSTEM.id}.postUseAction`, this, config) === false) return;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
|
@ -281,21 +288,18 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
source: {
|
||||
item: this.item._id,
|
||||
action: this._id
|
||||
// action: this
|
||||
},
|
||||
dialog: {
|
||||
configure: true
|
||||
},
|
||||
dialog: {},
|
||||
type: this.type,
|
||||
hasDamage: !!this.damage?.parts?.length,
|
||||
hasHealing: !!this.healing,
|
||||
hasEffect: !!this.effects?.length,
|
||||
hasSave: this.hasSave
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
requireConfigurationDialog(config) {
|
||||
return !config.event.shiftkey && !this.hasRoll && (config.costs?.length || config.uses);
|
||||
return !config.event.shiftKey && !this.hasRoll && (config.costs?.length || config.uses);
|
||||
}
|
||||
|
||||
prepareCost() {
|
||||
|
|
@ -321,7 +325,6 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
targets = targets.map(t => this.formatTarget(t));
|
||||
return targets;
|
||||
|
||||
}
|
||||
|
||||
prepareRange() {
|
||||
|
|
@ -330,13 +333,16 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
prepareRoll() {
|
||||
const roll = {
|
||||
const roll = {
|
||||
modifiers: [],
|
||||
trait: this.roll?.trait,
|
||||
label: 'Attack',
|
||||
type: this.actionType,
|
||||
difficulty: this.roll?.difficulty
|
||||
difficulty: this.roll?.difficulty,
|
||||
formula: this.roll.getFormula()
|
||||
};
|
||||
if (this.roll?.type === 'diceSet') roll.lite = true;
|
||||
|
||||
return roll;
|
||||
}
|
||||
|
||||
|
|
@ -345,11 +351,14 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
async consume(config) {
|
||||
const resources = config.costs.filter(c => c.enabled !== false).map(c => {
|
||||
return { type: c.type, value: c.total * -1 };
|
||||
});
|
||||
const resources = config.costs
|
||||
.filter(c => c.enabled !== false)
|
||||
.map(c => {
|
||||
return { type: c.type, value: (c.total ?? c.value) * -1 };
|
||||
});
|
||||
|
||||
await this.actor.modifyResource(resources);
|
||||
if(config.uses?.enabled) {
|
||||
if (config.uses?.enabled) {
|
||||
const newActions = foundry.utils.getProperty(this.item.system, this.systemPath).map(x => x.toObject());
|
||||
newActions[this.index].uses.value++;
|
||||
await this.item.update({ [`system.${this.systemPath}`]: newActions });
|
||||
|
|
@ -388,13 +397,16 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
|
||||
hasCost(costs) {
|
||||
const realCosts = this.getRealCosts(costs);
|
||||
return realCosts.reduce((a, c) => a && this.actor.system.resources[c.type]?.value >= (c.total ?? c.value), true);
|
||||
return realCosts.reduce(
|
||||
(a, c) => a && this.actor.system.resources[c.type]?.value >= (c.total ?? c.value),
|
||||
true
|
||||
);
|
||||
}
|
||||
/* COST */
|
||||
|
||||
/* USES */
|
||||
calcUses(uses) {
|
||||
if(!uses) return null;
|
||||
if (!uses) return null;
|
||||
return {
|
||||
...uses,
|
||||
enabled: uses.hasOwnProperty('enabled') ? uses.enabled : true
|
||||
|
|
@ -402,7 +414,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
hasUses(uses) {
|
||||
if(!uses) return true;
|
||||
if (!uses) return true;
|
||||
return (uses.hasOwnProperty('enabled') && !uses.enabled) || uses.value + 1 <= uses.max;
|
||||
}
|
||||
/* USES */
|
||||
|
|
@ -432,7 +444,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
/* TARGET */
|
||||
|
||||
/* RANGE */
|
||||
|
||||
|
||||
/* RANGE */
|
||||
|
||||
/* EFFECTS */
|
||||
|
|
@ -441,10 +453,10 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
let effects = this.effects;
|
||||
data.system.targets.forEach(async token => {
|
||||
if (!token.hit && !force) return;
|
||||
if(this.hasSave && token.saved.success === true) {
|
||||
effects = this.effects.filter(e => e.onSave === true)
|
||||
if (this.hasSave && token.saved.success === true) {
|
||||
effects = this.effects.filter(e => e.onSave === true);
|
||||
}
|
||||
if(!effects.length) return;
|
||||
if (!effects.length) return;
|
||||
effects.forEach(async e => {
|
||||
const actor = canvas.tokens.get(token.id)?.actor,
|
||||
effect = this.item.effects.get(e._id);
|
||||
|
|
@ -479,35 +491,42 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
|
||||
/* SAVE */
|
||||
async rollSave(target, event, message) {
|
||||
if(!target?.actor) return;
|
||||
target.actor.diceRoll({
|
||||
event,
|
||||
title: 'Roll Save',
|
||||
roll: {
|
||||
trait: this.save.trait,
|
||||
difficulty: this.save.difficulty,
|
||||
type: "reaction"
|
||||
},
|
||||
data: target.actor.getRollData()
|
||||
}).then(async (result) => {
|
||||
this.updateChatMessage(message, target.id, {result: result.roll.total, success: result.roll.success});
|
||||
})
|
||||
if (!target?.actor) return;
|
||||
target.actor
|
||||
.diceRoll({
|
||||
event,
|
||||
title: 'Roll Save',
|
||||
roll: {
|
||||
trait: this.save.trait,
|
||||
difficulty: this.save.difficulty,
|
||||
type: 'reaction'
|
||||
},
|
||||
data: target.actor.getRollData()
|
||||
})
|
||||
.then(async result => {
|
||||
if (result)
|
||||
this.updateChatMessage(message, target.id, {
|
||||
result: result.roll.total,
|
||||
success: result.roll.success
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async updateChatMessage(message, targetId, changes, chain=true) {
|
||||
async updateChatMessage(message, targetId, changes, chain = true) {
|
||||
setTimeout(async () => {
|
||||
const chatMessage = ui.chat.collection.get(message._id),
|
||||
msgTargets = chatMessage.system.targets,
|
||||
msgTarget = msgTargets.find(mt => mt.id === targetId);
|
||||
msgTarget.saved = changes;
|
||||
await chatMessage.update({'system.targets': msgTargets});
|
||||
},100);
|
||||
if(chain) {
|
||||
if(message.system.source.message) this.updateChatMessage(ui.chat.collection.get(message.system.source.message), targetId, changes, false);
|
||||
await chatMessage.update({ 'system.targets': msgTargets });
|
||||
}, 100);
|
||||
if (chain) {
|
||||
if (message.system.source.message)
|
||||
this.updateChatMessage(ui.chat.collection.get(message.system.source.message), targetId, changes, false);
|
||||
const relatedChatMessages = ui.chat.collection.filter(c => c.system.source.message === message._id);
|
||||
relatedChatMessages.forEach(c => {
|
||||
this.updateChatMessage(c, targetId, changes, false);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
/* SAVE */
|
||||
|
|
@ -525,7 +544,7 @@ export class DHDamageAction extends DHBaseAction {
|
|||
|
||||
getFormulaValue(part, data) {
|
||||
let formulaValue = part.value;
|
||||
if(this.hasRoll && part.resultBased && data.system.roll.result.duality === -1) return part.valueAlt;
|
||||
if (this.hasRoll && part.resultBased && data.system.roll.result.duality === -1) return part.valueAlt;
|
||||
return formulaValue;
|
||||
}
|
||||
|
||||
|
|
@ -535,16 +554,19 @@ export class DHDamageAction extends DHBaseAction {
|
|||
if (!formula || formula == '') return;
|
||||
let roll = { formula: formula, total: formula },
|
||||
bonusDamage = [];
|
||||
|
||||
|
||||
if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(data.system ?? data));
|
||||
|
||||
const config = {
|
||||
title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: this.name }),
|
||||
formula,
|
||||
targets: (data.system?.targets.filter(t => t.hit) ?? data.targets),
|
||||
roll: { formula },
|
||||
targets: data.system?.targets.filter(t => t.hit) ?? data.targets,
|
||||
hasSave: this.hasSave,
|
||||
source: data.system?.source
|
||||
source: data.system?.source,
|
||||
event
|
||||
};
|
||||
if(this.hasSave) config.onSave = this.save.damageMod;
|
||||
if(data.system) {
|
||||
if (this.hasSave) config.onSave = this.save.damageMod;
|
||||
if (data.system) {
|
||||
config.source.message = data._id;
|
||||
config.directDamage = false;
|
||||
}
|
||||
|
|
@ -575,7 +597,7 @@ export class DHAttackAction extends DHDamageAction {
|
|||
getParentDamage() {
|
||||
return {
|
||||
value: {
|
||||
multiplier: 'proficiency',
|
||||
multiplier: 'prof',
|
||||
dice: this.item?.system?.damage.value,
|
||||
bonus: this.item?.system?.damage.bonus ?? 0
|
||||
},
|
||||
|
|
@ -594,7 +616,8 @@ export class DHHealingAction extends DHBaseAction {
|
|||
|
||||
getFormulaValue(data) {
|
||||
let formulaValue = this.healing.value;
|
||||
if(this.hasRoll && this.healing.resultBased && data.system.roll.result.duality === -1) return this.healing.valueAlt;
|
||||
if (this.hasRoll && this.healing.resultBased && data.system.roll.result.duality === -1)
|
||||
return this.healing.valueAlt;
|
||||
return formulaValue;
|
||||
}
|
||||
|
||||
|
|
@ -605,15 +628,16 @@ export class DHHealingAction extends DHBaseAction {
|
|||
if (!formula || formula == '') return;
|
||||
let roll = { formula: formula, total: formula },
|
||||
bonusDamage = [];
|
||||
|
||||
|
||||
const config = {
|
||||
title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', {
|
||||
healing: game.i18n.localize(SYSTEM.GENERAL.healingTypes[this.healing.type].label)
|
||||
}),
|
||||
formula,
|
||||
roll: { formula },
|
||||
targets: (data.system?.targets ?? data.targets).filter(t => t.hit),
|
||||
messageType: 'healing',
|
||||
type: this.healing.type
|
||||
type: this.healing.type,
|
||||
event
|
||||
};
|
||||
|
||||
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
|
||||
|
|
|
|||
|
|
@ -2,13 +2,63 @@ import FormulaField from '../fields/formulaField.mjs';
|
|||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
/* Roll Field */
|
||||
|
||||
export class DHActionRollData extends foundry.abstract.DataModel {
|
||||
/** @override */
|
||||
static defineSchema() {
|
||||
return {
|
||||
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 }),
|
||||
diceRolling: new fields.SchemaField({
|
||||
multiplier: new fields.StringField({
|
||||
choices: SYSTEM.GENERAL.diceSetNumbers,
|
||||
initial: 'prof',
|
||||
label: 'Dice Number'
|
||||
}),
|
||||
flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
||||
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Dice Type' }),
|
||||
compare: new fields.StringField({
|
||||
choices: SYSTEM.ACTIONS.diceCompare,
|
||||
initial: 'above',
|
||||
label: 'Should be'
|
||||
}),
|
||||
treshold: new fields.NumberField({ initial: 1, integer: true, min: 1, label: 'Treshold' })
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
getFormula() {
|
||||
if (!this.type) return;
|
||||
let formula = '';
|
||||
switch (this.type) {
|
||||
case 'diceSet':
|
||||
const multiplier =
|
||||
this.diceRolling.multiplier === 'flat'
|
||||
? this.diceRolling.flatMultiplier
|
||||
: `@${this.diceRolling.multiplier}`;
|
||||
formula = `${multiplier}${this.diceRolling.dice}cs${SYSTEM.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`;
|
||||
break;
|
||||
default:
|
||||
// formula = `${(!!this.parent?.actor?.system?.attack ? `@attackBonus` : `@traits.${this.trait}.total`)}`;
|
||||
formula = '';
|
||||
break;
|
||||
}
|
||||
return formula;
|
||||
}
|
||||
}
|
||||
|
||||
/* Damage & Healing Field */
|
||||
|
||||
export class DHActionDiceData extends foundry.abstract.DataModel {
|
||||
/** @override */
|
||||
static defineSchema() {
|
||||
return {
|
||||
multiplier: new fields.StringField({
|
||||
choices: SYSTEM.GENERAL.multiplierTypes,
|
||||
initial: 'proficiency',
|
||||
initial: 'prof',
|
||||
label: 'Multiplier'
|
||||
}),
|
||||
flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
||||
|
|
@ -22,10 +72,13 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
getFormula(actor) {
|
||||
const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : actor.system[this.multiplier]?.total;
|
||||
/* const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : actor.system[this.multiplier]?.total;
|
||||
return this.custom.enabled
|
||||
? this.custom.formula
|
||||
: `${multiplier ?? 1}${this.dice}${this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : ''}`;
|
||||
: `${multiplier ?? 1}${this.dice}${this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : ''}`; */
|
||||
const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : `@${this.multiplier}`,
|
||||
bonus = this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : '';
|
||||
return this.custom.enabled ? this.custom.formula : `${multiplier ?? 1}${this.dice}${bonus}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,9 +106,12 @@ export class DHDamageData extends foundry.abstract.DataModel {
|
|||
nullable: false,
|
||||
required: true
|
||||
}),
|
||||
resultBased: new fields.BooleanField({ initial: false, label: "DAGGERHEART.Actions.Settings.ResultBased.label" }),
|
||||
resultBased: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.Actions.Settings.ResultBased.label'
|
||||
}),
|
||||
value: new fields.EmbeddedDataField(DHActionDiceData),
|
||||
valueAlt: new fields.EmbeddedDataField(DHActionDiceData),
|
||||
valueAlt: new fields.EmbeddedDataField(DHActionDiceData)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,4 +77,8 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
})
|
||||
};
|
||||
}
|
||||
|
||||
get attackBonus() {
|
||||
return this.attack.roll.bonus;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export default class DhCharacter extends BaseDataActor {
|
|||
}),
|
||||
experiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
description: new fields.StringField({}),
|
||||
name: new fields.StringField(),
|
||||
value: new fields.NumberField({ integer: true, initial: 0 }),
|
||||
bonus: new fields.NumberField({ integer: true, initial: 0 })
|
||||
})
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
})
|
||||
})
|
||||
),
|
||||
costs: new fields.ArrayField(new fields.ObjectField()),
|
||||
hasDamage: new fields.BooleanField({ initial: false }),
|
||||
hasHealing: new fields.BooleanField({ initial: false }),
|
||||
hasEffect: new fields.BooleanField({ initial: false }),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ export default class DHArmor extends BaseDataItem {
|
|||
label: 'TYPES.Item.armor',
|
||||
type: 'armor',
|
||||
hasDescription: true,
|
||||
isQuantifiable: true
|
||||
isQuantifiable: true,
|
||||
isInventoryItem: true
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { actionsTypes } from '../action/_module.mjs';
|
|||
* @property {string} type - The system type that this data model represents.
|
||||
* @property {boolean} hasDescription - Indicates whether items of this type have description field
|
||||
* @property {boolean} isQuantifiable - Indicates whether items of this type have quantity field
|
||||
* @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item
|
||||
*/
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
|
@ -18,7 +19,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
label: 'Base Item',
|
||||
type: 'base',
|
||||
hasDescription: false,
|
||||
isQuantifiable: false
|
||||
isQuantifiable: false,
|
||||
isInventoryItem: false
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -52,9 +54,9 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
const data = { ...actorRollData, item: { ...this } };
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
async _preCreate(data, options, user) {
|
||||
if(!this.constructor.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return;
|
||||
if (!this.constructor.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return;
|
||||
const actionType = {
|
||||
weapon: 'attack'
|
||||
}[this.constructor.metadata.type],
|
||||
|
|
@ -70,6 +72,6 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
parent: this.parent
|
||||
}
|
||||
);
|
||||
this.updateSource({actions: [action]});
|
||||
this.updateSource({ actions: [action] });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ export default class DHConsumable extends BaseDataItem {
|
|||
label: 'TYPES.Item.consumable',
|
||||
type: 'consumable',
|
||||
hasDescription: true,
|
||||
isQuantifiable: true
|
||||
isQuantifiable: true,
|
||||
isInventoryItem: true
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ export default class DHMiscellaneous extends BaseDataItem {
|
|||
label: 'TYPES.Item.miscellaneous',
|
||||
type: 'miscellaneous',
|
||||
hasDescription: true,
|
||||
isQuantifiable: true
|
||||
isQuantifiable: true,
|
||||
isInventoryItem: true
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import BaseDataItem from './base.mjs';
|
|||
import FormulaField from '../fields/formulaField.mjs';
|
||||
import ActionField from '../fields/actionField.mjs';
|
||||
import { weaponFeatures } from '../../config/itemConfig.mjs';
|
||||
import { actionsTypes } from '../action/_module.mjs';
|
||||
import { actionsTypes } from '../action/_module.mjs';
|
||||
|
||||
export default class DHWeapon extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -12,9 +12,7 @@ export default class DHWeapon extends BaseDataItem {
|
|||
type: 'weapon',
|
||||
hasDescription: true,
|
||||
isQuantifiable: true,
|
||||
embedded: {
|
||||
feature: 'featureTest'
|
||||
},
|
||||
isInventoryItem: true,
|
||||
hasInitialAction: true
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,38 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
|||
traitArray: new fields.ArrayField(new fields.NumberField({ required: true, integer: true }), {
|
||||
initial: () => [2, 1, 1, 0, 0, -1]
|
||||
}),
|
||||
currency: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.Settings.Homebrew.Currency.enabled'
|
||||
}),
|
||||
title: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Gold',
|
||||
label: 'DAGGERHEART.Settings.Homebrew.Currency.currencyName'
|
||||
}),
|
||||
coins: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Coins',
|
||||
label: 'DAGGERHEART.Settings.Homebrew.Currency.coinName'
|
||||
}),
|
||||
handfulls: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Handfulls',
|
||||
label: 'DAGGERHEART.Settings.Homebrew.Currency.handfullName'
|
||||
}),
|
||||
bags: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Bags',
|
||||
label: 'DAGGERHEART.Settings.Homebrew.Currency.bagName'
|
||||
}),
|
||||
chests: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Chests',
|
||||
label: 'DAGGERHEART.Settings.Homebrew.Currency.chestName'
|
||||
})
|
||||
}),
|
||||
restMoves: new fields.SchemaField({
|
||||
longRest: new fields.SchemaField({
|
||||
nrChoices: new fields.NumberField({ required: true, integer: true, min: 1, initial: 2 }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue