mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-24 08:23:38 +02:00
.
This commit is contained in:
parent
8f7c7ce818
commit
79b34acf09
8 changed files with 134 additions and 53 deletions
|
|
@ -1899,6 +1899,10 @@
|
||||||
"hint": "Multiply any damage dealt to you by this number"
|
"hint": "Multiply any damage dealt to you by this number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Attribute": {
|
||||||
|
"single": "Attribute",
|
||||||
|
"plural": "Attributes"
|
||||||
|
},
|
||||||
"Bonuses": {
|
"Bonuses": {
|
||||||
"rest": {
|
"rest": {
|
||||||
"downtimeAction": "Downtime Action",
|
"downtimeAction": "Downtime Action",
|
||||||
|
|
@ -2338,6 +2342,7 @@
|
||||||
"scars": "Scars",
|
"scars": "Scars",
|
||||||
"situationalBonus": "Situational Bonus",
|
"situationalBonus": "Situational Bonus",
|
||||||
"spent": "Spent",
|
"spent": "Spent",
|
||||||
|
"status": "Status",
|
||||||
"step": "Step",
|
"step": "Step",
|
||||||
"stress": "Stress",
|
"stress": "Stress",
|
||||||
"subclasses": "Subclasses",
|
"subclasses": "Subclasses",
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,10 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
||||||
id: x.id,
|
id: x.id,
|
||||||
label: x.name
|
label: x.name
|
||||||
}));
|
}));
|
||||||
|
partContext.conditionalTypes = Object.values(CONFIG.DH.GENERAL.activeEffectConditionalType).map(x => ({
|
||||||
|
id: x.id,
|
||||||
|
label: game.i18n.localize(x.label)
|
||||||
|
}));
|
||||||
break;
|
break;
|
||||||
case 'changes':
|
case 'changes':
|
||||||
const fields = this.document.system.schema.fields.changes.element.fields;
|
const fields = this.document.system.schema.fields.changes.element.fields;
|
||||||
|
|
@ -247,14 +251,22 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
||||||
}
|
}
|
||||||
|
|
||||||
static #addConditional() {
|
static #addConditional() {
|
||||||
const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form));
|
const submitData = this._processFormData(
|
||||||
|
null,
|
||||||
|
this.form,
|
||||||
|
new foundry.applications.ux.FormDataExtended(this.form)
|
||||||
|
);
|
||||||
const conditionals = Object.values(submitData.system?.conditionals ?? {});
|
const conditionals = Object.values(submitData.system?.conditionals ?? {});
|
||||||
conditionals.push(this.document.system.schema.fields.conditionals.element.getInitialValue());
|
conditionals.push(this.document.system.schema.fields.conditionals.element.getInitialValue());
|
||||||
return this.submit({ updateData: { system: { conditionals } } });
|
return this.submit({ updateData: { system: { conditionals } } });
|
||||||
}
|
}
|
||||||
|
|
||||||
static async #removeConditional(_event, button) {
|
static async #removeConditional(_event, button) {
|
||||||
const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form));
|
const submitData = this._processFormData(
|
||||||
|
null,
|
||||||
|
this.form,
|
||||||
|
new foundry.applications.ux.FormDataExtended(this.form)
|
||||||
|
);
|
||||||
const conditionals = Object.values(submitData.system.conditionals);
|
const conditionals = Object.values(submitData.system.conditionals);
|
||||||
const index = Number(button.dataset.index) || 0;
|
const index = Number(button.dataset.index) || 0;
|
||||||
conditionals.splice(index, 1);
|
conditionals.splice(index, 1);
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,9 @@ export default class SettingActiveEffectConfig extends HandlebarsApplicationMixi
|
||||||
actions: {
|
actions: {
|
||||||
editImage: SettingActiveEffectConfig.#editImage,
|
editImage: SettingActiveEffectConfig.#editImage,
|
||||||
addChange: SettingActiveEffectConfig.#addChange,
|
addChange: SettingActiveEffectConfig.#addChange,
|
||||||
deleteChange: SettingActiveEffectConfig.#deleteChange
|
deleteChange: SettingActiveEffectConfig.#deleteChange,
|
||||||
|
addConditional: SettingActiveEffectConfig.#addConditional,
|
||||||
|
removeConditional: SettingActiveEffectConfig.#removeConditional
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -33,8 +35,10 @@ export default class SettingActiveEffectConfig extends HandlebarsApplicationMixi
|
||||||
tabs: { template: 'templates/generic/tab-navigation.hbs' },
|
tabs: { template: 'templates/generic/tab-navigation.hbs' },
|
||||||
details: { template: 'systems/daggerheart/templates/sheets/activeEffect/details.hbs', scrollable: [''] },
|
details: { template: 'systems/daggerheart/templates/sheets/activeEffect/details.hbs', scrollable: [''] },
|
||||||
settings: { template: 'systems/daggerheart/templates/sheets/activeEffect/settings.hbs' },
|
settings: { template: 'systems/daggerheart/templates/sheets/activeEffect/settings.hbs' },
|
||||||
|
conditionals: { template: 'systems/daggerheart/templates/sheets/activeEffect/conditionals.hbs' },
|
||||||
changes: {
|
changes: {
|
||||||
template: 'systems/daggerheart/templates/sheets/activeEffect/changes.hbs',
|
template: 'systems/daggerheart/templates/sheets/activeEffect/changes.hbs',
|
||||||
|
templates: ['systems/daggerheart/templates/sheets/activeEffect/change.hbs'],
|
||||||
scrollable: ['ol[data-changes]']
|
scrollable: ['ol[data-changes]']
|
||||||
},
|
},
|
||||||
footer: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-form-footer.hbs' }
|
footer: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-form-footer.hbs' }
|
||||||
|
|
@ -45,6 +49,11 @@ export default class SettingActiveEffectConfig extends HandlebarsApplicationMixi
|
||||||
tabs: [
|
tabs: [
|
||||||
{ id: 'details', icon: 'fa-solid fa-book' },
|
{ id: 'details', icon: 'fa-solid fa-book' },
|
||||||
{ id: 'settings', icon: 'fa-solid fa-bars', label: 'DAGGERHEART.GENERAL.Tabs.settings' },
|
{ id: 'settings', icon: 'fa-solid fa-bars', label: 'DAGGERHEART.GENERAL.Tabs.settings' },
|
||||||
|
{
|
||||||
|
id: 'conditionals',
|
||||||
|
icon: 'fa-solid fa-person-circle-question',
|
||||||
|
label: 'DAGGERHEART.GENERAL.Tabs.conditionals'
|
||||||
|
},
|
||||||
{ id: 'changes', icon: 'fa-solid fa-gears' }
|
{ id: 'changes', icon: 'fa-solid fa-gears' }
|
||||||
],
|
],
|
||||||
initial: 'details',
|
initial: 'details',
|
||||||
|
|
@ -140,6 +149,20 @@ export default class SettingActiveEffectConfig extends HandlebarsApplicationMixi
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'conditionals':
|
||||||
|
context.conditionals = this.effect.system.conditionals.map(conditional => ({
|
||||||
|
...conditional,
|
||||||
|
...game.system.api.data.activeEffects.EffectConditional.getConditionalFieldUseage(conditional.type)
|
||||||
|
}));
|
||||||
|
context.statusChoices = Object.values(CONFIG.statusEffects).map(x => ({
|
||||||
|
id: x.id,
|
||||||
|
label: x.name
|
||||||
|
}));
|
||||||
|
context.conditionalTypes = Object.values(CONFIG.DH.GENERAL.activeEffectConditionalType).map(x => ({
|
||||||
|
id: x.id,
|
||||||
|
label: game.i18n.localize(x.label)
|
||||||
|
}));
|
||||||
|
break;
|
||||||
case 'changes':
|
case 'changes':
|
||||||
context.modes = Object.entries(CONST.ACTIVE_EFFECT_MODES).reduce((modes, [key, value]) => {
|
context.modes = Object.entries(CONST.ACTIVE_EFFECT_MODES).reduce((modes, [key, value]) => {
|
||||||
modes[value] = game.i18n.localize(`EFFECT.MODE_${key}`);
|
modes[value] = game.i18n.localize(`EFFECT.MODE_${key}`);
|
||||||
|
|
@ -155,6 +178,11 @@ export default class SettingActiveEffectConfig extends HandlebarsApplicationMixi
|
||||||
|
|
||||||
static async #onSubmit(_event, _form, formData) {
|
static async #onSubmit(_event, _form, formData) {
|
||||||
this.data = foundry.utils.expandObject(formData.object);
|
this.data = foundry.utils.expandObject(formData.object);
|
||||||
|
this.data.system.conditionals = Object.values(this.data.system.conditionals).map(x => ({
|
||||||
|
...x,
|
||||||
|
key: x.key.find(key => key) ?? ''
|
||||||
|
}));
|
||||||
|
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,6 +211,38 @@ export default class SettingActiveEffectConfig extends HandlebarsApplicationMixi
|
||||||
await fp.browse();
|
await fp.browse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
_onChangeForm(_formConfig, event) {
|
||||||
|
if (
|
||||||
|
foundry.utils.isElementInstanceOf(event.target, 'select') &&
|
||||||
|
event.target.name.startsWith('system.conditionals') &&
|
||||||
|
event.target.name.endsWith('type')
|
||||||
|
) {
|
||||||
|
const container = event.target.closest('.conditional-container');
|
||||||
|
|
||||||
|
const statusSelect = container.querySelector('.form-group.status-select');
|
||||||
|
const attributeAuto = container.querySelector('.form-group.attribute-auto');
|
||||||
|
if (event.target.value === CONFIG.DH.GENERAL.activeEffectConditionalType.status.id) {
|
||||||
|
statusSelect.classList.remove('not-visible');
|
||||||
|
attributeAuto.classList.add('not-visible');
|
||||||
|
} else {
|
||||||
|
statusSelect.classList.add('not-visible');
|
||||||
|
attributeAuto.classList.remove('not-visible');
|
||||||
|
}
|
||||||
|
statusSelect.querySelector('select').selectedIndex = '-1';
|
||||||
|
attributeAuto.querySelector('input').value = '';
|
||||||
|
|
||||||
|
const { usesValue, usesComparator } =
|
||||||
|
game.system.api.data.activeEffects.EffectConditional.getConditionalFieldUseage(event.target.value);
|
||||||
|
|
||||||
|
if (usesValue) container.querySelector('.form-group.value').classList.remove('not-visible');
|
||||||
|
else container.querySelector('.form-group.value').classList.add('not-visible');
|
||||||
|
|
||||||
|
if (usesComparator) container.querySelector('.form-group.comparator').classList.remove('not-visible');
|
||||||
|
else container.querySelector('.form-group.comparator').classList.add('not-visible');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new change to the effect's changes array.
|
* Add a new change to the effect's changes array.
|
||||||
* @this {ActiveEffectConfig}
|
* @this {ActiveEffectConfig}
|
||||||
|
|
@ -213,6 +273,27 @@ export default class SettingActiveEffectConfig extends HandlebarsApplicationMixi
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static #addConditional() {
|
||||||
|
const formData = foundry.utils.expandObject(new FormDataExtended(this.form).object);
|
||||||
|
const updatedConditionals = Object.values(formData.system.conditionals ?? {});
|
||||||
|
updatedConditionals.push(
|
||||||
|
game.system.api.data.activeEffects.BaseEffect._schema.fields.conditionals.element.getInitialValue()
|
||||||
|
);
|
||||||
|
|
||||||
|
this.effect = { ...formData, system: { ...formData.system, conditionals: updatedConditionals } };
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #removeConditional(_event, button) {
|
||||||
|
const submitData = foundry.utils.expandObject(new FormDataExtended(this.form).object);
|
||||||
|
const conditionals = Object.values(submitData.system.conditionals);
|
||||||
|
const index = Number(button.dataset.index) || 0;
|
||||||
|
conditionals.splice(index, 1);
|
||||||
|
|
||||||
|
this.effect = { ...submitData, system: { ...submitData.system, conditionals } };
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
static async configure(effect, options = {}) {
|
static async configure(effect, options = {}) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const app = new this(effect, options);
|
const app = new this(effect, options);
|
||||||
|
|
|
||||||
|
|
@ -52,46 +52,6 @@
|
||||||
* @extends {foundry.applications.ux.ContextMenu}
|
* @extends {foundry.applications.ux.ContextMenu}
|
||||||
*/
|
*/
|
||||||
export default class DHContextMenu extends foundry.applications.ux.ContextMenu {
|
export default class DHContextMenu extends foundry.applications.ux.ContextMenu {
|
||||||
/**
|
|
||||||
* @param {HTMLElement|jQuery} container - The HTML element that contains the context menu targets.
|
|
||||||
* @param {string} selector - A CSS selector which activates the context menu.
|
|
||||||
* @param {ContextMenuEntry[]} menuItems - An Array of entries to display in the menu
|
|
||||||
* @param {ContextMenuOptions} [options] - Additional options to configure the context menu.
|
|
||||||
*/
|
|
||||||
constructor(container, selector, menuItems, options) {
|
|
||||||
super(container, selector, menuItems, options);
|
|
||||||
|
|
||||||
/** @deprecated since v13 until v15 */
|
|
||||||
this.#jQuery = options.jQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to pass jQuery objects or HTMLElement instances to callback.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
#jQuery;
|
|
||||||
|
|
||||||
/**@inheritdoc */
|
|
||||||
activateListeners(menu) {
|
|
||||||
menu.addEventListener('click', this.#onClickItem.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle click events on context menu items.
|
|
||||||
* @param {PointerEvent} event The click event
|
|
||||||
*/
|
|
||||||
#onClickItem(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
const element = event.target.closest('.context-item');
|
|
||||||
if (!element) return;
|
|
||||||
const item = this.menuItems.find(i => i.element === element);
|
|
||||||
item?.onClick(event, this.#jQuery ? $(this.target) : this.target);
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger a context menu event in response to a normal click on a additional options button.
|
* Trigger a context menu event in response to a normal click on a additional options button.
|
||||||
* @param {PointerEvent} event
|
* @param {PointerEvent} event
|
||||||
|
|
|
||||||
|
|
@ -937,11 +937,11 @@ export const activeEffectConditionalTarget = {
|
||||||
export const activeEffectConditionalType = {
|
export const activeEffectConditionalType = {
|
||||||
attribute: {
|
attribute: {
|
||||||
id: 'attribute',
|
id: 'attribute',
|
||||||
label: 'Attribute'
|
label: 'DAGGERHEART.GENERAL.Attribute.single'
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
id: 'status',
|
id: 'status',
|
||||||
label: 'Status'
|
label: 'DAGGERHEART.GENERAL.status'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,10 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel {
|
||||||
img: 'icons/magic/life/heart-cross-blue.webp',
|
img: 'icons/magic/life/heart-cross-blue.webp',
|
||||||
description: '',
|
description: '',
|
||||||
statuses: [],
|
statuses: [],
|
||||||
changes: [],
|
|
||||||
system: {
|
system: {
|
||||||
|
changes: [],
|
||||||
|
conditionals: [],
|
||||||
|
duration: { type: '', description: '' },
|
||||||
rangeDependence: {
|
rangeDependence: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
type: CONFIG.DH.GENERAL.rangeInclusion.withinRange.id,
|
type: CONFIG.DH.GENERAL.rangeInclusion.withinRange.id,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.conditional-container {
|
.conditional-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -45,7 +46,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group.not-visible {
|
.form-group {
|
||||||
|
&.vertical {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
label {
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.not-visible {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,17 @@
|
||||||
<div class="conditionals-container">
|
<div class="conditionals-container">
|
||||||
<div class="conditional-container">
|
<div class="conditional-container">
|
||||||
{{!-- {{formGroup ../systemFields.conditionals.element.fields.target value=conditional.target name=(concat "system.conditionals." index ".target") localize=true }} --}}
|
{{!-- {{formGroup ../systemFields.conditionals.element.fields.target value=conditional.target name=(concat "system.conditionals." index ".target") localize=true }} --}}
|
||||||
{{formGroup ../systemFields.conditionals.element.fields.type value=conditional.type name=(concat "system.conditionals." index ".type") localize=true }}
|
<div class="form-group vertical">
|
||||||
|
<label>{{localize "DAGGERHEART.GENERAL.type"}}</label>
|
||||||
|
|
||||||
<div class="form-group status-select {{#unless (eq conditional.type 'status')}}not-visible{{/unless}}">
|
<div class="form-fields">
|
||||||
|
<select name="{{concat "system.conditionals." index ".type"}}">
|
||||||
|
{{selectOptions ../conditionalTypes selected=conditional.type labelAttr="label" valueAttr="id" blank="" localize=true}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group vertical status-select {{#unless (eq conditional.type 'status')}}not-visible{{/unless}}">
|
||||||
<label>{{localize "EFFECT.FIELDS.changes.element.key.label"}}</label>
|
<label>{{localize "EFFECT.FIELDS.changes.element.key.label"}}</label>
|
||||||
|
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
|
|
@ -20,7 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group attribute-auto {{#unless (eq conditional.type 'attribute')}}not-visible{{/unless}}">
|
<div class="form-group vertical attribute-auto {{#unless (eq conditional.type 'attribute')}}not-visible{{/unless}}">
|
||||||
<label>{{localize "EFFECT.FIELDS.changes.element.key.label"}}</label>
|
<label>{{localize "EFFECT.FIELDS.changes.element.key.label"}}</label>
|
||||||
|
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
|
|
@ -28,7 +36,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group value {{#unless conditional.usesValue}}not-visible{{/unless}}">
|
<div class="form-group vertical value {{#unless conditional.usesValue}}not-visible{{/unless}}">
|
||||||
<label>{{localize "EFFECT.FIELDS.changes.element.value.label"}}</label>
|
<label>{{localize "EFFECT.FIELDS.changes.element.value.label"}}</label>
|
||||||
|
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
|
|
@ -36,7 +44,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group comparator {{#unless conditional.usesComparator}}not-visible{{/unless}}">
|
<div class="form-group vertical comparator {{#unless conditional.usesComparator}}not-visible{{/unless}}">
|
||||||
<label>{{localize "DAGGERHEART.GENERAL.comparator"}}</label>
|
<label>{{localize "DAGGERHEART.GENERAL.comparator"}}</label>
|
||||||
|
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue