mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Merge 7b8b66de39 into 876e496d24
This commit is contained in:
commit
1d4786c341
15 changed files with 485 additions and 61 deletions
17
lang/en.json
17
lang/en.json
|
|
@ -138,6 +138,9 @@
|
|||
"Config": {
|
||||
"rangeDependence": {
|
||||
"title": "Range Dependence"
|
||||
},
|
||||
"conditional": {
|
||||
"title": "Conditional Application"
|
||||
}
|
||||
},
|
||||
"RangeDependance": {
|
||||
|
|
@ -684,6 +687,9 @@
|
|||
}
|
||||
},
|
||||
"CONFIG": {
|
||||
"ActiveEffectConditionalTarget": {
|
||||
"self": "Self"
|
||||
},
|
||||
"ActiveEffectDuration": {
|
||||
"temporary": "Temporary",
|
||||
"act": "Next Spotlight",
|
||||
|
|
@ -1015,6 +1021,13 @@
|
|||
"withinRange": "Within Range",
|
||||
"outsideRange": "Outside Range"
|
||||
},
|
||||
"Comparator": {
|
||||
"eq": "Equals",
|
||||
"gt": "Greater Than",
|
||||
"gte": "Greater Or Equals",
|
||||
"lt": "Lesser Than",
|
||||
"lte": "Lesser Or Equals"
|
||||
},
|
||||
"Condition": {
|
||||
"deathMove": {
|
||||
"name": "Death Move",
|
||||
|
|
@ -2198,7 +2211,8 @@
|
|||
"triggers": "Triggers",
|
||||
"deathMoves": "Deathmoves",
|
||||
"sources": "Sources",
|
||||
"packs": "Packs"
|
||||
"packs": "Packs",
|
||||
"conditionals": "Conditionals"
|
||||
},
|
||||
"Tiers": {
|
||||
"singular": "Tier",
|
||||
|
|
@ -2226,6 +2240,7 @@
|
|||
"basics": "Basics",
|
||||
"bonus": "Bonus",
|
||||
"burden": "Burden",
|
||||
"comparator": "Comparator",
|
||||
"condition": "Condition",
|
||||
"continue": "Continue",
|
||||
"criticalSuccess": "Critical Success",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,11 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['daggerheart', 'sheet', 'dh-style']
|
||||
classes: ['daggerheart', 'sheet', 'dh-style'],
|
||||
actions: {
|
||||
addConditional: DhActiveEffectConfig.#addConditional,
|
||||
removeConditional: DhActiveEffectConfig.#removeConditional
|
||||
}
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
|
|
@ -16,6 +20,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
tabs: { template: 'templates/generic/tab-navigation.hbs' },
|
||||
details: { template: 'systems/daggerheart/templates/sheets/activeEffect/details.hbs', scrollable: [''] },
|
||||
settings: { template: 'systems/daggerheart/templates/sheets/activeEffect/settings.hbs' },
|
||||
conditionals: { template: 'systems/daggerheart/templates/sheets/activeEffect/conditionals.hbs' },
|
||||
changes: {
|
||||
template: 'systems/daggerheart/templates/sheets/activeEffect/changes.hbs',
|
||||
templates: ['systems/daggerheart/templates/sheets/activeEffect/change.hbs'],
|
||||
|
|
@ -29,6 +34,11 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
tabs: [
|
||||
{ id: 'details', icon: 'fa-solid fa-book' },
|
||||
{ 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' }
|
||||
],
|
||||
initial: 'details',
|
||||
|
|
@ -185,6 +195,16 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
group: CONST.ACTIVE_EFFECT_TIME_DURATION_UNITS.includes(value) ? groups.time : groups.combat
|
||||
}));
|
||||
break;
|
||||
case 'conditionals':
|
||||
partContext.conditionals = this.document.system.conditionals.map(conditional => ({
|
||||
...conditional,
|
||||
...game.system.api.data.activeEffects.EffectConditional.getConditionalFieldUseage(conditional.type)
|
||||
}));
|
||||
partContext.statusChoices = Object.values(CONFIG.statusEffects).map(x => ({
|
||||
id: x.id,
|
||||
label: x.name
|
||||
}));
|
||||
break;
|
||||
case 'changes':
|
||||
const fields = this.document.system.schema.fields.changes.element.fields;
|
||||
partContext.changes = await Promise.all(
|
||||
|
|
@ -226,6 +246,21 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
);
|
||||
}
|
||||
|
||||
static #addConditional() {
|
||||
const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form));
|
||||
const conditionals = Object.values(submitData.system?.conditionals ?? {});
|
||||
conditionals.push(this.document.system.schema.fields.conditionals.element.getInitialValue());
|
||||
return this.submit({ updateData: { system: { conditionals } } });
|
||||
}
|
||||
|
||||
static async #removeConditional(_event, button) {
|
||||
const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form));
|
||||
const conditionals = Object.values(submitData.system.conditionals);
|
||||
const index = Number(button.dataset.index) || 0;
|
||||
conditionals.splice(index, 1);
|
||||
return this.submit({ updateData: { system: { conditionals: conditionals } } });
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
_onChangeForm(_formConfig, event) {
|
||||
if (foundry.utils.isElementInstanceOf(event.target, 'select') && event.target.name === 'system.duration.type') {
|
||||
|
|
@ -237,6 +272,35 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
|
|||
if (event.target.value === 'temporary') durationDescription.classList.add('visible');
|
||||
else durationDescription.classList.remove('visible');
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
|
|
|
|||
|
|
@ -917,3 +917,48 @@ export const activeEffectDurations = {
|
|||
label: 'DAGGERHEART.CONFIG.ActiveEffectDuration.custom'
|
||||
}
|
||||
};
|
||||
|
||||
export const activeEffectConditionalTarget = {
|
||||
self: {
|
||||
id: 'self',
|
||||
label: 'DAGGERHEART.CONFIG.ActiveEffectConditionalTarget.self'
|
||||
}
|
||||
// target: {
|
||||
// id: 'target',
|
||||
// label: 'DAGGERHEART.CONFIG.ActiveEffectConditionalTarget.target'
|
||||
// }
|
||||
};
|
||||
|
||||
export const activeEffectConditionalType = {
|
||||
attribute: {
|
||||
id: 'attribute',
|
||||
label: 'Attribute'
|
||||
},
|
||||
status: {
|
||||
id: 'status',
|
||||
label: 'Status'
|
||||
}
|
||||
};
|
||||
|
||||
export const comparator = {
|
||||
eq: {
|
||||
id: 'eq',
|
||||
label: 'DAGGERHEART.CONFIG.Comparator.eq'
|
||||
},
|
||||
gt: {
|
||||
id: 'gt',
|
||||
label: 'DAGGERHEART.CONFIG.Comparator.gt'
|
||||
},
|
||||
gte: {
|
||||
id: 'gte',
|
||||
label: 'DAGGERHEART.CONFIG.Comparator.gte'
|
||||
},
|
||||
lt: {
|
||||
id: 'lt',
|
||||
label: 'DAGGERHEART.CONFIG.Comparator.lt'
|
||||
},
|
||||
lte: {
|
||||
id: 'lte',
|
||||
label: 'DAGGERHEART.CONFIG.Comparator.lte'
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import BaseEffect from './baseEffect.mjs';
|
||||
import BeastformEffect from './beastformEffect.mjs';
|
||||
import HordeEffect from './hordeEffect.mjs';
|
||||
import { EffectConditionals, EffectConditional } from './effectConditional.mjs';
|
||||
|
||||
export { BaseEffect, BeastformEffect, HordeEffect };
|
||||
export { BaseEffect, BeastformEffect, HordeEffect, EffectConditionals, EffectConditional };
|
||||
|
||||
export const config = {
|
||||
base: BaseEffect,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { EffectConditionals } from './effectConditional.mjs';
|
||||
|
||||
/** -- Changes Type Priorities --
|
||||
* - Base Number -
|
||||
* Custom: 0
|
||||
|
|
@ -33,6 +35,7 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel {
|
|||
priority: new fields.NumberField()
|
||||
})
|
||||
),
|
||||
conditionals: new EffectConditionals(),
|
||||
duration: new fields.SchemaField({
|
||||
type: new fields.StringField({
|
||||
choices: CONFIG.DH.GENERAL.activeEffectDurations,
|
||||
|
|
|
|||
82
module/data/activeEffect/effectConditional.mjs
Normal file
82
module/data/activeEffect/effectConditional.mjs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import { compareValues, itemAbleRollParse } from '../../helpers/utils.mjs';
|
||||
|
||||
export class EffectConditionals extends foundry.data.fields.ArrayField {
|
||||
constructor(context) {
|
||||
super(new EffectConditional(), context);
|
||||
}
|
||||
|
||||
static isConditionalSuspended(effect) {
|
||||
const actor =
|
||||
effect.parent.type === 'character'
|
||||
? effect.parent
|
||||
: effect.parent.parent?.type === 'character'
|
||||
? effect.parent.parent
|
||||
: null;
|
||||
if (!actor) return false;
|
||||
|
||||
for (const conditional of effect.system.conditionals) {
|
||||
switch (conditional.type) {
|
||||
case CONFIG.DH.GENERAL.activeEffectConditionalType.status.id:
|
||||
const hasStatus = Array.from(actor.allApplicableEffects()).some(
|
||||
x => !x.disabled && x.statuses.has(conditional.key)
|
||||
);
|
||||
if (!hasStatus) return true;
|
||||
break;
|
||||
case CONFIG.DH.GENERAL.activeEffectConditionalType.attribute.id:
|
||||
const actorValue = foundry.utils.getProperty(actor, conditional.key);
|
||||
const conditionalValue = game.system.api.documents.DhActiveEffect.effectSafeEval(
|
||||
itemAbleRollParse(conditional.value, actor)
|
||||
);
|
||||
if (!compareValues(actorValue, conditionalValue, conditional.comparator)) return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class EffectConditional extends foundry.data.fields.SchemaField {
|
||||
constructor(context) {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
const schema = {
|
||||
target: new fields.StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.activeEffectConditionalTarget,
|
||||
initial: CONFIG.DH.GENERAL.activeEffectConditionalTarget.self.id,
|
||||
label: 'DAGGERHEART.GENERAL.Target.single'
|
||||
}),
|
||||
type: new fields.StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.activeEffectConditionalType,
|
||||
initial: CONFIG.DH.GENERAL.activeEffectConditionalType.status.id,
|
||||
label: 'DAGGERHEART.GENERAL.type'
|
||||
}),
|
||||
key: new fields.StringField({ required: true, label: 'EFFECT.FIELDS.changes.element.key.label' }),
|
||||
value: new fields.StringField({ nullable: true, label: 'EFFECT.FIELDS.changes.element.value.label' }),
|
||||
comparator: new fields.StringField({
|
||||
choices: CONFIG.DH.GENERAL.comparator,
|
||||
initial: CONFIG.DH.GENERAL.comparator.eq.id,
|
||||
label: 'DAGGERHEART.GENERAL.comparator'
|
||||
})
|
||||
};
|
||||
|
||||
super(schema, context);
|
||||
}
|
||||
|
||||
static getConditionalFieldUseage(conditionalType) {
|
||||
let usesValue = false;
|
||||
let usesComparator = false;
|
||||
|
||||
if ([CONFIG.DH.GENERAL.activeEffectConditionalType.attribute.id].includes(conditionalType)) {
|
||||
usesValue = true;
|
||||
usesComparator = true;
|
||||
}
|
||||
|
||||
return {
|
||||
usesValue,
|
||||
usesComparator
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,9 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
|
||||
/**@override */
|
||||
get isSuppressed() {
|
||||
const conditionalSuspended = game.system.api.data.activeEffects.EffectConditionals.isConditionalSuspended(this);
|
||||
if (conditionalSuspended) return true;
|
||||
|
||||
// If this is a copied effect from an attachment, never suppress it
|
||||
// (These effects have attachmentSource metadata)
|
||||
if (this.flags?.daggerheart?.attachmentSource) {
|
||||
|
|
|
|||
|
|
@ -538,7 +538,7 @@ export function getIconVisibleActiveEffects(effects) {
|
|||
const alwaysShown = effect.showIcon === CONST.ACTIVE_EFFECT_SHOW_ICON.ALWAYS;
|
||||
const conditionalShown = effect.showIcon === CONST.ACTIVE_EFFECT_SHOW_ICON.CONDITIONAL && !effect.transfer; // TODO: system specific logic
|
||||
|
||||
return !effect.disabled && (alwaysShown || conditionalShown);
|
||||
return !effect.active && (alwaysShown || conditionalShown);
|
||||
});
|
||||
}
|
||||
export async function getFeaturesHTMLData(features) {
|
||||
|
|
@ -603,6 +603,28 @@ export function calculateExpectedValue(formulaOrTerms) {
|
|||
return terms.reduce((r, t) => r + (t.bonus ?? 0) + (t.diceQuantity ? (t.diceQuantity * (t.faces + 1)) / 2 : 0), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Number} valA The number being compared to a second one
|
||||
* @param {Number} valB The number the first is being compared to
|
||||
* @param {Comparator} comparator The type of comparison
|
||||
* @returns { Boolean } Whether valA passes the comparison
|
||||
*/
|
||||
export function compareValues(valA, valB, comparator) {
|
||||
switch (comparator) {
|
||||
case CONFIG.DH.GENERAL.comparator.eq.id:
|
||||
return valA === valB;
|
||||
case CONFIG.DH.GENERAL.comparator.gt.id:
|
||||
return valA > valB;
|
||||
case CONFIG.DH.GENERAL.comparator.gte.id:
|
||||
return valA >= valB;
|
||||
case CONFIG.DH.GENERAL.comparator.lt.id:
|
||||
return valA < valB;
|
||||
case CONFIG.DH.GENERAL.comparator.lte.id:
|
||||
return valA <= valB;
|
||||
}
|
||||
}
|
||||
|
||||
export function parseRallyDice(value, effect) {
|
||||
const legacyStartsWithPrefix = value.toLowerCase().startsWith('d');
|
||||
const workingValue = legacyStartsWithPrefix ? value.slice(1) : value;
|
||||
|
|
|
|||
|
|
@ -28,27 +28,36 @@
|
|||
"type": "withinRange",
|
||||
"target": "hostile",
|
||||
"range": "melee"
|
||||
}
|
||||
},
|
||||
"changes": [
|
||||
{
|
||||
"key": "system.rules.damageReduction.thresholdImmunities.minor",
|
||||
"value": 1,
|
||||
"priority": null,
|
||||
"type": "override"
|
||||
}
|
||||
],
|
||||
"duration": {
|
||||
"type": ""
|
||||
},
|
||||
"conditionals": [
|
||||
{
|
||||
"type": "attribute",
|
||||
"key": "system.resources.hitPoints.value",
|
||||
"value": "@system.resources.hitPoints.max - 2",
|
||||
"comparator": "gte",
|
||||
"target": "self"
|
||||
}
|
||||
]
|
||||
},
|
||||
"_id": "UJTsJlnhi5Zi0XQ2",
|
||||
"img": "systems/daggerheart/assets/icons/domains/domain-card/bone.png",
|
||||
"changes": [
|
||||
{
|
||||
"key": "system.rules.damageReduction.thresholdImmunities.minor",
|
||||
"mode": 5,
|
||||
"value": "1",
|
||||
"priority": null
|
||||
}
|
||||
],
|
||||
"disabled": true,
|
||||
"disabled": false,
|
||||
"duration": {
|
||||
"startTime": null,
|
||||
"combat": null,
|
||||
"seconds": null,
|
||||
"rounds": null,
|
||||
"turns": null,
|
||||
"startRound": null,
|
||||
"startTurn": null
|
||||
"value": null,
|
||||
"units": "seconds",
|
||||
"expiry": null,
|
||||
"expired": false
|
||||
},
|
||||
"description": "<p class=\"Body\">When you have 2 or fewer Hit Points unmarked, you don’t take Minor damage.</p>",
|
||||
"origin": null,
|
||||
|
|
@ -60,6 +69,16 @@
|
|||
"_stats": {
|
||||
"compendiumSource": null
|
||||
},
|
||||
"start": {
|
||||
"time": 0,
|
||||
"combat": null,
|
||||
"combatant": null,
|
||||
"initiative": null,
|
||||
"round": null,
|
||||
"turn": null
|
||||
},
|
||||
"showIcon": 1,
|
||||
"folder": null,
|
||||
"_key": "!items.effects!zbxPl81kbWEegKQN.UJTsJlnhi5Zi0XQ2"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -30,31 +30,40 @@
|
|||
"type": "withinRange",
|
||||
"target": "hostile",
|
||||
"range": "melee"
|
||||
}
|
||||
},
|
||||
"changes": [
|
||||
{
|
||||
"key": "system.bonuses.damage.physical.bonus",
|
||||
"mode": 2,
|
||||
"value": "@system.levelData.level.current",
|
||||
"priority": null
|
||||
},
|
||||
{
|
||||
"key": "system.bonuses.damage.magical.bonus",
|
||||
"mode": 2,
|
||||
"value": "@system.levelData.level.current",
|
||||
"priority": null
|
||||
}
|
||||
],
|
||||
"disabled": true,
|
||||
"changes": [
|
||||
{
|
||||
"key": "system.bonuses.damage.physical.bonus",
|
||||
"value": "@system.levelData.level.current",
|
||||
"priority": null,
|
||||
"type": "add"
|
||||
},
|
||||
{
|
||||
"key": "system.bonuses.damage.magical.bonus",
|
||||
"value": "@system.levelData.level.current",
|
||||
"priority": null,
|
||||
"type": "add"
|
||||
}
|
||||
],
|
||||
"duration": {
|
||||
"type": ""
|
||||
},
|
||||
"conditionals": [
|
||||
{
|
||||
"type": "status",
|
||||
"key": "vulnerable",
|
||||
"value": "",
|
||||
"comparator": "eq",
|
||||
"target": "self"
|
||||
}
|
||||
]
|
||||
},
|
||||
"disabled": false,
|
||||
"duration": {
|
||||
"startTime": null,
|
||||
"combat": null,
|
||||
"seconds": null,
|
||||
"rounds": null,
|
||||
"turns": null,
|
||||
"startRound": null,
|
||||
"startTurn": null
|
||||
"value": null,
|
||||
"units": "seconds",
|
||||
"expiry": null,
|
||||
"expired": false
|
||||
},
|
||||
"description": "<p>While you're Vulnerable, add your level to your damage rolls.</p>",
|
||||
"tint": "#ffffff",
|
||||
|
|
@ -64,6 +73,16 @@
|
|||
"_stats": {
|
||||
"compendiumSource": null
|
||||
},
|
||||
"start": {
|
||||
"time": 0,
|
||||
"combat": null,
|
||||
"combatant": null,
|
||||
"initiative": null,
|
||||
"round": null,
|
||||
"turn": null
|
||||
},
|
||||
"showIcon": 1,
|
||||
"folder": null,
|
||||
"_key": "!items.effects!uByM34yQlw38yf1V.HMx9uZ54mvMiH95x"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -26,27 +26,36 @@
|
|||
"type": "withinRange",
|
||||
"target": "hostile",
|
||||
"range": "melee"
|
||||
}
|
||||
},
|
||||
"changes": [
|
||||
{
|
||||
"key": "system.evasion",
|
||||
"value": "@system.proficiency",
|
||||
"priority": 21,
|
||||
"type": "add"
|
||||
}
|
||||
],
|
||||
"duration": {
|
||||
"type": ""
|
||||
},
|
||||
"conditionals": [
|
||||
{
|
||||
"type": "attribute",
|
||||
"key": "system.resources.hope.value",
|
||||
"value": "2",
|
||||
"comparator": "gte",
|
||||
"target": "self"
|
||||
}
|
||||
]
|
||||
},
|
||||
"_id": "0i7GVOvjH6bK5AUM",
|
||||
"img": "icons/magic/defensive/barrier-shield-dome-blue-purple.webp",
|
||||
"changes": [
|
||||
{
|
||||
"key": "system.evasion",
|
||||
"mode": 2,
|
||||
"value": "@system.proficiency",
|
||||
"priority": 21
|
||||
}
|
||||
],
|
||||
"disabled": false,
|
||||
"duration": {
|
||||
"startTime": null,
|
||||
"combat": null,
|
||||
"seconds": null,
|
||||
"rounds": null,
|
||||
"turns": null,
|
||||
"startRound": null,
|
||||
"startTurn": null
|
||||
"value": null,
|
||||
"units": "seconds",
|
||||
"expiry": null,
|
||||
"expired": false
|
||||
},
|
||||
"description": "<p>While you have at least 2 Hope, you add your Proficiency to your Evasion.</p>",
|
||||
"origin": null,
|
||||
|
|
@ -58,6 +67,16 @@
|
|||
"_stats": {
|
||||
"compendiumSource": null
|
||||
},
|
||||
"start": {
|
||||
"time": 0,
|
||||
"combat": null,
|
||||
"combatant": null,
|
||||
"initiative": null,
|
||||
"round": null,
|
||||
"turn": null
|
||||
},
|
||||
"showIcon": 1,
|
||||
"folder": null,
|
||||
"_key": "!items.effects!oirsCnN66GOlK3Fa.0i7GVOvjH6bK5AUM"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -16,7 +16,72 @@
|
|||
"artist": ""
|
||||
}
|
||||
},
|
||||
"effects": [],
|
||||
"effects": [
|
||||
{
|
||||
"name": "Rise To The Challenge",
|
||||
"type": "base",
|
||||
"system": {
|
||||
"changes": [
|
||||
{
|
||||
"key": "system.rules.dualityRoll.defaultHopeDice",
|
||||
"type": "upgrade",
|
||||
"value": 20,
|
||||
"priority": null,
|
||||
"phase": "initial"
|
||||
}
|
||||
],
|
||||
"conditionals": [
|
||||
{
|
||||
"type": "attribute",
|
||||
"key": "system.resources.hitPoints.value",
|
||||
"value": "@system.resources.hitPoints.max - 2",
|
||||
"comparator": "gte",
|
||||
"target": "self"
|
||||
}
|
||||
],
|
||||
"duration": {
|
||||
"description": "",
|
||||
"type": ""
|
||||
},
|
||||
"rangeDependence": {
|
||||
"enabled": false,
|
||||
"type": "withinRange",
|
||||
"target": "hostile",
|
||||
"range": "melee"
|
||||
}
|
||||
},
|
||||
"_id": "MA744uJrGMQCDywg",
|
||||
"img": "icons/magic/control/debuff-energy-hold-levitate-yellow.webp",
|
||||
"disabled": false,
|
||||
"start": {
|
||||
"time": 0,
|
||||
"combat": null,
|
||||
"combatant": null,
|
||||
"initiative": null,
|
||||
"round": null,
|
||||
"turn": null
|
||||
},
|
||||
"duration": {
|
||||
"value": null,
|
||||
"units": "seconds",
|
||||
"expiry": null,
|
||||
"expired": false
|
||||
},
|
||||
"description": "<p>While you have 2 or fewer Hit Points unmarked, you can roll a d20 as your Hope Die.</p>",
|
||||
"origin": null,
|
||||
"tint": "#ffffff",
|
||||
"transfer": true,
|
||||
"statuses": [],
|
||||
"showIcon": 1,
|
||||
"folder": null,
|
||||
"sort": 0,
|
||||
"flags": {},
|
||||
"_stats": {
|
||||
"compendiumSource": null
|
||||
},
|
||||
"_key": "!items.effects!dcutk8RVOJ2sEkO1.MA744uJrGMQCDywg"
|
||||
}
|
||||
],
|
||||
"sort": 0,
|
||||
"ownership": {
|
||||
"default": 0,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
.conditionals-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
.conditional-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.tab.changes {
|
||||
gap: 0;
|
||||
|
||||
|
|
@ -32,4 +44,8 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-group.not-visible {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
50
templates/sheets/activeEffect/conditionals.hbs
Normal file
50
templates/sheets/activeEffect/conditionals.hbs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<section class="tab{{#if tab.active}} active{{/if}}" data-group="{{tab.group}}" data-tab="{{tab.id}}">
|
||||
<button type="button" data-action="addConditional">{{localize "Add Conditional"}}<i class="fa-solid fa-plus"></i></button>
|
||||
|
||||
{{#each conditionals as |conditional index|}}
|
||||
<fieldset class="one-column">
|
||||
<legend><a data-action="removeConditional" data-index="{{index}}"><i class="fa-solid fa-trash"></i></a></legend>
|
||||
|
||||
<div class="conditionals-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.type value=conditional.type name=(concat "system.conditionals." index ".type") localize=true }}
|
||||
|
||||
<div class="form-group status-select {{#unless (eq conditional.type 'status')}}not-visible{{/unless}}">
|
||||
<label>{{localize "EFFECT.FIELDS.changes.element.key.label"}}</label>
|
||||
|
||||
<div class="form-fields">
|
||||
<select name="{{concat "system.conditionals." index ".key"}}">
|
||||
{{selectOptions ../statusChoices selected=conditional.key labelAttr="label" valueAttr="id" blank="" localize=true}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group attribute-auto {{#unless (eq conditional.type 'attribute')}}not-visible{{/unless}}">
|
||||
<label>{{localize "EFFECT.FIELDS.changes.element.key.label"}}</label>
|
||||
|
||||
<div class="form-fields">
|
||||
<input type="text" class="effect-change-input" name="{{concat "system.conditionals." index ".key"}}" value="{{conditional.key}}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group value {{#unless conditional.usesValue}}not-visible{{/unless}}">
|
||||
<label>{{localize "EFFECT.FIELDS.changes.element.value.label"}}</label>
|
||||
|
||||
<div class="form-fields">
|
||||
{{formInput ../systemFields.conditionals.element.fields.value value=conditional.value name=(concat "system.conditionals." index ".value") localize=true }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group comparator {{#unless conditional.usesComparator}}not-visible{{/unless}}">
|
||||
<label>{{localize "DAGGERHEART.GENERAL.comparator"}}</label>
|
||||
|
||||
<div class="form-fields">
|
||||
{{formInput ../systemFields.conditionals.element.fields.comparator value=conditional.comparator name=(concat "system.conditionals." index ".comparator") localize=true }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
{{/each}}
|
||||
</section>
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
{{formGroup systemFields.rangeDependence.fields.target value=source.system.rangeDependence.target localize=true }}
|
||||
{{formGroup systemFields.rangeDependence.fields.range value=source.system.rangeDependence.range localize=true }}
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="one-column">
|
||||
<legend>{{localize "EFFECT.DURATION.Label"}}</legend>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue