mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-19 00:19:03 +01:00
Merged with main
This commit is contained in:
commit
9b9632cf94
150 changed files with 1077 additions and 930 deletions
|
|
@ -34,8 +34,8 @@ export default class DHAttackAction extends DHDamageAction {
|
|||
};
|
||||
}
|
||||
|
||||
async use(event, ...args) {
|
||||
const result = await super.use(event, args);
|
||||
async use(event, options) {
|
||||
const result = await super.use(event, options);
|
||||
|
||||
const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns;
|
||||
await updateCountdowns(CONFIG.DH.GENERAL.countdownTypes.characterAttack.id);
|
||||
|
|
|
|||
|
|
@ -111,12 +111,13 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
return actorData;
|
||||
}
|
||||
|
||||
async use(event, ...args) {
|
||||
async use(event, options = {}) {
|
||||
if (!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
|
||||
|
||||
if (this.chatDisplay) await this.toChat();
|
||||
|
||||
let config = this.prepareConfig(event);
|
||||
let { byPassRoll } = options,
|
||||
config = this.prepareConfig(event, byPassRoll);
|
||||
for (let i = 0; i < this.constructor.extraSchemas.length; i++) {
|
||||
let clsField = this.constructor.getActionField(this.constructor.extraSchemas[i]);
|
||||
if (clsField?.prepareConfig) {
|
||||
|
|
@ -133,14 +134,14 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
if (!config) return;
|
||||
}
|
||||
|
||||
if (this.hasRoll) {
|
||||
if (config.hasRoll) {
|
||||
const rollConfig = this.prepareRoll(config);
|
||||
config.roll = rollConfig;
|
||||
config = await this.actor.diceRoll(config);
|
||||
if (!config) return;
|
||||
}
|
||||
|
||||
if (this.doFollowUp()) {
|
||||
if (this.doFollowUp(config)) {
|
||||
if (this.rollDamage && this.damage.parts.length) await this.rollDamage(event, config);
|
||||
else if (this.trigger) await this.trigger(event, config);
|
||||
else if (this.hasSave || this.hasEffect) {
|
||||
|
|
@ -160,7 +161,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
}
|
||||
|
||||
/* */
|
||||
prepareConfig(event) {
|
||||
prepareConfig(event, byPass = false) {
|
||||
const hasRoll = this.getUseHasRoll(byPass);
|
||||
return {
|
||||
event,
|
||||
title: `${this.item.name}: ${this.name}`,
|
||||
|
|
@ -170,10 +172,10 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
actor: this.actor.uuid
|
||||
},
|
||||
dialog: {
|
||||
configure: this.hasRoll
|
||||
configure: hasRoll
|
||||
},
|
||||
type: this.type,
|
||||
hasRoll: this.hasRoll,
|
||||
hasRoll: hasRoll,
|
||||
hasDamage: this.damage?.parts?.length && this.type !== 'healing',
|
||||
hasHealing: this.damage?.parts?.length && this.type === 'healing',
|
||||
hasEffect: !!this.effects?.length,
|
||||
|
|
@ -182,12 +184,12 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
selectedRollMode: game.settings.get('core', 'rollMode'),
|
||||
isFastForward: event.shiftKey,
|
||||
data: this.getRollData(),
|
||||
evaluate: this.hasRoll
|
||||
evaluate: hasRoll
|
||||
};
|
||||
}
|
||||
|
||||
requireConfigurationDialog(config) {
|
||||
return !config.event.shiftKey && !this.hasRoll && (config.costs?.length || config.uses);
|
||||
return !config.event.shiftKey && !config.hasRoll && (config.costs?.length || config.uses);
|
||||
}
|
||||
|
||||
prepareRoll() {
|
||||
|
|
@ -205,7 +207,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
}
|
||||
|
||||
doFollowUp(config) {
|
||||
return !this.hasRoll;
|
||||
return !config.hasRoll;
|
||||
}
|
||||
|
||||
async consume(config, successCost = false) {
|
||||
|
|
@ -220,16 +222,13 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const resources = config.costs
|
||||
.filter(c =>
|
||||
c.enabled !== false
|
||||
&&
|
||||
(
|
||||
(!successCost && (!c.consumeOnSuccess || config.roll?.success))
|
||||
||
|
||||
(successCost && c.consumeOnSuccess)
|
||||
)
|
||||
.filter(
|
||||
c =>
|
||||
c.enabled !== false &&
|
||||
((!successCost && (!c.consumeOnSuccess || config.roll?.success)) ||
|
||||
(successCost && c.consumeOnSuccess))
|
||||
)
|
||||
.map(c => {
|
||||
const resource = usefulResources[c.key];
|
||||
|
|
@ -242,21 +241,23 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
});
|
||||
|
||||
await this.actor.modifyResource(resources);
|
||||
if (config.uses?.enabled
|
||||
&&
|
||||
(
|
||||
(!successCost && (!config.uses?.consumeOnSuccess || config.roll?.success))
|
||||
||
|
||||
(successCost && config.uses?.consumeOnSuccess)
|
||||
)
|
||||
) this.update({ 'uses.value': this.uses.value + 1 });
|
||||
if (
|
||||
config.uses?.enabled &&
|
||||
((!successCost && (!config.uses?.consumeOnSuccess || config.roll?.success)) ||
|
||||
(successCost && config.uses?.consumeOnSuccess))
|
||||
)
|
||||
this.update({ 'uses.value': this.uses.value + 1 });
|
||||
|
||||
if(config.roll?.success || successCost)
|
||||
(config.message ?? config.parent).update({'system.successConsumed': true})
|
||||
if (config.roll?.success || successCost)
|
||||
(config.message ?? config.parent).update({ 'system.successConsumed': true });
|
||||
}
|
||||
/* */
|
||||
|
||||
/* ROLL */
|
||||
getUseHasRoll(byPass = false) {
|
||||
return this.hasRoll && !byPass;
|
||||
}
|
||||
|
||||
get hasRoll() {
|
||||
return !!this.roll?.type;
|
||||
}
|
||||
|
|
@ -301,11 +302,9 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
}
|
||||
|
||||
async applyEffect(effect, actor) {
|
||||
const origin = effect.parent?.parent ? effect.parent.parent.uuid : effect.parent.uuid;
|
||||
// Enable an existing effect on the target if it originated from this effect
|
||||
const existingEffect = actor.effects.find(e => e.origin === origin);
|
||||
const existingEffect = actor.effects.find(e => e.origin === effect.uuid);
|
||||
if (existingEffect) {
|
||||
return existingEffect.update(
|
||||
return effect.update(
|
||||
foundry.utils.mergeObject({
|
||||
...effect.constructor.getInitialDuration(),
|
||||
disabled: false
|
||||
|
|
@ -318,7 +317,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
...effect.toObject(),
|
||||
disabled: false,
|
||||
transfer: false,
|
||||
origin: origin
|
||||
origin: effect.uuid
|
||||
});
|
||||
await ActiveEffect.implementation.create(effectData, { parent: actor });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import DHBaseAction from './baseAction.mjs';
|
|||
export default class DhBeastformAction extends DHBaseAction {
|
||||
static extraSchemas = [...super.extraSchemas, 'beastform'];
|
||||
|
||||
async use(event, ...args) {
|
||||
async use(event, options) {
|
||||
const beastformConfig = this.prepareBeastformConfig();
|
||||
|
||||
const abort = await this.handleActiveTransformations();
|
||||
|
|
@ -20,7 +20,7 @@ export default class DhBeastformAction extends DHBaseAction {
|
|||
const { selected, evolved, hybrid } = await BeastformDialog.configure(beastformConfig, this.item);
|
||||
if (!selected) return;
|
||||
|
||||
const result = await super.use(event, args);
|
||||
const result = await super.use(event, options);
|
||||
if (!result) return;
|
||||
|
||||
await this.transform(selected, evolved, hybrid);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export default 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 (data.hasRoll && part.resultBased && data.system.roll.result.duality === -1) return part.valueAlt;
|
||||
|
||||
const isAdversary = this.actor.type === 'adversary';
|
||||
if (isAdversary && this.actor.system.type === CONFIG.DH.ACTOR.adversaryTypes.horde.id) {
|
||||
|
|
@ -51,7 +51,7 @@ export default class DHDamageAction extends DHBaseAction {
|
|||
dialog: {},
|
||||
data: this.getRollData(),
|
||||
targetSelection: systemData.targets.length > 0
|
||||
}
|
||||
};
|
||||
if (this.hasSave) config.onSave = this.save.damageMod;
|
||||
if (data.system) {
|
||||
config.source.message = data._id;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ export default class DHMacroAction extends DHBaseAction {
|
|||
}
|
||||
|
||||
async trigger(event, ...args) {
|
||||
// const config = await super.use(event, args);
|
||||
// if (['error', 'warning'].includes(config.type)) return;
|
||||
const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID,
|
||||
macro = await fromUuid(fixUUID);
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ export default class DHSummonAction extends DHBaseAction {
|
|||
|
||||
async trigger(event, ...args) {
|
||||
if (!this.canSummon || !canvas.scene) return;
|
||||
// const config = await super.use(event, args);
|
||||
}
|
||||
|
||||
get canSummon() {
|
||||
|
|
|
|||
|
|
@ -68,12 +68,13 @@ export default class DhCharacter extends BaseDataActor {
|
|||
new fields.SchemaField({
|
||||
name: new fields.StringField(),
|
||||
value: new fields.NumberField({ integer: true, initial: 0 }),
|
||||
description: new fields.StringField()
|
||||
description: new fields.StringField(),
|
||||
core: new fields.BooleanField({ initial: false })
|
||||
})
|
||||
),
|
||||
gold: new fields.SchemaField({
|
||||
coins: new fields.NumberField({ initial: 0, integer: true }),
|
||||
handfulls: new fields.NumberField({ initial: 0, integer: true }),
|
||||
handfuls: new fields.NumberField({ initial: 1, integer: true }),
|
||||
bags: new fields.NumberField({ initial: 0, integer: true }),
|
||||
chests: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
|
|
@ -573,7 +574,10 @@ export default class DhCharacter extends BaseDataActor {
|
|||
case 'experience':
|
||||
selection.data.forEach(id => {
|
||||
const experience = this.experiences[id];
|
||||
if (experience) experience.value += selection.value;
|
||||
if (experience) {
|
||||
experience.value += selection.value;
|
||||
experience.leveledUp = true;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
@ -620,6 +624,23 @@ export default class DhCharacter extends BaseDataActor {
|
|||
};
|
||||
}
|
||||
|
||||
async _preUpdate(changes, options, userId) {
|
||||
const allowed = await super._preUpdate(changes, options, userId);
|
||||
if (allowed === false) return;
|
||||
|
||||
/* The first two experiences are always marked as core */
|
||||
if (changes.system?.experiences && Object.keys(this.experiences).length < 2) {
|
||||
const experiences = new Set(Object.keys(this.experiences));
|
||||
const changeExperiences = new Set(Object.keys(changes.system.experiences));
|
||||
const newExperiences = Array.from(changeExperiences.difference(experiences));
|
||||
|
||||
for (var i = 0; i < Math.min(newExperiences.length, 2 - experiences.size); i++) {
|
||||
const experience = newExperiences[i];
|
||||
changes.system.experiences[experience].core = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async _preDelete() {
|
||||
if (this.companion) {
|
||||
this.companion.updateLevel(1);
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
const targetsField = () => new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({}),
|
||||
actorId: new fields.StringField({}),
|
||||
name: new fields.StringField({}),
|
||||
img: new fields.StringField({}),
|
||||
difficulty: new fields.NumberField({ integer: true, nullable: true }),
|
||||
evasion: new fields.NumberField({ integer: true }),
|
||||
hit: new fields.BooleanField({ initial: false }),
|
||||
saved: new fields.SchemaField({
|
||||
result: new fields.NumberField(),
|
||||
success: new fields.BooleanField({ nullable: true, initial: null })
|
||||
const targetsField = () =>
|
||||
new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({}),
|
||||
actorId: new fields.StringField({}),
|
||||
name: new fields.StringField({}),
|
||||
img: new fields.StringField({}),
|
||||
difficulty: new fields.NumberField({ integer: true, nullable: true }),
|
||||
evasion: new fields.NumberField({ integer: true }),
|
||||
hit: new fields.BooleanField({ initial: false }),
|
||||
saved: new fields.SchemaField({
|
||||
result: new fields.NumberField(),
|
||||
success: new fields.BooleanField({ nullable: true, initial: null })
|
||||
})
|
||||
})
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
||||
targetHook = null;
|
||||
|
|
@ -40,27 +41,25 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
|||
action: new fields.StringField()
|
||||
}),
|
||||
damage: new fields.ObjectField(),
|
||||
costs: new fields.ArrayField(
|
||||
new fields.ObjectField()
|
||||
),
|
||||
costs: new fields.ArrayField(new fields.ObjectField()),
|
||||
successConsumed: new fields.BooleanField({ initial: false })
|
||||
};
|
||||
}
|
||||
|
||||
get actionActor() {
|
||||
if(!this.source.actor) return null;
|
||||
if (!this.source.actor) return null;
|
||||
return fromUuidSync(this.source.actor);
|
||||
}
|
||||
|
||||
get actionItem() {
|
||||
const actionActor = this.actionActor;
|
||||
if(!actionActor || !this.source.item) return null;
|
||||
if (!actionActor || !this.source.item) return null;
|
||||
return actionActor.items.get(this.source.item);
|
||||
}
|
||||
|
||||
get action() {
|
||||
const actionItem = this.actionItem;
|
||||
if(!actionItem || !this.source.action) return null;
|
||||
if (!actionItem || !this.source.action) return null;
|
||||
return actionItem.system.actionsList?.find(a => a.id === this.source.action);
|
||||
}
|
||||
|
||||
|
|
@ -76,90 +75,85 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
|||
this.targetSelection = mode;
|
||||
this.updateTargets();
|
||||
this.registerTargetHook();
|
||||
this.parent.update(
|
||||
{
|
||||
system: {
|
||||
targetSelection: this.targetSelection,
|
||||
oldTargets: this.oldTargets
|
||||
}
|
||||
this.parent.update({
|
||||
system: {
|
||||
targetSelection: this.targetSelection,
|
||||
oldTargets: this.oldTargets
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
get hitTargets() {
|
||||
return this.currentTargets.filter(t => (t.hit || !this.hasRoll || !this.targetSelection));
|
||||
return this.currentTargets.filter(t => t.hit || !this.hasRoll || !this.targetSelection);
|
||||
}
|
||||
|
||||
async updateTargets() {
|
||||
this.currentTargets = this.getTargetList();
|
||||
if(!this.targetSelection) {
|
||||
if (!this.targetSelection) {
|
||||
this.currentTargets.forEach(ct => {
|
||||
if(this.targets.find(t => t.actorId === ct.actorId)) return;
|
||||
if (this.targets.find(t => t.actorId === ct.actorId)) return;
|
||||
const indexTarget = this.oldTargets.findIndex(ot => ot.actorId === ct.actorId);
|
||||
if(indexTarget === -1)
|
||||
this.oldTargets.push(ct);
|
||||
if (indexTarget === -1) this.oldTargets.push(ct);
|
||||
});
|
||||
if(this.hasSave) this.setPendingSaves();
|
||||
if(this.currentTargets.length) {
|
||||
if(!this.parent._id) return;
|
||||
const updates = await this.parent.update(
|
||||
{
|
||||
system: {
|
||||
oldTargets: this.oldTargets
|
||||
}
|
||||
if (this.hasSave) this.setPendingSaves();
|
||||
if (this.currentTargets.length) {
|
||||
if (!this.parent._id) return;
|
||||
const updates = await this.parent.update({
|
||||
system: {
|
||||
oldTargets: this.oldTargets
|
||||
}
|
||||
);
|
||||
if(!updates && ui.chat.collection.get(this.parent.id))
|
||||
ui.chat.updateMessage(this.parent);
|
||||
});
|
||||
if (!updates && ui.chat.collection.get(this.parent.id)) ui.chat.updateMessage(this.parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerTargetHook() {
|
||||
if(this.targetSelection && this.targetHook !== null) {
|
||||
Hooks.off("targetToken", this.targetHook);
|
||||
if (this.targetSelection && this.targetHook !== null) {
|
||||
Hooks.off('targetToken', this.targetHook);
|
||||
this.targetHook = null;
|
||||
} else if(!this.targetSelection && this.targetHook === null) {
|
||||
this.targetHook = Hooks.on("targetToken", foundry.utils.debounce(this.updateTargets.bind(this), 50));
|
||||
} else if (!this.targetSelection && this.targetHook === null) {
|
||||
this.targetHook = Hooks.on('targetToken', foundry.utils.debounce(this.updateTargets.bind(this), 50));
|
||||
}
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
if(this.hasTarget) {
|
||||
if (this.hasTarget) {
|
||||
this.hasHitTarget = this.targets.filter(t => t.hit === true).length > 0;
|
||||
this.updateTargets();
|
||||
this.registerTargetHook();
|
||||
if(this.targetSelection === true) {
|
||||
this.targetShort = this.targets.reduce((a,c) => {
|
||||
if(c.hit) a.hit += 1;
|
||||
else c.miss += 1;
|
||||
return a;
|
||||
}, {hit: 0, miss: 0})
|
||||
if (this.targetSelection === true) {
|
||||
this.targetShort = this.targets.reduce(
|
||||
(a, c) => {
|
||||
if (c.hit) a.hit += 1;
|
||||
else a.miss += 1;
|
||||
return a;
|
||||
},
|
||||
{ hit: 0, miss: 0 }
|
||||
);
|
||||
}
|
||||
if(this.hasSave) this.setPendingSaves();
|
||||
if (this.hasSave) this.setPendingSaves();
|
||||
}
|
||||
|
||||
|
||||
this.canViewSecret = this.parent.speakerActor?.testUserPermission(game.user, 'OBSERVER');
|
||||
}
|
||||
|
||||
getTargetList() {
|
||||
return this.targetSelection !== true
|
||||
? Array.from(game.user.targets).map(t =>{
|
||||
const target = game.system.api.fields.ActionFields.TargetField.formatTarget(t),
|
||||
oldTarget = this.targets.find(ot => ot.actorId === target.actorId) ?? this.oldTargets.find(ot => ot.actorId === target.actorId);
|
||||
if(oldTarget) return oldTarget;
|
||||
return target;
|
||||
})
|
||||
? Array.from(game.user.targets).map(t => {
|
||||
const target = game.system.api.fields.ActionFields.TargetField.formatTarget(t),
|
||||
oldTarget =
|
||||
this.targets.find(ot => ot.actorId === target.actorId) ??
|
||||
this.oldTargets.find(ot => ot.actorId === target.actorId);
|
||||
if (oldTarget) return oldTarget;
|
||||
return target;
|
||||
})
|
||||
: this.targets;
|
||||
}
|
||||
|
||||
setPendingSaves() {
|
||||
this.pendingSaves = this.targetSelection
|
||||
? this.targets.filter(
|
||||
target => target.hit && target.saved.success === null
|
||||
).length > 0
|
||||
: this.currentTargets.filter(
|
||||
target => target.saved.success === null
|
||||
).length > 0;
|
||||
? this.targets.filter(target => target.hit && target.saved.success === null).length > 0
|
||||
: this.currentTargets.filter(target => target.saved.success === null).length > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,25 @@ export default class BeastformField extends fields.SchemaField {
|
|||
constructor(options = {}, context = {}) {
|
||||
const beastformFields = {
|
||||
tierAccess: new fields.SchemaField({
|
||||
exact: new fields.NumberField({ integer: true, nullable: true, initial: null })
|
||||
exact: new fields.NumberField({
|
||||
integer: true,
|
||||
nullable: true,
|
||||
initial: null,
|
||||
choices: () => {
|
||||
const settingsTiers = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.LevelTiers
|
||||
).tiers;
|
||||
return Object.values(settingsTiers).reduce(
|
||||
(acc, tier) => {
|
||||
acc[tier.tier] = game.i18n.localize(tier.name);
|
||||
return acc;
|
||||
},
|
||||
{ 1: game.i18n.localize('DAGGERHEART.GENERAL.Tiers.1') }
|
||||
);
|
||||
},
|
||||
hint: 'DAGGERHEART.ACTIONS.Config.beastform.exactHint'
|
||||
})
|
||||
})
|
||||
};
|
||||
super(beastformFields, options, context);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@ export default class UsesField extends fields.SchemaField {
|
|||
initial: null,
|
||||
nullable: true
|
||||
}),
|
||||
consumeOnSuccess: new fields.BooleanField({ initial: false, label: "DAGGERHEART.ACTIONS.Settings.consumeOnSuccess.label" })
|
||||
consumeOnSuccess: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.ACTIONS.Settings.consumeOnSuccess.label'
|
||||
})
|
||||
};
|
||||
super(usesFields, options, context);
|
||||
}
|
||||
|
|
@ -30,6 +33,7 @@ export default class UsesField extends fields.SchemaField {
|
|||
if (!uses) return null;
|
||||
return {
|
||||
...uses,
|
||||
remaining: this.remainingUses,
|
||||
enabled: uses.hasOwnProperty('enabled') ? uses.enabled : true
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import DHActionConfig from '../../applications/sheets-configs/action-config.mjs';
|
||||
import { itemAbleRollParse } from '../../helpers/utils.mjs';
|
||||
import MappingField from './mappingField.mjs';
|
||||
|
||||
/**
|
||||
|
|
@ -164,6 +165,15 @@ export function ActionMixin(Base) {
|
|||
return foundry.utils.getProperty(this.parent, this.systemPath) instanceof Collection;
|
||||
}
|
||||
|
||||
get remainingUses() {
|
||||
if (!this.uses) return null;
|
||||
|
||||
return Math.max(
|
||||
(this.uses.max ? itemAbleRollParse(this.uses.max, this.actor) : 0) - (this.uses.value ?? 0),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
static async create(data, operation = {}) {
|
||||
const { parent, renderSheet } = operation;
|
||||
let { type } = data;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,26 @@ export default class DHBeastform extends BaseDataItem {
|
|||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
get beastformAttackData() {
|
||||
const effect = this.parent.effects.find(x => x.type === 'beastform');
|
||||
if (!effect) return null;
|
||||
|
||||
const traitBonus = effect.changes.find(x => x.key === `system.traits.${this.mainTrait}.value`)?.value ?? 0;
|
||||
const evasionBonus = effect.changes.find(x => x.key === 'system.evasion')?.value ?? 0;
|
||||
|
||||
const damageDiceIndex = effect.changes.find(x => x.key === 'system.rules.attack.damage.diceIndex');
|
||||
const damageDice = damageDiceIndex ? Object.keys(CONFIG.DH.GENERAL.diceTypes)[damageDiceIndex.value] : null;
|
||||
const damageBonus = effect.changes.find(x => x.key === 'system.rules.attack.damage.bonus')?.value ?? 0;
|
||||
|
||||
return {
|
||||
trait: game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.mainTrait].label),
|
||||
traitBonus: traitBonus ? Number(traitBonus).signedString() : '',
|
||||
evasionBonus: evasionBonus ? Number(evasionBonus).signedString() : '',
|
||||
damageDice: damageDice,
|
||||
damageBonus: damageBonus ? `${Number(damageBonus).signedString()}` : ''
|
||||
};
|
||||
}
|
||||
|
||||
async _preCreate() {
|
||||
if (!this.actor) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ export default class DhAutomation extends foundry.abstract.DataModel {
|
|||
required: true,
|
||||
initial: true,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.resourceScrollTexts.label'
|
||||
}),
|
||||
playerCanEditSheet: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.playerCanEditSheet.label'
|
||||
})
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,10 +45,10 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
|||
initial: 'Coins',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.coinName'
|
||||
}),
|
||||
handfulls: new fields.StringField({
|
||||
handfuls: new fields.StringField({
|
||||
required: true,
|
||||
initial: 'Handfulls',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.handfullName'
|
||||
initial: 'Handfuls',
|
||||
label: 'DAGGERHEART.SETTINGS.Homebrew.currency.handfulName'
|
||||
}),
|
||||
bags: new fields.StringField({
|
||||
required: true,
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
export default class DhRangeMeasurement extends foundry.abstract.DataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
enabled: new fields.BooleanField({ required: true, initial: true, label: 'DAGGERHEART.GENERAL.enabled' }),
|
||||
melee: new fields.NumberField({ required: true, initial: 5, label: 'DAGGERHEART.CONFIG.Range.melee.name' }),
|
||||
veryClose: new fields.NumberField({
|
||||
required: true,
|
||||
initial: 15,
|
||||
label: 'DAGGERHEART.CONFIG.Range.veryClose.name'
|
||||
}),
|
||||
close: new fields.NumberField({
|
||||
required: true,
|
||||
initial: 30,
|
||||
label: 'DAGGERHEART.CONFIG.Range.close.name'
|
||||
}),
|
||||
far: new fields.NumberField({ required: true, initial: 60, label: 'DAGGERHEART.CONFIG.Range.far.name' }),
|
||||
veryFar: new fields.NumberField({
|
||||
required: true,
|
||||
initial: 120,
|
||||
label: 'DAGGERHEART.CONFIG.Range.veryFar.name'
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -17,9 +17,28 @@ export default class DhVariantRules extends foundry.abstract.DataModel {
|
|||
label: 'DAGGERHEART.SETTINGS.VariantRules.FIELDS.actionTokens.tokens.label'
|
||||
})
|
||||
}),
|
||||
useCoins: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.VariantRules.FIELDS.useCoins.label'
|
||||
rangeMeasurement: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: true,
|
||||
label: 'DAGGERHEART.GENERAL.enabled'
|
||||
}),
|
||||
melee: new fields.NumberField({
|
||||
required: true,
|
||||
initial: 5,
|
||||
label: 'DAGGERHEART.CONFIG.Range.melee.name'
|
||||
}),
|
||||
veryClose: new fields.NumberField({
|
||||
required: true,
|
||||
initial: 15,
|
||||
label: 'DAGGERHEART.CONFIG.Range.veryClose.name'
|
||||
}),
|
||||
close: new fields.NumberField({
|
||||
required: true,
|
||||
initial: 30,
|
||||
label: 'DAGGERHEART.CONFIG.Range.close.name'
|
||||
}),
|
||||
far: new fields.NumberField({ required: true, initial: 60, label: 'DAGGERHEART.CONFIG.Range.far.name' })
|
||||
})
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export { default as DhAppearance } from './Appearance.mjs';
|
||||
export { default as DhAutomation } from './Automation.mjs';
|
||||
export { default as DhHomebrew } from './Homebrew.mjs';
|
||||
export { default as DhRangeMeasurement } from './RangeMeasurement.mjs';
|
||||
export { default as DhVariantRules } from './VariantRules.mjs';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue