Add multiple conditions handler + update Bare Bones domain card

This commit is contained in:
Dapoolp 2025-09-02 16:39:02 +02:00
parent af3a415e56
commit 4a63836c0d
8 changed files with 213 additions and 38 deletions

View file

@ -1935,6 +1935,7 @@
},
"actorName": "Actor Name",
"amount": "Amount",
"and": "AND",
"any": "Any",
"armor": "Armor",
"armors": "Armors",
@ -1947,9 +1948,12 @@
"bonus": "Bonus",
"burden": "Burden",
"conditional": {
"label": "Condition",
"hint": "(Optionnal) Set a condition that need to be verified to apply effects below.",
"notMet": "Condition Not Met"
"label": {
"single": "Condition",
"plural": "Conditions"
},
"hint": "(Optionnal) Set one or more conditions that need to be verified to apply effects below.",
"notMet": "Conditions Not Met"
},
"continue": "Continue",
"criticalSuccess": "Critical Success",
@ -2014,6 +2018,7 @@
"newCategory": "New Category",
"none": "None",
"noTarget": "No current target",
"or": "OR",
"partner": "Partner",
"player": {
"single": "Player",

View file

@ -20,7 +20,12 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
}
static DEFAULT_OPTIONS = {
classes: ['daggerheart', 'sheet', 'dh-style']
classes: ['daggerheart', 'sheet', 'dh-style'],
actions: {
addCondition: DhActiveEffectConfig.#onAddCondition,
deleteCondition: DhActiveEffectConfig.#onDeleteCondition,
setAndOr: DhActiveEffectConfig.#setAndOr
}
};
static PARTS = {
@ -115,4 +120,46 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
return partContext;
}
/* ----------------------------------------- */
/**
* Add a new condition to the effect's conditions array.
* @this {DhActiveEffectConfig}
* @type {ApplicationClickAction}
*/
static async #onAddCondition() {
const submitData = this._processFormData(null, this.form, new foundry.applications.ux.FormDataExtended(this.form));
const conditions = Object.values(submitData.system.conditional?.condition ?? {});
conditions.push({});
return this.submit({updateData: {'system.conditional.condition': conditions}});
}
/* ----------------------------------------- */
/**
* Add a new condition to the effect's conditions array.
* @this {DhActiveEffectConfig}
* @type {ApplicationClickAction}
*/
static async #onDeleteCondition(event) {
const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form));
const conditions = Object.values(submitData.system.conditional.condition ?? {});
const row = event.target.closest("li");
const index = Number(row.dataset.index) || 0;
conditions.splice(index, 1);
return this.submit({updateData: {'system.conditional.condition': conditions}});
}
/* ----------------------------------------- */
/**
* Add a new condition to the effect's conditions array.
* @this {DhActiveEffectConfig}
* @type {ApplicationClickAction}
*/
static async #setAndOr(event) {
const value = event.target.dataset.value;
return this.submit({updateData: {'system.conditional.andOr': value === 'true'}});
}
}

View file

