mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Initial v14 fixes
This commit is contained in:
parent
b374070809
commit
1a928e950c
19 changed files with 197 additions and 180 deletions
|
|
@ -33,6 +33,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
settings: { template: 'systems/daggerheart/templates/sheets/activeEffect/settings.hbs' },
|
||||
changes: {
|
||||
template: 'systems/daggerheart/templates/sheets/activeEffect/changes.hbs',
|
||||
templates: ['systems/daggerheart/templates/sheets/activeEffect/change.hbs'],
|
||||
scrollable: ['ol[data-changes]']
|
||||
},
|
||||
footer: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-form-footer.hbs' }
|
||||
|
|
@ -121,8 +122,41 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
}));
|
||||
}
|
||||
break;
|
||||
case 'changes':
|
||||
const fields = this.document.system.schema.fields.changes.element.fields;
|
||||
partContext.changes = await Promise.all(
|
||||
foundry.utils
|
||||
.deepClone(context.source.changes)
|
||||
.map((c, i) => this._prepareChangeContext(c, i, fields))
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return partContext;
|
||||
}
|
||||
|
||||
_prepareChangeContext(change, index, fields) {
|
||||
if (typeof change.value !== 'string') change.value = JSON.stringify(change.value);
|
||||
const defaultPriority = game.system.api.documents.DhActiveEffect.CHANGE_TYPES[change.type]?.defaultPriority;
|
||||
Object.assign(
|
||||
change,
|
||||
['key', 'type', 'value', 'priority'].reduce((paths, fieldName) => {
|
||||
paths[`${fieldName}Path`] = `system.changes.${index}.${fieldName}`;
|
||||
return paths;
|
||||
}, {})
|
||||
);
|
||||
return (
|
||||
game.system.api.documents.DhActiveEffect.CHANGE_TYPES[change.type].render?.(
|
||||
change,
|
||||
index,
|
||||
defaultPriority
|
||||
) ??
|
||||
renderTemplate('systems/daggerheart/templates/sheets/activeEffect/change.hbs', {
|
||||
change,
|
||||
index,
|
||||
defaultPriority,
|
||||
fields
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,18 +72,6 @@ const typeSettingsMap = {
|
|||
*/
|
||||
export default function DHApplicationMixin(Base) {
|
||||
class DHSheetV2 extends HandlebarsApplicationMixin(Base) {
|
||||
/**
|
||||
* @param {DHSheetV2Configuration} [options={}]
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
/**
|
||||
* @type {foundry.applications.ux.DragDrop[]}
|
||||
* @private
|
||||
*/
|
||||
this._dragDrop = this._createDragDropHandlers();
|
||||
}
|
||||
|
||||
#nonHeaderAttribution = ['environment', 'ancestry', 'community', 'domainCard'];
|
||||
|
||||
/**
|
||||
|
|
@ -177,7 +165,7 @@ export default function DHApplicationMixin(Base) {
|
|||
/**@inheritdoc */
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
this._dragDrop.forEach(d => d.bind(htmlElement));
|
||||
// this._dragDrop.forEach(d => d.bind(htmlElement));
|
||||
|
||||
// Handle delta inputs
|
||||
for (const deltaInput of htmlElement.querySelectorAll('input[data-allow-delta]')) {
|
||||
|
|
@ -350,21 +338,6 @@ export default function DHApplicationMixin(Base) {
|
|||
/* Drag and Drop */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Creates drag-drop handlers from the configured options.
|
||||
* @returns {foundry.applications.ux.DragDrop[]}
|
||||
* @private
|
||||
*/
|
||||
_createDragDropHandlers() {
|
||||
return this.options.dragDrop.map(d => {
|
||||
d.callbacks = {
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
drop: this._onDrop.bind(this)
|
||||
};
|
||||
return new foundry.applications.ux.DragDrop.implementation(d);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle dragStart event.
|
||||
* @param {DragEvent} event
|
||||
|
|
|
|||
|
|
@ -52,10 +52,6 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
}
|
||||
};
|
||||
|
||||
get element() {
|
||||
return document.body.querySelector('.daggerheart.dh-style.countdowns');
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _renderFrame(options) {
|
||||
const frame = await super._renderFrame(options);
|
||||
|
|
@ -68,6 +64,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
|
||||
const header = frame.querySelector('.window-header');
|
||||
header.querySelector('button[data-action="close"]').remove();
|
||||
header.querySelector('button[data-action="toggleControls"]').remove();
|
||||
|
||||
if (game.user.isGM) {
|
||||
const editTooltip = game.i18n.localize('DAGGERHEART.APPLICATIONS.CountdownEdit.editTitle');
|
||||
|
|
@ -278,10 +275,8 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
return acc;
|
||||
}, {})
|
||||
};
|
||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns,
|
||||
DhCountdowns.gmSetSetting.bind(settings),
|
||||
settings, null, {
|
||||
refreshType: RefreshType.Countdown
|
||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||
refreshType: RefreshType.Countdown
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export default class DhTemplateLayer extends foundry.canvas.layers.TemplateLayer
|
|||
order: 2,
|
||||
title: 'CONTROLS.GroupMeasure',
|
||||
icon: 'fa-solid fa-ruler-combined',
|
||||
visible: game.user.can('TEMPLATE_CREATE'),
|
||||
visible: game.user.can('REGION_CREATE'),
|
||||
onChange: (event, active) => {
|
||||
if (active) canvas.templates.activate();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -70,8 +70,12 @@ export const range = {
|
|||
}
|
||||
};
|
||||
|
||||
/* circle|cone|rect|ray used to be CONST.MEASURED_TEMPLATE_TYPES. Hardcoded for now */
|
||||
export const templateTypes = {
|
||||
...CONST.MEASURED_TEMPLATE_TYPES,
|
||||
CIRCLE: 'circle',
|
||||
CONE: 'cone',
|
||||
RECTANGLE: 'rect',
|
||||
RAY: 'ray',
|
||||
EMANATION: 'emanation',
|
||||
INFRONT: 'inFront'
|
||||
};
|
||||
|
|
@ -737,3 +741,36 @@ export const sceneRangeMeasurementSetting = {
|
|||
label: 'Custom'
|
||||
}
|
||||
};
|
||||
|
||||
export const activeEffectModes = {
|
||||
custom: {
|
||||
id: 'custom',
|
||||
priority: 0,
|
||||
label: 'EFFECT.CHANGES.TYPES.custom'
|
||||
},
|
||||
multiply: {
|
||||
id: 'multiply',
|
||||
priority: 10,
|
||||
label: 'EFFECT.CHANGES.TYPES.multiply'
|
||||
},
|
||||
add: {
|
||||
id: 'add',
|
||||
priority: 20,
|
||||
label: 'EFFECT.CHANGES.TYPES.add'
|
||||
},
|
||||
downgrade: {
|
||||
id: 'downgrade',
|
||||
priority: 30,
|
||||
label: 'EFFECT.CHANGES.TYPES.downgrade'
|
||||
},
|
||||
upgrade: {
|
||||
id: 'upgrade',
|
||||
priority: 40,
|
||||
label: 'EFFECT.CHANGES.TYPES.upgrade'
|
||||
},
|
||||
override: {
|
||||
id: 'override',
|
||||
priority: 50,
|
||||
label: 'EFFECT.CHANGES.TYPES.override'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,84 +2,4 @@ import DHBaseAction from './baseAction.mjs';
|
|||
|
||||
export default class DhBeastformAction extends DHBaseAction {
|
||||
static extraSchemas = [...super.extraSchemas, 'beastform'];
|
||||
|
||||
/* async use(event, options) {
|
||||
const beastformConfig = this.prepareBeastformConfig();
|
||||
|
||||
const abort = await this.handleActiveTransformations();
|
||||
if (abort) return;
|
||||
|
||||
const calcCosts = game.system.api.fields.ActionFields.CostField.calcCosts.call(this, this.cost);
|
||||
const hasCost = game.system.api.fields.ActionFields.CostField.hasCost.call(this, calcCosts);
|
||||
if (!hasCost) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.insufficientResources'));
|
||||
return;
|
||||
}
|
||||
|
||||
const { selected, evolved, hybrid } = await BeastformDialog.configure(beastformConfig, this.item);
|
||||
if (!selected) return;
|
||||
|
||||
const result = await super.use(event, options);
|
||||
if (!result) return;
|
||||
|
||||
await this.transform(selected, evolved, hybrid);
|
||||
}
|
||||
|
||||
prepareBeastformConfig(config) {
|
||||
const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers;
|
||||
const actorLevel = this.actor.system.levelData.level.current;
|
||||
const actorTier =
|
||||
Object.values(settingsTiers).find(
|
||||
tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end
|
||||
) ?? 1;
|
||||
|
||||
return {
|
||||
tierLimit: this.beastform.tierAccess.exact ?? actorTier
|
||||
};
|
||||
}
|
||||
|
||||
async transform(selectedForm, evolvedData, hybridData) {
|
||||
const formData = evolvedData?.form ? evolvedData.form.toObject() : selectedForm.toObject();
|
||||
const beastformEffect = formData.effects.find(x => x.type === 'beastform');
|
||||
if (!beastformEffect) {
|
||||
ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect');
|
||||
return;
|
||||
}
|
||||
|
||||
if (evolvedData?.form) {
|
||||
const evolvedForm = selectedForm.effects.find(x => x.type === 'beastform');
|
||||
if (!evolvedForm) {
|
||||
ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect');
|
||||
return;
|
||||
}
|
||||
|
||||
beastformEffect.changes = [...beastformEffect.changes, ...evolvedForm.changes];
|
||||
formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)];
|
||||
}
|
||||
|
||||
if (selectedForm.system.beastformType === CONFIG.DH.ITEM.beastformTypes.hybrid.id) {
|
||||
formData.system.advantageOn = Object.values(hybridData.advantages).reduce((advantages, formCategory) => {
|
||||
Object.keys(formCategory).forEach(advantageKey => {
|
||||
advantages[advantageKey] = formCategory[advantageKey];
|
||||
});
|
||||
return advantages;
|
||||
}, {});
|
||||
formData.system.features = [
|
||||
...formData.system.features,
|
||||
...Object.values(hybridData.features).flatMap(x => Object.keys(x))
|
||||
];
|
||||
}
|
||||
|
||||
this.actor.createEmbeddedDocuments('Item', [formData]);
|
||||
}
|
||||
|
||||
async handleActiveTransformations() {
|
||||
const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform');
|
||||
const existingEffects = beastformEffects.length > 0;
|
||||
await this.actor.deleteEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
beastformEffects.map(x => x.id)
|
||||
);
|
||||
return existingEffects;
|
||||
} */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,27 @@
|
|||
* "Anything that uses another data model value as its value": +1 - Effects that increase traits have to be calculated first at Base priority. (EX: Raise evasion by half your agility)
|
||||
*/
|
||||
|
||||
export default class BaseEffect extends foundry.abstract.TypeDataModel {
|
||||
export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
changes: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
key: new fields.StringField({ required: true }),
|
||||
type: new fields.StringField({
|
||||
required: true,
|
||||
blank: false,
|
||||
choices: CONFIG.DH.GENERAL.activeEffectModes,
|
||||
initial: CONFIG.DH.GENERAL.activeEffectModes.add.id,
|
||||
validate: BaseEffect.#validateType
|
||||
}),
|
||||
value: new fields.AnyField({ required: true, nullable: true, serializable: true, initial: '' }),
|
||||
phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }),
|
||||
priority: new fields.NumberField()
|
||||
})
|
||||
),
|
||||
rangeDependence: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({
|
||||
required: true,
|
||||
|
|
@ -45,6 +61,23 @@ export default class BaseEffect extends foundry.abstract.TypeDataModel {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that an {@link EffectChangeData#type} string is well-formed.
|
||||
* @param {string} type The string to be validated
|
||||
* @returns {true}
|
||||
* @throws {Error} An error if the type string is malformed
|
||||
*/
|
||||
static #validateType(type) {
|
||||
if (type.length < 3) throw new Error('must be at least three characters long');
|
||||
if (!/^custom\.-?\d+$/.test(type) && !type.split('.').every(s => /^[a-z0-9]+$/i.test(s))) {
|
||||
throw new Error(
|
||||
'A change type must either be a sequence of dot-delimited, alpha-numeric substrings or of the form' +
|
||||
' "custom.{number}"'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static getDefaultObject() {
|
||||
return {
|
||||
name: 'New Effect',
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ export default class BeastformEffect extends BaseEffect {
|
|||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
...super.defineSchema(),
|
||||
characterTokenData: new fields.SchemaField({
|
||||
usesDynamicToken: new fields.BooleanField({ initial: false }),
|
||||
tokenImg: new fields.FilePathField({
|
||||
|
|
|
|||
|
|
@ -111,9 +111,17 @@ export class ActionField extends foundry.data.fields.ObjectField {
|
|||
* @param {object} sourceData Candidate source data of the root model.
|
||||
* @param {any} fieldData The value of this field within the source data.
|
||||
*/
|
||||
migrateSource(sourceData, fieldData) {
|
||||
const cls = this.getModel(fieldData);
|
||||
if (cls) cls.migrateDataSafe(fieldData);
|
||||
_migrate(sourceData, _fieldData) {
|
||||
const source = sourceData ?? this.options.initial;
|
||||
if (!source) return sourceData;
|
||||
|
||||
const cls = this.getModel(source);
|
||||
if (cls) {
|
||||
cls.migrateDataSafe(source);
|
||||
return source;
|
||||
}
|
||||
|
||||
return sourceData;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,12 +101,13 @@ export default class DHBeastform extends BaseDataItem {
|
|||
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 traitBonus =
|
||||
effect.system.changes.find(x => x.key === `system.traits.${this.mainTrait}.value`)?.value ?? 0;
|
||||
const evasionBonus = effect.system.changes.find(x => x.key === 'system.evasion')?.value ?? 0;
|
||||
|
||||
const damageDiceIndex = effect.changes.find(x => x.key === 'system.rules.attack.damage.diceIndex');
|
||||
const damageDiceIndex = effect.system.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;
|
||||
const damageBonus = effect.system.changes.find(x => x.key === 'system.rules.attack.damage.bonus')?.value ?? 0;
|
||||
|
||||
return {
|
||||
trait: game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.mainTrait].label),
|
||||
|
|
@ -169,17 +170,17 @@ export default class DHBeastform extends BaseDataItem {
|
|||
|
||||
const beastformEffect = this.parent.effects.find(x => x.type === 'beastform');
|
||||
await beastformEffect.updateSource({
|
||||
changes: [
|
||||
...beastformEffect.changes,
|
||||
{
|
||||
key: 'system.advantageSources',
|
||||
mode: 2,
|
||||
value: Object.values(this.advantageOn)
|
||||
.map(x => x.value)
|
||||
.join(', ')
|
||||
}
|
||||
],
|
||||
system: {
|
||||
changes: [
|
||||
...beastformEffect.system.changes,
|
||||
{
|
||||
key: 'system.advantageSources',
|
||||
mode: 2,
|
||||
value: Object.values(this.advantageOn)
|
||||
.map(x => x.value)
|
||||
.join(', ')
|
||||
}
|
||||
],
|
||||
characterTokenData: {
|
||||
usesDynamicToken: this.parent.parent.prototypeToken.ring.enabled,
|
||||
tokenImg: this.parent.parent.prototypeToken.texture.src,
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ export default class DHSubclass extends BaseDataItem {
|
|||
}
|
||||
|
||||
async _preCreate(data, options, user) {
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
if (allowed === false) return;
|
||||
|
||||
if (this.actor?.type === 'character') {
|
||||
const dataUuid = data.uuid ?? data._stats.compendiumSource ?? `Item.${data._id}`;
|
||||
if (this.actor.system.class.subclass) {
|
||||
|
|
@ -85,8 +88,5 @@ export default class DHSubclass extends BaseDataItem {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
if (allowed === false) return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ export default class DamageRoll extends DHRoll {
|
|||
if (config.data.parent.appliedEffects) {
|
||||
// Bardic Rally
|
||||
const rallyChoices = config.data?.parent?.appliedEffects.reduce((a, c) => {
|
||||
const change = c.changes.find(ch => ch.key === 'system.bonuses.rally');
|
||||
const change = c.system.changes.find(ch => ch.key === 'system.bonuses.rally');
|
||||
if (change) a.push({ value: c.id, label: change.value });
|
||||
return a;
|
||||
}, []);
|
||||
|
|
|
|||
|
|
@ -249,12 +249,12 @@ export default class DHRoll extends Roll {
|
|||
const changeKeys = this.getActionChangeKeys();
|
||||
return (
|
||||
this.options.effects?.reduce((acc, effect) => {
|
||||
if (effect.changes.some(x => changeKeys.some(key => x.key.includes(key)))) {
|
||||
if (effect.system.changes.some(x => changeKeys.some(key => x.key.includes(key)))) {
|
||||
acc[effect.id] = {
|
||||
id: effect.id,
|
||||
name: effect.name,
|
||||
description: effect.description,
|
||||
changes: effect.changes,
|
||||
changes: effect.system.changes,
|
||||
origEffect: effect,
|
||||
selected: !effect.disabled
|
||||
};
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ export default class DualityRoll extends D20Roll {
|
|||
|
||||
setRallyChoices() {
|
||||
return this.data?.parent?.appliedEffects.reduce((a, c) => {
|
||||
const change = c.changes.find(ch => ch.key === 'system.bonuses.rally');
|
||||
const change = c.system.changes.find(ch => ch.key === 'system.bonuses.rally');
|
||||
if (change) a.push({ value: c.id, label: change.value });
|
||||
return a;
|
||||
}, []);
|
||||
|
|
@ -179,7 +179,7 @@ export default class DualityRoll extends D20Roll {
|
|||
static async buildConfigure(config = {}, message = {}) {
|
||||
config.dialog ??= {};
|
||||
config.guaranteedCritical = config.data?.parent?.appliedEffects.reduce((a, c) => {
|
||||
const change = c.changes.find(ch => ch.key === 'system.rules.roll.guaranteedCritical');
|
||||
const change = c.system.changes.find(ch => ch.key === 'system.rules.roll.guaranteedCritical');
|
||||
if (change) a = true;
|
||||
return a;
|
||||
}, false);
|
||||
|
|
|
|||
|
|
@ -109,17 +109,25 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
|
||||
/**@inheritdoc*/
|
||||
static applyField(model, change, field) {
|
||||
change.value = DhActiveEffect.getChangeValue(model, change, change.effect);
|
||||
change.key = DhActiveEffect.getChangeKey(model, change, change.effect);
|
||||
super.applyField(model, change, field);
|
||||
}
|
||||
|
||||
/** */
|
||||
static getChangeKey(model, change, effect) {
|
||||
return DhActiveEffect.parseValue(change.key, model, change, effect);
|
||||
}
|
||||
|
||||
static getChangeValue(model, change, effect) {
|
||||
let value = change.value;
|
||||
const isOriginTarget = value.toLowerCase().includes('origin.@');
|
||||
return DhActiveEffect.parseValue(change.value, model, change, effect);
|
||||
}
|
||||
|
||||
static parseValue(value, model, change, effect) {
|
||||
let key = value;
|
||||
const isOriginTarget = key.toLowerCase().includes('origin.@');
|
||||
let parseModel = model;
|
||||
if (isOriginTarget && effect.origin) {
|
||||
value = change.value.replaceAll(/origin\.@/gi, '@');
|
||||
key = change.key.replaceAll(/origin\.@/gi, '@');
|
||||
try {
|
||||
const originEffect = foundry.utils.fromUuidSync(effect.origin);
|
||||
const doc =
|
||||
|
|
@ -130,8 +138,8 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
} catch (_) {}
|
||||
}
|
||||
|
||||
const evalValue = this.effectSafeEval(itemAbleRollParse(value, parseModel, effect.parent));
|
||||
return evalValue ?? value;
|
||||
const evalValue = this.effectSafeEval(itemAbleRollParse(key, parseModel, effect.parent));
|
||||
return evalValue ?? key;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -415,7 +415,12 @@ export async function createEmbeddedItemWithEffects(actor, baseData, update) {
|
|||
...baseData,
|
||||
id: data.id,
|
||||
uuid: data.uuid,
|
||||
effects: data.effects?.map(effect => effect.toObject())
|
||||
_uuid: data.uuid,
|
||||
effects: data.effects?.map(effect => effect.toObject()),
|
||||
_stats: {
|
||||
...data._stats,
|
||||
compendiumSource: data.pack ? `Compendium.${data.pack}.Item.${data.id}` : null
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
"id": "daggerheart",
|
||||
"title": "Daggerheart",
|
||||
"description": "An unofficial implementation of the Daggerheart system",
|
||||
"version": "1.6.1",
|
||||
"version": "2.0.0",
|
||||
"compatibility": {
|
||||
"minimum": "13.346",
|
||||
"verified": "13.351",
|
||||
"maximum": "13"
|
||||
"minimum": "14.353",
|
||||
"verified": "14.353",
|
||||
"maximum": "14"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
|
|
|
|||
17
templates/sheets/activeEffect/change.hbs
Normal file
17
templates/sheets/activeEffect/change.hbs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<li data-index="{{index}}">
|
||||
<div class="key">
|
||||
{{formInput fields.key name=change.keyPath value=change.key}}
|
||||
</div>
|
||||
<div class="type">
|
||||
{{formInput fields.type name=change.typePath value=change.type localize=true}}
|
||||
</div>
|
||||
<div class="value">
|
||||
{{formInput fields.value name=change.valuePath value=change.value elementType="input"}}
|
||||
</div>
|
||||
<div class="priority">
|
||||
{{formInput fields.priority name=change.priorityPath value=change.priority placeholder=defaultPriority}}
|
||||
</div>
|
||||
<div class="controls">
|
||||
<button type="button" class="inline-control icon fa-solid fa-trash" data-action="deleteChange"></button>
|
||||
</div>
|
||||
</li>
|
||||
|
|
@ -1,31 +1,16 @@
|
|||
<section class="tab changes{{#if tab.active}} active{{/if}}" data-group="{{tab.group}}" data-tab="{{tab.id}}">
|
||||
<header>
|
||||
<div class="key">{{localize "EFFECT.ChangeKey"}}</div>
|
||||
<div class="mode">{{localize "EFFECT.ChangeMode"}}</div>
|
||||
<div class="value">{{localize "EFFECT.ChangeValue"}}</div>
|
||||
<div class="priority">{{localize "EFFECT.ChangePriority"}}</div>
|
||||
<div class="controls"><a data-action="addChange"><i class="fa-regular fa-square-plus"></i></a></div>
|
||||
<div class="key">{{localize "EFFECT.FIELDS.changes.element.key.label"}}</div>
|
||||
<div class="type">{{localize "EFFECT.FIELDS.changes.element.type.label"}}</div>
|
||||
<div class="value">{{localize "EFFECT.FIELDS.changes.element.value.label"}}</div>
|
||||
<div class="priority">{{localize "EFFECT.FIELDS.changes.element.priority.label"}}</div>
|
||||
<div class="controls">
|
||||
<button type="button" class="inline-control icon fa-regular fa-square-plus" data-action="addChange"></button>
|
||||
</div>
|
||||
</header>
|
||||
<ol class="scrollable" data-changes>
|
||||
{{#each source.changes as |change i|}}
|
||||
{{#with ../fields.changes.element.fields as |changeFields|}}
|
||||
<li data-index="{{i}}">
|
||||
<div class="key">
|
||||
<input type="text" class="effect-change-input" name="{{concat "changes." i ".key"}}" value="{{change.key}}" />
|
||||
</div>
|
||||
<div class="mode">
|
||||
{{formInput changeFields.mode name=(concat "changes." i ".mode") value=change.mode choices=@root.modes}}
|
||||
</div>
|
||||
<div class="value">
|
||||
{{formInput changeFields.value name=(concat "changes." i ".value") value=change.value}}
|
||||
</div>
|
||||
<div class="priority">
|
||||
{{formInput changeFields.priority name=(concat "changes." i ".priority") value=change.priority
|
||||
placeholder=(lookup ../../priorities change.mode)}}
|
||||
</div>
|
||||
<div class="controls"><a data-action="deleteChange"><i class="fa-solid fa-trash"></i></a></div>
|
||||
</li>
|
||||
{{/with}}
|
||||
{{#each changes as |change|}}
|
||||
{{{change}}}
|
||||
{{/each}}
|
||||
</ol>
|
||||
</section>
|
||||
Loading…
Add table
Add a link
Reference in a new issue