@ -4,10 +4,15 @@ export default class BaseEffect extends foundry.abstract.TypeDataModel {
return {
conditional: new fields.SchemaField({
field: new fields.StringField({required: true, nullable: true}),
operator: new fields.StringField({required: true, choices: CONFIG.DH.EFFECTS.conditionalTypes(), initial: 'equals'}),
value: new fields.StringField({required: true}),
negate: new fields.BooleanField({initial: false})
andOr: new fields.BooleanField({ initial: true }),
condition: new fields.ArrayField(
new fields.SchemaField({
field: new fields.StringField({required: true, nullable: true}),
operator: new fields.StringField({required: true, choices: CONFIG.DH.EFFECTS.conditionalTypes(), initial: 'equals'}),
value: new fields.StringField({required: true}),
negate: new fields.BooleanField({initial: false})
})
)
}),
rangeDependence: new fields.SchemaField({
enabled: new fields.BooleanField({

View file

@ -112,8 +112,12 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
}
verifyCondition(actor) {
if(!this.system.conditional?.field) return true;
return foundry.applications.ux.SearchFilter.evaluateFilter(actor, this.system.conditional);
if(!this.system.conditional?.condition.length) return true;
return this.system.conditional.condition.filter(c => c.field).map(c => {
if(!isNaN(c.value))
c.value = Number(c.value);
return c;
})[this.system.conditional.andOr ? 'every' : 'some'](c => foundry.applications.ux.SearchFilter.evaluateFilter(actor, c));
}
/**

View file

@ -4,7 +4,7 @@
"type": "domainCard",
"folder": "QpOL7jPbMBzH96qR",
"system": {
"description": "<p class=\"Body-Foundation\">When you choose not to equip armor, you have a base Armor Score of 3 + your Strength and use the following as your base damage thresholds:</p><ul><li class=\"vertical-card-list-found\"><em><strong>Tier 1:</strong></em> 9/19</li><li class=\"vertical-card-list-found\"><em><strong>Tier 2:</strong></em> 11/24</li><li class=\"vertical-card-list-found\"><em><strong>Tier 3:</strong></em> 13/31</li><li class=\"vertical-card-list-found\"><em><strong>Tier 4:</strong></em> 15/38</li></ul><p>Equip the below armor to use Bare Bones.</p><p>@UUID[Compendium.daggerheart.armors.Item.ITAjcigTcUw5pMCN]{Bare Bones}</p>",
"description": "<p class=\"Body-Foundation\">When you choose not to equip armor, you have a base Armor Score of 3 + your Strength and use the following as your base damage thresholds:</p><ul><li class=\"vertical-card-list-found\"><em><strong>Tier 1:</strong></em> 9/19</li><li class=\"vertical-card-list-found\"><em><strong>Tier 2:</strong></em> 11/24</li><li class=\"vertical-card-list-found\"><em><strong>Tier 3:</strong></em> 13/31</li><li class=\"vertical-card-list-found\"><em><strong>Tier 4:</strong></em> 15/38</li></ul>",
"domain": "valor",
"recallCost": 0,
"level": 1,
@ -25,12 +25,83 @@
"exportSource": null,
"coreVersion": "13.347",
"systemId": "daggerheart",
"systemVersion": "1.0.5",
"systemVersion": "1.1.2",
"createdTime": 1754067006722,
"modifiedTime": 1755429823165,
"lastModifiedBy": "VZIeX2YDvX338Zvr"
"modifiedTime": 1756823636026,
"lastModifiedBy": "8iAdslq1c1LfHXVb"
},
"effects": [],
"effects": [
{
"name": "Bare Bones",
"type": "base",
"system": {
"conditional": {
"andOr": true,
"condition": [
{
"field": "system.armor",
"operator": "is_empty",
"value": "",
"negate": false
}
]
},
"rangeDependence": {
"enabled": false,
"type": "withinRange",
"target": "hostile",
"range": "melee"
}
},
"_id": "c8XXojizrnP1IHHK",
"img": "systems/daggerheart/assets/icons/domains/domain-card/valor.png",
"changes": [
{
"key": "system.armorScore",
"mode": 5,
"value": "3 + @system.traits.strength.value",
"priority": 0
},
{
"key": "system.damageThresholds.major",
"mode": 5,
"value": "9 + (@tier -1)*2",
"priority": 0
},
{
"key": "system.damageThresholds.severe",
"mode": 5,
"value": "19 + (@tier - 1) * 5 + max(0, (@tier -2) * 2 )",
"priority": 0
}
],
"disabled": false,
"duration": {
"startTime": null,
"combat": null,
"seconds": null,
"rounds": null,
"turns": null,
"startRound": null,
"startTurn": null
},
"description": "<p>When you choose not to equip armor, you have a base Armor Score of 3 + your Strength and use the following as your base damage thresholds:</p><ul><li class=\"vertical-card-list-found\"><em><strong>Tier 1:</strong></em> 9/19</li><li class=\"vertical-card-list-found\"><em><strong>Tier 2:</strong></em> 11/24</li><li class=\"vertical-card-list-found\"><em><strong>Tier 3:</strong></em> 13/31</li><li class=\"vertical-card-list-found\"><em><strong>Tier 4:</strong></em> 15/38</li></ul>",
"origin": null,
"tint": "#ffffff",
"transfer": true,
"statuses": [],
"sort": 0,
"flags": {},
"_stats": {
"coreVersion": "13.347",
"systemId": "daggerheart",
"systemVersion": "1.1.2",
"createdTime": 1756823269943,
"modifiedTime": 1756823587199,
"lastModifiedBy": "8iAdslq1c1LfHXVb"
}
}
],
"ownership": {
"default": 0,
"MQSznptE5yLT7kj8": 3

View file

@ -530,6 +530,39 @@
font-size: var(--font-size-12);
padding-left: 3px;
}
.double-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
margin-left: auto;
margin-bottom: .5rem;
margin-right: .5rem;
> button {
height: calc(var(--input-height) / 1.5);
min-height: calc(var(--input-height) / 1.5);
font-size: var(--font-size-12);
&:hover {
background-color: light-dark(transparent, #f3c267);
color: light-dark(#18162e, #18162e);
}
&.inactive {
background-color: @medium-red;
}
&:first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&:last-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
}
}
.application.setting.dh-style {

View file

@ -74,13 +74,13 @@ body.game:is(.performance-low, .noblur) {
grid-template-columns: 12fr 7fr 7fr 4fr 1fr;
}
&.conditional {
header, ol {
grid-template-columns: 12fr 7fr 10fr 3fr;
scrollbar-gutter: unset;
overflow: unset;
}
}
// &.conditional {
// header, ol {
// grid-template-columns: 12fr 7fr 10fr 3fr;
// scrollbar-gutter: unset;
// overflow: unset;
// }
// }
}
}
}

View file

@ -1,28 +1,38 @@
<section class="tab changes{{#if tab.active}} active{{/if}}" data-group="{{tab.group}}" data-tab="{{tab.id}}">
<fieldset class="conditional">
<legend>{{localize "DAGGERHEART.GENERAL.conditional.label"}}</legend>
<legend>{{localize "DAGGERHEART.GENERAL.conditional.label.plural"}}</legend>
<p class="hint">{{localize "DAGGERHEART.GENERAL.conditional.hint"}}</p>
<div class="double-buttons">
<button type="button" data-action="setAndOr" data-value="true"{{#unless source.system.conditional.andOr}} class="inactive"{{/unless}}>{{localize 'DAGGERHEART.GENERAL.and'}}</button>
<button type="button" data-action="setAndOr" data-value="false"{{#if source.system.conditional.andOr}} class="inactive"{{/if}}>{{localize 'DAGGERHEART.GENERAL.or'}}</button>
</div>
<header>
<div class="field">{{localize "EFFECT.ChangeKey"}}</div>
<div class="operator">{{localize "EFFECT.ChangeFilter"}}</div>
<div class="value">{{localize "EFFECT.ChangeValue"}}</div>
<div class="negate">{{localize "EFFECT.ChangeNegate"}}</div>
<div class="controls"><a data-action="addCondition"><i class="fa-regular fa-square-plus"></i></a></div>
</header>
<ol>
<li>
<div class="field">
{{formInput document.system.schema.fields.conditional.fields.field value=source.system.conditional.field localize=true }}
</div>
<div class="operator">
{{formInput document.system.schema.fields.conditional.fields.operator value=source.system.conditional.operator localize=true }}
</div>
<div class="value">
{{formInput document.system.schema.fields.conditional.fields.value value=source.system.conditional.value localize=true }}
</div>
<div class="negate">
{{formInput document.system.schema.fields.conditional.fields.negate value=source.system.conditional.negate localize=true }}
</div>
</li>
<ol class="scrollable">
{{#each source.system.conditional.condition as |condition i|}}
{{#with ../document.system.schema.fields.conditional.fields.condition.element.fields as |conditionFields|}}
<li data-index="{{i}}">
<div class="field">
{{formInput conditionFields.field value=condition.field name=(concat "system.conditional.condition." i ".field") localize=true }}
</div>
<div class="operator">
{{formInput conditionFields.operator value=condition.operator name=(concat "system.conditional.condition." i ".operator") localize=true }}
</div>
<div class="value">
{{formInput conditionFields.value value=condition.value name=(concat "system.conditional.condition." i ".value") localize=true }}
</div>
<div class="negate">
{{formInput conditionFields.negate value=condition.negate name=(concat "system.conditional.condition." i ".negate") localize=true }}
</div>
<div class="controls"><a data-action="deleteCondition"><i class="fa-solid fa-trash"></i></a></div>
</li>
{{/with}}
{{/each}}
</ol>
</fieldset>
<fieldset>