Merge branch 'main' into feature/106-items-browser

This commit is contained in:
Dapoolp 2025-08-06 16:30:58 +02:00
commit e5f0ac7d30
41 changed files with 888 additions and 209 deletions

View file

@ -1854,7 +1854,9 @@
"tier1": "Tier 1", "tier1": "Tier 1",
"tier2": "Tier 2", "tier2": "Tier 2",
"tier3": "Tier 3", "tier3": "Tier 3",
"tier4": "tier 4" "tier4": "tier 4",
"domains": "Domains",
"downtime": "Downtime"
}, },
"Tiers": { "Tiers": {
"singular": "Tier", "singular": "Tier",
@ -1887,6 +1889,7 @@
"damageType": "Damage Type", "damageType": "Damage Type",
"description": "Description", "description": "Description",
"difficulty": "Difficulty", "difficulty": "Difficulty",
"downtime": "Downtime",
"dropActorsHere": "Drop Actors here", "dropActorsHere": "Drop Actors here",
"duality": "Duality", "duality": "Duality",
"dualityRoll": "Duality Roll", "dualityRoll": "Duality Roll",
@ -1919,6 +1922,7 @@
"inactiveEffects": "Inactive Effects", "inactiveEffects": "Inactive Effects",
"inventory": "Inventory", "inventory": "Inventory",
"itemResource": "Item Resource", "itemResource": "Item Resource",
"label": "Label",
"level": "Level", "level": "Level",
"levelUp": "Level Up", "levelUp": "Level Up",
"loadout": "Loadout", "loadout": "Loadout",
@ -2137,6 +2141,18 @@
"handfullName": "Handfull Name", "handfullName": "Handfull Name",
"bagName": "Bag Name", "bagName": "Bag Name",
"chestName": "Chest Name" "chestName": "Chest Name"
},
"domains": {
"domainsTitle": "Base Domains",
"homebrewDomains": "Homebrew Domains",
"newDomain": "New Domain",
"newDomainInputTitle": "Create Homebrew Domain",
"newDomainInputLabel": "New Domain Name",
"newDomainInputHint": "This cannot be altered later",
"editDomain": "Active Domain",
"deleteDomain": "Delete Domain",
"deleteDomainText": "Are you sure you want to delete the {name} domain? It will be immediately removed from all Actors in this world where it's currently used. Compendiums are not cleared.",
"duplicateDomain": "There is already a domain with this identification."
} }
}, },
"Menu": { "Menu": {

View file

@ -34,7 +34,7 @@ export default class MulticlassChoiceDialog extends HandlebarsApplicationMixin(A
const context = await super._prepareContext(_options); const context = await super._prepareContext(_options);
context.multiclass = this.multiclass; context.multiclass = this.multiclass;
context.domainChoices = this.multiclass.domains.map(value => { context.domainChoices = this.multiclass.domains.map(value => {
const domain = CONFIG.DH.DOMAIN.domains[value]; const domain = CONFIG.DH.DOMAIN.allDomains()[value];
return { return {
value: value, value: value,
label: game.i18n.localize(domain.label), label: game.i18n.localize(domain.label),

View file

@ -1,6 +1,5 @@
import LevelUpBase from './levelup.mjs'; import LevelUpBase from './levelup.mjs';
import { DhLevelup } from '../../data/levelup.mjs'; import { DhLevelup } from '../../data/levelup.mjs';
import { domains } from '../../config/domainConfig.mjs';
import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs'; import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs';
export default class DhCharacterLevelUp extends LevelUpBase { export default class DhCharacterLevelUp extends LevelUpBase {
@ -113,7 +112,7 @@ export default class DhCharacterLevelUp extends LevelUpBase {
: levelBase; : levelBase;
return game.i18n.format('DAGGERHEART.APPLICATIONS.Levelup.selections.emptyDomainCardHint', { return game.i18n.format('DAGGERHEART.APPLICATIONS.Levelup.selections.emptyDomainCardHint', {
domain: game.i18n.localize(domains[domain.domain].label), domain: game.i18n.localize(CONFIG.DH.DOMAIN.allDomains()[domain.domain].label),
level: levelMax level: levelMax
}); });
}), }),
@ -170,7 +169,7 @@ export default class DhCharacterLevelUp extends LevelUpBase {
uuid: multiclass.uuid, uuid: multiclass.uuid,
domains: domains:
multiclass?.system?.domains.map(key => { multiclass?.system?.domains.map(key => {
const domain = domains[key]; const domain = CONFIG.DH.DOMAIN.allDomains()[key];
const alreadySelected = this.actor.system.class.value.system.domains.includes(key); const alreadySelected = this.actor.system.class.value.system.domains.includes(key);
return { return {
@ -315,7 +314,10 @@ export default class DhCharacterLevelUp extends LevelUpBase {
? { ? {
...multiclassItem.toObject(), ...multiclassItem.toObject(),
domain: checkbox.secondaryData.domain domain: checkbox.secondaryData.domain
? game.i18n.localize(domains[checkbox.secondaryData.domain].label) ? game.i18n.localize(
CONFIG.DH.DOMAIN.allDomains()[checkbox.secondaryData.domain]
.label
)
: null, : null,
subclass: subclass ? subclass.name : null subclass: subclass ? subclass.name : null
} }

View file

@ -1,5 +1,4 @@
import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs'; import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs';
import { domains } from '../../config/domainConfig.mjs';
import { getDeleteKeys, tagifyElement } from '../../helpers/utils.mjs'; import { getDeleteKeys, tagifyElement } from '../../helpers/utils.mjs';
import { ItemBrowser } from '../ui/itemBrowser.mjs'; import { ItemBrowser } from '../ui/itemBrowser.mjs';
@ -23,10 +22,11 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
static DEFAULT_OPTIONS = { static DEFAULT_OPTIONS = {
tag: 'form', tag: 'form',
classes: ['daggerheart', 'levelup'], classes: ['daggerheart', 'dialog', 'dh-style', 'levelup'],
position: { width: 1000, height: 'auto' }, position: { width: 1000, height: 'auto' },
window: { window: {
resizable: true resizable: true,
icon: 'fa-solid fa-arrow-turn-up'
}, },
actions: { actions: {
save: this.save, save: this.save,
@ -48,7 +48,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
static PARTS = { static PARTS = {
tabs: { template: 'systems/daggerheart/templates/levelup/tabs/tab-navigation.hbs' }, tabs: { template: 'systems/daggerheart/templates/levelup/tabs/tab-navigation.hbs' },
advancements: { template: 'systems/daggerheart/templates/levelup/tabs/advancements.hbs' }, advancements: { template: 'systems/daggerheart/templates/levelup/tabs/advancements.hbs' },
selections: { template: 'systems/daggerheart/templates/levelup/tabs/selections.hbs' }, selections: {
template: 'systems/daggerheart/templates/levelup/tabs/selections.hbs',
scrollable: ['.selections']
},
summary: { template: 'systems/daggerheart/templates/levelup/tabs/summary.hbs' }, summary: { template: 'systems/daggerheart/templates/levelup/tabs/summary.hbs' },
footer: { template: 'systems/daggerheart/templates/levelup/tabs/footer.hbs' } footer: { template: 'systems/daggerheart/templates/levelup/tabs/footer.hbs' }
}; };
@ -252,7 +255,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
? { ? {
...multiclassItem.toObject(), ...multiclassItem.toObject(),
domain: checkbox.secondaryData.domain domain: checkbox.secondaryData.domain
? game.i18n.localize(domains[checkbox.secondaryData.domain].label) ? game.i18n.localize(
CONFIG.DH.DOMAIN.allDomains()[checkbox.secondaryData.domain]
.label
)
: null, : null,
subclass: subclass ? subclass.name : null subclass: subclass ? subclass.name : null
} }
@ -356,10 +362,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
experienceIncreaseTagify, experienceIncreaseTagify,
Object.keys(this.actor.system.experiences).reduce((acc, id) => { Object.keys(this.actor.system.experiences).reduce((acc, id) => {
const experience = this.actor.system.experiences[id]; const experience = this.actor.system.experiences[id];
acc[id] = { label: experience.name }; acc.push({ id: id, label: experience.name });
return acc; return acc;
}, {}), }, []),
this.tagifyUpdate('experience').bind(this) this.tagifyUpdate('experience').bind(this)
); );
} }

View file

@ -1,4 +1,5 @@
import { DhHomebrew } from '../../data/settings/_module.mjs'; import { DhHomebrew } from '../../data/settings/_module.mjs';
import { slugify } from '../../helpers/utils.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
export default class DhHomebrewSettings extends HandlebarsApplicationMixin(ApplicationV2) { export default class DhHomebrewSettings extends HandlebarsApplicationMixin(ApplicationV2) {
@ -8,6 +9,10 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
this.settings = new DhHomebrew( this.settings = new DhHomebrew(
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).toObject() game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).toObject()
); );
this.selected = {
domain: null
};
} }
get title() { get title() {
@ -17,7 +22,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
static DEFAULT_OPTIONS = { static DEFAULT_OPTIONS = {
tag: 'form', tag: 'form',
id: 'daggerheart-homebrew-settings', id: 'daggerheart-homebrew-settings',
classes: ['daggerheart', 'dh-style', 'dialog', 'setting'], classes: ['daggerheart', 'dh-style', 'dialog', 'setting', 'homebrew-settings'],
position: { width: '600', height: 'auto' }, position: { width: '600', height: 'auto' },
window: { window: {
icon: 'fa-solid fa-gears' icon: 'fa-solid fa-gears'
@ -27,6 +32,9 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
editItem: this.editItem, editItem: this.editItem,
removeItem: this.removeItem, removeItem: this.removeItem,
resetMoves: this.resetMoves, resetMoves: this.resetMoves,
addDomain: this.addDomain,
toggleSelectedDomain: this.toggleSelectedDomain,
deleteDomain: this.deleteDomain,
save: this.save, save: this.save,
reset: this.reset reset: this.reset
}, },
@ -34,9 +42,19 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
}; };
static PARTS = { static PARTS = {
tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
settings: { template: 'systems/daggerheart/templates/settings/homebrew-settings/settings.hbs' },
domains: { template: 'systems/daggerheart/templates/settings/homebrew-settings/domains.hbs' },
downtime: { template: 'systems/daggerheart/templates/settings/homebrew-settings/downtime.hbs' },
footer: { template: 'systems/daggerheart/templates/settings/homebrew-settings/footer.hbs' }
};
/** @inheritdoc */
static TABS = {
main: { main: {
template: 'systems/daggerheart/templates/settings/homebrew-settings.hbs', tabs: [{ id: 'settings' }, { id: 'domains' }, { id: 'downtime' }],
scrollable: [''] initial: 'settings',
labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
} }
}; };
@ -47,7 +65,26 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
return context; return context;
} }
static async updateData(event, element, formData) { async _preparePartContext(partId, context) {
await super._preparePartContext(partId, context);
switch (partId) {
case 'domains':
const selectedDomain = this.selected.domain ? this.settings.domains[this.selected.domain] : null;
const enrichedDescription = selectedDomain
? await foundry.applications.ux.TextEditor.implementation.enrichHTML(selectedDomain.description)
: null;
if (enrichedDescription !== null) context.selectedDomain = { ...selectedDomain, enrichedDescription };
context.configDomains = CONFIG.DH.DOMAIN.domains;
context.homebrewDomains = this.settings.domains;
break;
}
return context;
}
static async updateData(_event, _element, formData) {
const updatedSettings = foundry.utils.expandObject(formData.object); const updatedSettings = foundry.utils.expandObject(formData.object);
await this.settings.updateSource({ await this.settings.updateSource({
@ -163,6 +200,107 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
this.render(); this.render();
} }
static async addDomain(event) {
event.preventDefault();
const content = new foundry.data.fields.StringField({
label: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.newDomainInputLabel'),
hint: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.newDomainInputHint'),
required: true
}).toFormGroup({}, { name: 'domainName', localize: true }).outerHTML;
async function callback(_, button) {
const domainName = button.form.elements.domainName.value;
if (!domainName) return;
const newSlug = slugify(domainName);
const existingDomains = [
...Object.values(this.settings.domains),
...Object.values(CONFIG.DH.DOMAIN.domains)
];
if (existingDomains.find(x => slugify(game.i18n.localize(x.label)) === newSlug)) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.duplicateDomain'));
return;
}
this.settings.updateSource({
[`domains.${newSlug}`]: {
id: newSlug,
label: domainName,
src: 'icons/svg/portal.svg'
}
});
this.selected.domain = newSlug;
this.render();
}
foundry.applications.api.DialogV2.prompt({
content: content,
rejectClose: false,
modal: true,
ok: { callback: callback.bind(this) },
window: {
title: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.newDomainInputTitle')
},
position: { width: 400 }
});
}
static toggleSelectedDomain(_, target) {
this.selected.domain = this.selected.domain === target.id ? null : target.id;
this.render();
}
static async deleteDomain() {
const confirmed = await foundry.applications.api.DialogV2.confirm({
window: {
title: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.deleteDomain')
},
content: game.i18n.format('DAGGERHEART.SETTINGS.Homebrew.domains.deleteDomainText', {
name: this.settings.domains[this.selected.domain].label
})
});
if (!confirmed) return;
await this.settings.updateSource({
[`domains.-=${this.selected.domain}`]: null
});
const currentSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew);
if (currentSettings.domains[this.selected.domain]) {
await currentSettings.updateSource({ [`domains.-=${this.selected.domain}`]: null });
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, currentSettings);
}
const updateClasses = game.items.filter(x => x.type === 'class');
for (let actor of game.actors) {
updateClasses.push(...actor.items.filter(x => x.type === 'class'));
}
for (let c of updateClasses) {
if (c.system.domains.includes(this.selected.domain)) {
const newDomains =
c.system.domains.length === 1
? [CONFIG.DH.DOMAIN.domains.arcana.id]
: c.system.domains.filter(x => x !== this.selected.domain);
await c.update({ 'system.domains': newDomains });
}
c.sheet.render();
}
const updateDomainCards = game.items.filter(
x => x.type === 'domainCard' && x.system.domain === this.selected.domain
);
for (let d of updateDomainCards) {
await d.update({ 'system.domain': CONFIG.DH.DOMAIN.domains.arcana.id });
d.sheet.render();
}
this.selected.domain = null;
this.render();
}
static async save() { static async save() {
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, this.settings.toObject()); await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, this.settings.toObject());
this.close(); this.close();
@ -200,4 +338,13 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
} }
return obj; return obj;
} }
_getTabs(tabs) {
for (const v of Object.values(tabs)) {
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
v.cssClass = v.active ? 'active' : '';
}
return tabs;
}
} }

View file

@ -14,7 +14,7 @@ export default class ClassSheet extends DHBaseItemSheet {
tagifyConfigs: [ tagifyConfigs: [
{ {
selector: '.domain-input', selector: '.domain-input',
options: () => CONFIG.DH.DOMAIN.domains, options: () => CONFIG.DH.DOMAIN.orderedDomains(),
callback: ClassSheet.#onDomainSelect, callback: ClassSheet.#onDomainSelect,
tagifyOptions: { tagifyOptions: {
maxTags: () => game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxDomains maxTags: () => game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxDomains

View file

@ -34,4 +34,12 @@ export default class DomainCardSheet extends DHBaseItemSheet {
scrollable: ['.effects'] scrollable: ['.effects']
} }
}; };
async _prepareContext(options) {
const context = await super._prepareContext(options);
context.domain = CONFIG.DH.DOMAIN.allDomains()[this.document.system.domain];
context.domainChoices = CONFIG.DH.DOMAIN.orderedDomains();
return context;
}
} }

View file

@ -219,7 +219,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu {
} }
})); }));
const domainFilter = Object.values(CONFIG.DH.DOMAIN.domains).map(({ id, label }) => ({ const domainFilter = Object.values(CONFIG.DH.DOMAIN.allDomains()).map(({ id, label }) => ({
group: game.i18n.localize('DAGGERHEART.GENERAL.Domain.single'), group: game.i18n.localize('DAGGERHEART.GENERAL.Domain.single'),
name: game.i18n.localize(label), name: game.i18n.localize(label),
filter: { filter: {

View file

@ -55,8 +55,17 @@ export const domains = {
} }
}; };
export const classDomainMap = { export const allDomains = () => ({
rogue: [domains.midnight, domains.grace] ...domains,
...game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).domains
});
export const orderedDomains = () => {
const all = {
...domains,
...game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).domains
};
return Object.values(all).sort((a, b) => game.i18n.localize(a.label).localeCompare(game.i18n.localize(b.label)));
}; };
export const subclassMap = { export const subclassMap = {

View file

@ -18,7 +18,7 @@ export default class DHDomainCard extends BaseDataItem {
return { return {
...super.defineSchema(), ...super.defineSchema(),
domain: new fields.StringField({ domain: new fields.StringField({
choices: CONFIG.DH.DOMAIN.domains, choices: CONFIG.DH.DOMAIN.allDomains,
required: true, required: true,
initial: CONFIG.DH.DOMAIN.domains.arcana.id initial: CONFIG.DH.DOMAIN.domains.arcana.id
}), }),

View file

@ -2,8 +2,6 @@ import { defaultRestOptions } from '../../config/generalConfig.mjs';
import { ActionsField } from '../fields/actionField.mjs'; import { ActionsField } from '../fields/actionField.mjs';
export default class DhHomebrew extends foundry.abstract.DataModel { export default class DhHomebrew extends foundry.abstract.DataModel {
static LOCALIZATION_PREFIXES = ['DAGGERHEART.SETTINGS.Homebrew']; // Doesn't work for some reason
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
@ -98,7 +96,19 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
{ initial: defaultRestOptions.shortRest() } { initial: defaultRestOptions.shortRest() }
) )
}) })
}) }),
domains: new fields.TypedObjectField(
new fields.SchemaField({
id: new fields.StringField({ required: true }),
label: new fields.StringField({ required: true, initial: '', label: 'DAGGERHEART.GENERAL.label' }),
src: new fields.FilePathField({
categories: ['IMAGE'],
base64: false,
label: 'Image'
}),
description: new fields.HTMLField()
})
)
}; };
} }
} }

View file

@ -83,15 +83,16 @@ export const chunkify = (array, chunkSize, mappingFunc) => {
return chunkifiedArray; return chunkifiedArray;
}; };
export const tagifyElement = (element, options, onChange, tagifyOptions = {}) => { export const tagifyElement = (element, baseOptions, onChange, tagifyOptions = {}) => {
const { maxTags } = tagifyOptions; const { maxTags } = tagifyOptions;
const options = typeof baseOptions === 'object' ? Object.values(baseOptions) : baseOptions;
const tagifyElement = new Tagify(element, { const tagifyElement = new Tagify(element, {
tagTextProp: 'name', tagTextProp: 'name',
enforceWhitelist: true, enforceWhitelist: true,
whitelist: Object.keys(options).map(key => { whitelist: options.map(option => {
const option = options[key];
return { return {
value: key, value: option.id,
name: game.i18n.localize(option.label), name: game.i18n.localize(option.label),
src: option.src, src: option.src,
description: option.description description: option.description
@ -100,7 +101,7 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) =>
maxTags: typeof maxTags === 'function' ? maxTags() : maxTags, maxTags: typeof maxTags === 'function' ? maxTags() : maxTags,
dropdown: { dropdown: {
mapValueTo: 'name', mapValueTo: 'name',
searchKeys: ['name'], searchKeys: ['value'],
enabled: 0, enabled: 0,
maxItems: 100, maxItems: 100,
closeOnSelect: true, closeOnSelect: true,
@ -369,3 +370,7 @@ export async function createEmbeddedItemWithEffects(actor, baseData, update) {
return doc; return doc;
} }
export const slugify = name => {
return name.toLowerCase().replaceAll(' ', '-').replaceAll('.', '');
};

View file

@ -68,6 +68,7 @@
"description": "<p>A coruscating mass of uncontrollable magic.</p>", "description": "<p>A coruscating mass of uncontrollable magic.</p>",
"attack": { "attack": {
"name": "Warp Blast", "name": "Warp Blast",
"img": "icons/magic/light/beam-rays-magenta.webp",
"roll": { "roll": {
"bonus": 3, "bonus": 3,
"type": "attack" "type": "attack"

View file

@ -19,7 +19,7 @@
"actionType": "action", "actionType": "action",
"cost": [ "cost": [
{ {
"scalable": true, "scalable": false,
"key": "stress", "key": "stress",
"value": 1, "value": 1,
"step": 1, "step": 1,
@ -95,8 +95,8 @@
"systemId": "daggerheart", "systemId": "daggerheart",
"systemVersion": "0.0.1", "systemVersion": "0.0.1",
"createdTime": 1753922784496, "createdTime": 1753922784496,
"modifiedTime": 1754304556054, "modifiedTime": 1754445106667,
"lastModifiedBy": "MQSznptE5yLT7kj8" "lastModifiedBy": "Q9NoTaEarn3VMS6Z"
}, },
"_id": "GRL0cvs96vrTDckZ", "_id": "GRL0cvs96vrTDckZ",
"sort": 3400000, "sort": 3400000,
@ -105,7 +105,7 @@
"name": "Rage Up (1)", "name": "Rage Up (1)",
"img": "systems/daggerheart/assets/icons/domains/domain-card/blade.png", "img": "systems/daggerheart/assets/icons/domains/domain-card/blade.png",
"origin": "Compendium.daggerheart.domains.Item.GRL0cvs96vrTDckZ", "origin": "Compendium.daggerheart.domains.Item.GRL0cvs96vrTDckZ",
"transfer": true, "transfer": false,
"_id": "bq1MhcmoP6Wo5CXF", "_id": "bq1MhcmoP6Wo5CXF",
"type": "base", "type": "base",
"system": { "system": {
@ -118,13 +118,19 @@
}, },
"changes": [ "changes": [
{ {
"key": "system.bonuses.roll.attack.bonus", "key": "system.bonuses.damage.magical.bonus",
"mode": 2,
"value": "2*@system.traits.strength.value",
"priority": null
},
{
"key": "system.bonuses.damage.physical.bonus",
"mode": 2, "mode": 2,
"value": "2*@system.traits.strength.value", "value": "2*@system.traits.strength.value",
"priority": null "priority": null
} }
], ],
"disabled": true, "disabled": false,
"duration": { "duration": {
"startTime": null, "startTime": null,
"combat": null, "combat": null,
@ -147,8 +153,8 @@
"systemId": "daggerheart", "systemId": "daggerheart",
"systemVersion": "0.0.1", "systemVersion": "0.0.1",
"createdTime": 1754246159246, "createdTime": 1754246159246,
"modifiedTime": 1754304575352, "modifiedTime": 1754446417671,
"lastModifiedBy": "MQSznptE5yLT7kj8" "lastModifiedBy": "Q9NoTaEarn3VMS6Z"
}, },
"_key": "!items.effects!GRL0cvs96vrTDckZ.bq1MhcmoP6Wo5CXF" "_key": "!items.effects!GRL0cvs96vrTDckZ.bq1MhcmoP6Wo5CXF"
}, },
@ -156,7 +162,7 @@
"name": "Rage Up (2)", "name": "Rage Up (2)",
"img": "systems/daggerheart/assets/icons/domains/domain-card/blade.png", "img": "systems/daggerheart/assets/icons/domains/domain-card/blade.png",
"origin": "Compendium.daggerheart.domains.Item.GRL0cvs96vrTDckZ", "origin": "Compendium.daggerheart.domains.Item.GRL0cvs96vrTDckZ",
"transfer": true, "transfer": false,
"_id": "t6SIjQxB6UBUJ98f", "_id": "t6SIjQxB6UBUJ98f",
"type": "base", "type": "base",
"system": { "system": {
@ -169,13 +175,19 @@
}, },
"changes": [ "changes": [
{ {
"key": "system.bonuses.roll.attack.bonus", "key": "system.bonuses.damage.magical.bonus",
"mode": 2,
"value": "4*@system.traits.strength.value",
"priority": null
},
{
"key": "system.bonuses.damage.physical.bonus",
"mode": 2, "mode": 2,
"value": "4*@system.traits.strength.value", "value": "4*@system.traits.strength.value",
"priority": null "priority": null
} }
], ],
"disabled": true, "disabled": false,
"duration": { "duration": {
"startTime": null, "startTime": null,
"combat": null, "combat": null,
@ -198,8 +210,8 @@
"systemId": "daggerheart", "systemId": "daggerheart",
"systemVersion": "0.0.1", "systemVersion": "0.0.1",
"createdTime": 1754246675511, "createdTime": 1754246675511,
"modifiedTime": 1754304583724, "modifiedTime": 1754446412834,
"lastModifiedBy": "MQSznptE5yLT7kj8" "lastModifiedBy": "Q9NoTaEarn3VMS6Z"
}, },
"_key": "!items.effects!GRL0cvs96vrTDckZ.t6SIjQxB6UBUJ98f" "_key": "!items.effects!GRL0cvs96vrTDckZ.t6SIjQxB6UBUJ98f"
} }

View file

@ -3,6 +3,7 @@
@import './level-up/sheet.less'; @import './level-up/sheet.less';
@import './level-up/summary-container.less'; @import './level-up/summary-container.less';
@import './level-up/tiers-container.less'; @import './level-up/tiers-container.less';
@import './level-up/footer.less';
@import './resource-dice/sheet.less'; @import './resource-dice/sheet.less';

View file

@ -0,0 +1,19 @@
@import '../../utils/fonts.less';
.daggerheart.levelup {
.tab-footer {
margin-top: 10px;
.levelup-navigation-actions,
.levelup-footer {
display: flex;
justify-content: end;
gap: 10px;
button {
font-family: @font-body;
font-weight: bold;
height: 40px;
}
}
}
}

View file

@ -1,3 +1,6 @@
@import '../../utils/colors.less';
@import '../../utils/fonts.less';
.daggerheart.levelup { .daggerheart.levelup {
.levelup-navigation-container { .levelup-navigation-container {
display: flex; display: flex;
@ -7,23 +10,18 @@
nav { nav {
flex: 1; flex: 1;
border: none;
.levelup-tab-container { .levelup-tab-container {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
}
}
.levelup-navigation-actions { a,
width: 306px; span {
display: flex; font-family: @font-body;
justify-content: end; color: light-dark(@dark-blue, @golden);
gap: 16px; }
margin-right: 4px;
* {
width: calc(50% - 8px);
} }
} }
} }

View file

@ -1,18 +1,38 @@
@import '../../utils/fonts.less';
@import '../../utils/colors.less';
.daggerheart.levelup { .daggerheart.levelup {
.levelup-selections-container { .levelup-selections-container {
overflow: auto;
padding: 10px 0;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
max-height: 500px;
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
.achievement-experience-cards { .achievement-experience-cards {
display: flex; display: flex;
gap: 8px; gap: 8px;
.achievement-experience-card { .achievement-experience-card {
border: 1px solid;
border-radius: 4px;
padding-right: 4px;
font-size: 18px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
background: light-dark(@dark-blue-40, @golden-40);
border-radius: 3px;
padding: 5px;
font-size: 16px;
gap: 4px; gap: 4px;
width: 100%;
input {
background: light-dark(@soft-shadow, @semi-transparent-dark-blue);
width: 80%;
}
span {
font-family: @font-body;
}
.achievement-experience-marker { .achievement-experience-marker {
border: 1px solid; border: 1px solid;
@ -30,10 +50,13 @@
.levelup-card-selection { .levelup-card-selection {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center;
gap: 40px; gap: 40px;
height: 190px;
.card-preview-container { .card-preview-container {
width: calc(100% * (1 / 5)); height: 100%;
max-width: 200px;
} }
.levelup-domains-selection-container { .levelup-domains-selection-container {
@ -89,10 +112,30 @@
} }
} }
.card-section {
flex: 1 1 100%;
.card-section-header {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 10px;
h3 {
font-family: @font-subtitle;
color: light-dark(@dark, @beige);
margin: 0;
white-space: nowrap;
}
}
}
.levelup-selections-title { .levelup-selections-title {
display: flex; margin-left: auto;
align-items: center; margin-right: auto;
gap: 4px; font-size: 22px;
font-weight: bold;
padding: 0 12px;
} }
.levelup-radio-choices { .levelup-radio-choices {

View file

@ -25,9 +25,11 @@
section { section {
.section-container { .section-container {
display: flex; display: flex;
flex-direction: column; flex-direction: row;
gap: 8px; justify-content: center;
gap: 20px 8px;
margin-top: 8px; margin-top: 8px;
flex-wrap: wrap;
} }
} }

View file

@ -1,5 +1,28 @@
@import '../../utils/colors.less';
@import '../../utils/fonts.less';
.daggerheart.levelup { .daggerheart.levelup {
.summary-header {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 10px;
h3 {
font-family: @font-subtitle;
color: light-dark(@dark, @beige);
margin: 0;
white-space: nowrap;
}
}
.levelup-summary-container { .levelup-summary-container {
overflow: auto;
padding: 10px 0;
scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent;
max-height: 700px;
mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
.level-achievements-container, .level-achievements-container,
.level-advancements-container { .level-advancements-container {
display: flex; display: flex;
@ -11,7 +34,7 @@
h4, h4,
h5 { h5 {
margin: 0; margin: 0;
color: var(--color-text-secondary); color: light-dark(@dark, @beige);
} }
} }
@ -19,7 +42,19 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
font-size: 20px; font-size: 14px;
font-family: @font-body;
color: light-dark(@dark, @beige);
}
h5.summary-section {
display: flex;
align-items: center;
gap: 4px;
font-size: 16px;
font-family: @font-subtitle;
color: light-dark(@dark, @beige);
margin-bottom: 5px;
} }
.summary-selection-container { .summary-selection-container {
@ -28,9 +63,11 @@
.summary-selection { .summary-selection {
border: 2px solid; border: 2px solid;
border-radius: 6px; border-radius: 3px;
padding: 0 4px; padding: 0 4px;
font-size: 18px; font-size: 14px;
font-family: @font-body;
color: light-dark(@dark, @beige);
} }
} }
} }

View file

@ -1,3 +1,6 @@
@import '../../utils/colors.less';
@import '../../utils/fonts.less';
.daggerheart.levelup { .daggerheart.levelup {
.tiers-container { .tiers-container {
display: flex; display: flex;
@ -38,7 +41,7 @@
height: min-content; height: min-content;
&.multi { &.multi {
border: 2px solid grey; border: 2px solid light-dark(@dark-blue-40, @golden-40);
padding: 2.4px 2.5px 0; padding: 2.4px 2.5px 0;
border-radius: 4px; border-radius: 4px;
gap: 2px; gap: 2px;
@ -56,7 +59,8 @@
} }
.checkbox-group-label { .checkbox-group-label {
font-size: 14px; font-family: @font-body;
font-size: 12px;
font-style: italic; font-style: italic;
} }
} }

View file

@ -619,6 +619,7 @@
margin-left: 8px; margin-left: 8px;
height: 20px; height: 20px;
width: 20px; width: 20px;
filter: @dark-filter;
} }
} }
} }
@ -651,31 +652,33 @@
} }
} }
.theme-light .application { .theme-light {
&.sheet.dh-style { .application {
button.glow { &.sheet.dh-style {
animation: glow-dark 0.75s infinite alternate; button.glow {
} animation: glow-dark 0.75s infinite alternate;
} }
.component.dh-style.card-preview-container {
background-image: url('../assets/parchments/dh-parchment-light.png');
.preview-text-container {
background-image: url(../assets/parchments/dh-parchment-dark.png);
} }
.preview-selected-icon-container { .component.dh-style.card-preview-container {
background-image: url(../assets/parchments/dh-parchment-dark.png); background-image: url('../assets/parchments/dh-parchment-light.png');
color: var(--color-light-5);
.preview-text-container {
background-image: url(../assets/parchments/dh-parchment-dark.png);
}
.preview-selected-icon-container {
background-image: url(../assets/parchments/dh-parchment-dark.png);
color: var(--color-light-5);
}
} }
} }
} }
.application .component.dh-style.card-preview-container { .application .component.dh-style.card-preview-container {
position: relative; position: relative;
border-radius: 6px; border: 2px solid transparent;
border: 2px solid var(--color-tabs-border);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
aspect-ratio: 0.75; aspect-ratio: 0.75;
@ -697,31 +700,41 @@
justify-content: center; justify-content: center;
} }
.preview-image-container { .preview-selected-container {
flex: 1;
border-radius: 4px 4px 0 0;
}
.preview-text-container {
flex: 1;
border-radius: 0 0 4px 4px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; border: 2px solid light-dark(@dark-blue-50, @beige-50);
justify-content: center; border-radius: 6px;
font-size: 18px; max-width: 200px;
text-align: center; height: 100%;
color: var(--color-text-selection-bg);
background-image: url(../assets/parchments/dh-parchment-light.png); .preview-image-container {
width: 100%;
flex-grow: 1;
object-fit: cover;
border-radius: 4px 4px 0 0;
}
.preview-text-container {
font-family: @font-body;
padding: 10px 0;
text-align: center;
font-size: 16px;
color: light-dark(@beige, @dark);
background-image: url(../assets/parchments/dh-parchment-light.png);
border-radius: 0 0 4px 4px;
}
} }
.preview-empty-container { .preview-empty-container {
border-radius: 6px;
pointer-events: none; pointer-events: none;
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex: 1; flex: 1;
border: 2px dashed light-dark(@dark-blue-50, @beige-50);
.preview-empty-inner-container { .preview-empty-inner-container {
width: 100%; width: 100%;
@ -729,15 +742,19 @@
justify-content: center; justify-content: center;
.preview-add-icon { .preview-add-icon {
font-size: 48px; font-size: 40px;
color: light-dark(@dark-blue-50, @beige-50);
} }
.preview-empty-subtext { .preview-empty-subtext {
position: absolute; position: absolute;
top: 10%; bottom: 5%;
font-size: 18px; font-size: 10px;
font-variant: small-caps; font-variant: small-caps;
text-align: center; text-align: center;
font-family: @font-body;
font-style: italic;
color: light-dark(@dark-blue-60, @beige-80);
} }
} }
} }

View file

@ -55,6 +55,10 @@
width: 40px; width: 40px;
object-fit: cover; object-fit: cover;
border-radius: 3px; border-radius: 3px;
&.actor-img {
border-radius: 50%;
}
} }
.roll-img { .roll-img {

View file

@ -3,11 +3,11 @@
.appTheme({ .appTheme({
.item-card-header .item-icons-list .item-icon img { .item-card-header .item-icons-list .item-icon img {
filter: invert(88%) sepia(98%) saturate(1784%) hue-rotate(311deg) brightness(104%) contrast(91%); filter: @golden-filter;
} }
}, { }, {
.item-card-header .item-icons-list .item-icon img { .item-card-header .item-icons-list .item-icon img {
filter: invert(87%) sepia(15%) saturate(343%) hue-rotate(333deg) brightness(110%) contrast(87%); filter: @bright-beige-filter;
} }
}); });

View file

@ -24,6 +24,9 @@
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
align-items: center; align-items: center;
width: 100%;
padding: 0 10px;
margin-bottom: 5px;
} }
} }
@ -33,6 +36,7 @@
text-align: center; text-align: center;
font-style: italic; font-style: italic;
justify-content: center; justify-content: center;
padding: 10px 0;
} }
.experience-list { .experience-list {
@ -40,7 +44,6 @@
flex-direction: column; flex-direction: column;
gap: 5px; gap: 5px;
width: 100%; width: 100%;
margin-top: 10px;
align-items: center; align-items: center;
.experience-row { .experience-row {
@ -49,6 +52,8 @@
width: 250px; width: 250px;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%;
padding: 0 10px;
.experience-name { .experience-name {
width: 180px; width: 180px;

View file

@ -18,4 +18,6 @@
@import './resources/resources.less'; @import './resources/resources.less';
@import './settings/settings.less'; @import './settings/settings.less';
@import './settings/homebrew-settings/domains.less';

View file

@ -0,0 +1,155 @@
.theme-light .daggerheart.dh-style.setting.homebrew-settings .domains.tab {
.domains-container .domain-container {
.domain-label {
background-image: url('../assets/parchments/dh-parchment-light.png');
}
img {
filter: @dark-filter;
}
}
}
.daggerheart.dh-style.setting.homebrew-settings {
.domains.tab {
.title-wrapper {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
&:first-child {
h2 {
margin-top: 0;
}
}
.top-lines {
position: relative;
bottom: 8px;
}
h2 {
display: flex;
align-items: center;
font-family: @font-subtitle;
position: relative;
width: auto;
white-space: nowrap;
margin-top: 16px;
gap: 8px;
color: light-dark(@dark, @beige);
.add-button {
border-radius: 50%;
width: 24px;
height: 24px;
font-size: 12px;
}
}
}
.domains-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
gap: 8px;
.domain-container {
position: relative;
display: flex;
justify-content: center;
border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px;
&.selectable {
height: 100%;
background: inherit;
padding: 0;
}
&.inactive {
opacity: 0.5;
}
.domain-label {
position: absolute;
top: 4px;
border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px;
padding: 0 2px;
color: light-dark(@dark, @beige);
background-image: url('../assets/parchments/dh-parchment-dark.png');
white-space: nowrap;
text-wrap: auto;
text-align: center;
z-index: 2;
}
img {
border-radius: 6px;
filter: @beige-filter;
}
}
}
.domain-edit-container {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.3s ease-in-out;
overflow: hidden;
&.extended {
grid-template-rows: 1fr;
fieldset {
opacity: 1;
}
}
fieldset {
overflow: hidden;
opacity: 0;
transition: opacity 0.3s ease-in-out;
legend {
display: flex;
align-items: center;
gap: 4px;
button {
border-radius: 50%;
font-size: 12px;
height: 24px;
width: 24px;
margin-right: 4px;
}
}
.domain-filepicker-row {
width: 100%;
.form-group {
flex: 1;
gap: 8px;
.form-fields {
flex: 1;
display: flex;
file-picker {
flex: 1;
}
}
}
}
textarea {
width: 100%;
height: 120px;
margin-top: 4px;
}
}
}
}
}

View file

@ -119,6 +119,7 @@
top: -7px; top: -7px;
font-size: 12px; font-size: 12px;
font-variant: petite-caps; font-variant: petite-caps;
z-index: 2;
} }
input { input {

View file

@ -5,6 +5,8 @@
@golden-10: #f3c26710; @golden-10: #f3c26710;
@golden-40: #f3c26740; @golden-40: #f3c26740;
@golden-bg: #f3c2671a; @golden-bg: #f3c2671a;
@golden-filter: brightness(0) saturate(100%) invert(89%) sepia(13%) saturate(2008%) hue-rotate(332deg) brightness(99%)
contrast(92%);
@chat-blue: #8f87ee; @chat-blue: #8f87ee;
@chat-blue-10: #8f87ee10; @chat-blue-10: #8f87ee10;
@ -49,6 +51,7 @@
@dark: #222; @dark: #222;
@dark-15: #22222215; @dark-15: #22222215;
@dark-40: #22222240; @dark-40: #22222240;
@dark-filter: brightness(0) saturate(100%);
@deep-black: #0e0d15; @deep-black: #0e0d15;
@ -56,6 +59,10 @@
@beige-15: #efe6d815; @beige-15: #efe6d815;
@beige-50: #efe6d850; @beige-50: #efe6d850;
@beige-80: #efe6d880; @beige-80: #efe6d880;
@beige-filter: brightness(0) saturate(100%) invert(87%) sepia(25%) saturate(164%) hue-rotate(339deg) brightness(106%)
contrast(87%);
@bright-beige-filter: brightness(0) saturate(100%) invert(87%) sepia(15%) saturate(343%) hue-rotate(333deg)
brightness(110%) contrast(87%);
@soft-white-shadow: rgba(255, 255, 255, 0.05); @soft-white-shadow: rgba(255, 255, 255, 0.05);

View file

@ -3,13 +3,15 @@
{{#if (not disabled)}}data-action="viewCompendium"{{/if}} data-compendium="{{this.compendium}}" data-path="{{this.path}}" data-limit="{{this.limit}}" {{#if (not disabled)}}data-action="viewCompendium"{{/if}} data-compendium="{{this.compendium}}" data-path="{{this.path}}" data-limit="{{this.limit}}"
> >
{{#if this.img}} {{#if this.img}}
<img class="preview-image-container" src="{{this.img}}" /> <div class="preview-selected-container">
<div class="preview-text-container"> <img class="preview-image-container" src="{{this.img}}" />
{{#if altPartialBlock}} <div class="preview-text-container">
{{> @partial-block }} {{#if altPartialBlock}}
{{else}} {{> @partial-block }}
{{this.name}} {{else}}
{{/if}} {{this.name}}
{{/if}}
</div>
</div> </div>
{{else}} {{else}}
<div class="preview-empty-container"> <div class="preview-empty-container">

View file

@ -1,4 +1,23 @@
<section class='tab-footer'> <section class='tab-footer'>
{{#if this.levelupAuto}}
<div class="levelup-navigation-actions {{#if (not this.showTabs)}}test{{/if}}">
{{#if this.navigate.previous.fromSummary}}
<button data-action="activatePart" data-part="advancements">{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToLevelup"}}</button>
<button data-action="save" {{#if (not this.levelup.allLevelsFinished)}}disabled{{/if}}>{{localize "Finish Levelup"}}</button>
{{else}}
{{#if (not this.navigate.previous.disabled)}}
<button data-action="updateCurrentLevel" >{{this.navigate.previous.label}}</button>
{{/if}}
{{/if}}
{{#if this.navigate.next.show}}
{{#if this.navigate.next.toSummary}}
<button data-action="activatePart" data-part="summary" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToSummary"}}</button>
{{else}}
<button data-action="updateCurrentLevel" data-forward="true" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{this.navigate.next.label}}</button>
{{/if}}
{{/if}}
</div>
{{/if}}
{{#unless levelupAuto}} {{#unless levelupAuto}}
<div class="levelup-footer"> <div class="levelup-footer">
<button type="button" data-action="close">{{localize "Cancel"}}</button> <button type="button" data-action="close">{{localize "Cancel"}}</button>

View file

@ -5,55 +5,60 @@
> >
<div class="section-container levelup-selections-container"> <div class="section-container levelup-selections-container">
{{#if (gt this.newExperiences.length 0)}} {{#if (gt this.newExperiences.length 0)}}
<div> <fieldset class="new-experience">
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.newExperiences"}}</h3> <legend class="levelup-selections-title">
{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.newExperiences"}}
</legend>
<div class="achievement-experience-cards"> <div class="achievement-experience-cards">
{{#each this.newExperiences}} {{#each this.newExperiences}}
<div class="achievement-experience-card"> <div class="achievement-experience-card">
<div class="flexrow"> <input type="text" name="{{concat "levelup.levels." this.level ".achievements.experiences." this.key ".name"}}" value="{{this.name}}" placeholder="{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.experiencePlaceholder"}}" />
<input type="text" name="{{concat "levelup.levels." this.level ".achievements.experiences." this.key ".name"}}" value="{{this.name}}" placeholder="{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.experiencePlaceholder"}}" /> <span>{{numberFormat this.modifier sign=true}}</span>
<div class="flex0">{{numberFormat this.modifier sign=true}}</div>
</div>
<div class="achievement-experience-marker"> <div class="achievement-experience-marker">
{{#if this.name}}<i class="fa-solid fa-check"></i>{{/if}} {{#if this.name}}<i class="fa-solid fa-check"></i>{{/if}}
</div> </div>
</div> </div>
{{/each}} {{/each}}
</div> </div>
</div> </fieldset>
{{/if}} {{/if}}
{{#if this.traits.active}} {{#if this.traits.active}}
<div> <fieldset>
<h3 class="levelup-selections-title"> <legend class="levelup-selections-title">
<div>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.traits"}}</div> <span>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.traits"}} {{this.traits.progress.selected}}/{{this.traits.progress.max}}</span>
<div>{{this.traits.progress.selected}}/{{this.traits.progress.max}}</div> </legend>
</h3>
<input type="text" class="levelup-trait-increases" value="{{this.traits.values}}" /> <input type="text" class="levelup-trait-increases" value="{{this.traits.values}}" />
</div> </fieldset>
{{/if}} {{/if}}
{{#if this.experienceIncreases.active}} {{#if this.experienceIncreases.active}}
<div> <fieldset>
<h3 class="levelup-selections-title"> <legend class="levelup-selections-title">
<div>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.experienceIncreases"}}</div> <span>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.experienceIncreases"}} {{this.experienceIncreases.progress.selected}}/{{this.experienceIncreases.progress.max}}</span>
<div>{{this.experienceIncreases.progress.selected}}/{{this.experienceIncreases.progress.max}}</div> </legend>
</h3>
<input type="text" class="levelup-experience-increases" value="{{this.experienceIncreases.values}}" /> <input type="text" class="levelup-experience-increases" value="{{this.experienceIncreases.values}}" />
</div> </fieldset>
{{/if}} {{/if}}
{{#if (gt this.domainCards.length 0)}} {{#if (gt this.domainCards.length 0)}}
<div> <div class="card-section">
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h3> <div class="card-section-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h3>
<side-line-div></side-line-div>
</div>
<div class="tip">
</div>
<div class="levelup-card-selection domain-cards"> <div class="levelup-card-selection domain-cards">
{{#each this.domainCards}} {{#each this.domainCards}}
{{#> "systems/daggerheart/templates/components/card-preview.hbs" this }} {{#> "systems/daggerheart/templates/components/card-preview.hbs" this }}
{{#each this.emptySubtexts}} {{#each this.emptySubtexts}}
<div>{{this}}</div> <div class="">{{this}}</div>
{{/each}} {{/each}}
{{/"systems/daggerheart/templates/components/card-preview.hbs"}} {{/"systems/daggerheart/templates/components/card-preview.hbs"}}
{{/each}} {{/each}}
@ -62,8 +67,12 @@
{{/if}} {{/if}}
{{#if (gt this.subclassCards.length 0)}} {{#if (gt this.subclassCards.length 0)}}
<div> <div class="card-section">
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.subclass"}}</h3> <div class="card-section-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.subclass"}}</h3>
<side-line-div></side-line-div>
</div>
<div class="levelup-card-selection subclass-cards"> <div class="levelup-card-selection subclass-cards">
{{#each this.subclassCards}} {{#each this.subclassCards}}
@ -74,40 +83,47 @@
{{/if}} {{/if}}
{{#if this.multiclass}} {{#if this.multiclass}}
<div> <div class="card-section">
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.multiclass"}}</h3> <div class="card-section-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.multiclass"}}</h3>
<side-line-div></side-line-div>
</div>
<div class="levelup-card-selection multiclass-cards" data-path="{{this.multiclass.path}}" data-tier="{{this.multiclass.tier}}" data-min-cost="{{this.multiclass.minCost}}" data-amount="{{this.multiclass.amount}}" data-value="{{this.multiclass.value}}" data-type="{{this.multiclass.type}}"> <div class="levelup-card-selection multiclass-cards" data-path="{{this.multiclass.path}}" data-tier="{{this.multiclass.tier}}" data-min-cost="{{this.multiclass.minCost}}" data-amount="{{this.multiclass.amount}}" data-value="{{this.multiclass.value}}" data-type="{{this.multiclass.type}}">
{{#> "systems/daggerheart/templates/components/card-preview.hbs" this.multiclass }} {{#> "systems/daggerheart/templates/components/card-preview.hbs" this.multiclass }}
{{this.multiclass.emptySubtext}} {{this.multiclass.emptySubtext}}
{{/"systems/daggerheart/templates/components/card-preview.hbs"}} {{/"systems/daggerheart/templates/components/card-preview.hbs"}}
<div class="levelup-domains-selection-container"> {{#if this.multiclass.domains}}
{{#each this.multiclass.domains}} <div class="levelup-domains-selection-container">
<div class="levelup-domain-selection-container {{#if this.disabled}}disabled{{/if}}" {{#if (not this.disabled)}}data-action="selectDomain" data-uuid="{{../multiclass.uuid}}" data-domain="{{this.id}}" data-path="{{../multiclass.path}}" {{/if}}> {{#each this.multiclass.domains}}
<div class="levelup-domain-label">{{localize this.label}}</div> <div class="levelup-domain-selection-container {{#if this.disabled}}disabled{{/if}}" {{#if (not this.disabled)}}data-action="selectDomain" data-uuid="{{../multiclass.uuid}}" data-domain="{{this.id}}" data-path="{{../multiclass.path}}" {{/if}}>
<img src="{{this.src}}" /> <div class="levelup-domain-label">{{localize this.label}}</div>
{{#if this.selected}} <img src="{{this.src}}" />
<div class="levelup-domain-selected"> {{#if this.selected}}
<i class="fa-solid fa-check"></i> <div class="levelup-domain-selected">
</div> <i class="fa-solid fa-check"></i>
{{/if}} </div>
</div> {{/if}}
{{/each}} </div>
</div> {{/each}}
</div>
<div class="levelup-domains-selection-container"> {{/if}}
{{#each this.multiclass.subclasses}} {{#if this.multiclass.subclasses}}
<div class="levelup-domain-selection-container {{#if this.disabled}}disabled{{/if}}" {{#if (not this.disabled)}}data-action="selectSubclass" data-uuid="{{../multiclass.uuid}}" data-subclass="{{this.uuid}}" data-path="{{../multiclass.path}}" {{/if}}> <div class="levelup-domains-selection-container">
<div class="levelup-domain-label">{{localize this.name}}</div> {{#each this.multiclass.subclasses}}
<img src="{{this.img}}" /> <div class="levelup-domain-selection-container {{#if this.disabled}}disabled{{/if}}" {{#if (not this.disabled)}}data-action="selectSubclass" data-uuid="{{../multiclass.uuid}}" data-subclass="{{this.uuid}}" data-path="{{../multiclass.path}}" {{/if}}>
{{#if this.selected}} <div class="levelup-domain-label">{{localize this.name}}</div>
<div class="levelup-domain-selected"> <img src="{{this.img}}" />
<i class="fa-solid fa-check"></i> {{#if this.selected}}
</div> <div class="levelup-domain-selected">
{{/if}} <i class="fa-solid fa-check"></i>
</div> </div>
{{/each}} {{/if}}
</div> </div>
{{/each}}
</div>
{{/if}}
</div> </div>
</div> </div>
{{/if}} {{/if}}

View file

@ -3,6 +3,13 @@
data-tab='{{tabs.summary.id}}' data-tab='{{tabs.summary.id}}'
data-group='{{tabs.summary.group}}' data-group='{{tabs.summary.group}}'
> >
<div class="summary-header">
<side-line-div class="invert"></side-line-div>
<h3>{{localize tabs.summary.label}}</h3>
<side-line-div></side-line-div>
</div>
<div class="section-container levelup-summary-container"> <div class="section-container levelup-summary-container">
{{#if this.achievements}} {{#if this.achievements}}
<fieldset> <fieldset>
@ -35,7 +42,7 @@
{{/if}} {{/if}}
{{#if this.achievements.domainCards.shown}} {{#if this.achievements.domainCards.shown}}
<div> <div>
<h5>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h5> <h5 class="summary-section">{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h5>
<div class="summary-selection-container"> <div class="summary-selection-container">
{{#each this.achievements.domainCards.values}} {{#each this.achievements.domainCards.values}}
<div class="summary-selection">{{this.name}}</div> <div class="summary-selection">{{this.name}}</div>
@ -45,7 +52,7 @@
{{/if}} {{/if}}
{{#if this.achievements.experiences.shown}} {{#if this.achievements.experiences.shown}}
<div> <div>
<h5>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.newExperiences"}}</h5> <h5 class="summary-section">{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.newExperiences"}}</h5>
<div class="summary-selection-container"> <div class="summary-selection-container">
{{#each this.achievements.experiences.values}} {{#each this.achievements.experiences.values}}
<div class="summary-selection">{{this.name}} {{numberFormat this.modifier sign=true}}</div> <div class="summary-selection">{{this.name}} {{numberFormat this.modifier sign=true}}</div>
@ -97,7 +104,7 @@
{{#if this.advancements.traits}} {{#if this.advancements.traits}}
<div> <div>
<h5>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.traits"}}</h5> <h5 class="summary-section">{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.traits"}}</h5>
{{#each this.advancements.traits}} {{#each this.advancements.traits}}
<div class="increase-container"> <div class="increase-container">
@ -111,7 +118,7 @@
{{#if this.advancements.domainCards}} {{#if this.advancements.domainCards}}
<div> <div>
<h5>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h5> <h5 class="summary-section">{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.domainCards"}}</h5>
<div class="summary-selection-container"> <div class="summary-selection-container">
{{#each this.advancements.domainCards}} {{#each this.advancements.domainCards}}
<div class="summary-selection">{{this.name}}</div> <div class="summary-selection">{{this.name}}</div>
@ -122,7 +129,7 @@
{{#if this.advancements.experiences}} {{#if this.advancements.experiences}}
<div> <div>
<h5>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.experienceIncreases"}}</h5> <h5 class="summary-section">{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.experienceIncreases"}}</h5>
<div class="summary-selection-container"> <div class="summary-selection-container">
{{#each this.advancements.experiences}} {{#each this.advancements.experiences}}
<div class="summary-selection">{{this.name}} {{numberFormat this.modifier sign=true}}</div> <div class="summary-selection">{{this.name}} {{numberFormat this.modifier sign=true}}</div>
@ -133,7 +140,7 @@
{{#if this.advancements.subclass}} {{#if this.advancements.subclass}}
<div> <div>
<h5>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.subclass"}}</h5> <h5 class="summary-section">{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.subclass"}}</h5>
<div class="summary-selection-container"> <div class="summary-selection-container">
{{#each this.advancements.subclass}} {{#each this.advancements.subclass}}
<div class="summary-selection">{{this.name}} - {{this.featureLabel}}</div> <div class="summary-selection">{{this.name}} - {{this.featureLabel}}</div>
@ -145,7 +152,7 @@
{{#if this.advancements.multiclass}} {{#if this.advancements.multiclass}}
{{#with this.advancements.multiclass}} {{#with this.advancements.multiclass}}
<div> <div>
<h5>{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.multiclass"}}</h5> <h5 class="summary-section">{{localize "DAGGERHEART.APPLICATIONS.Levelup.summary.multiclass"}}</h5>
<div class="summary-selection-container"> <div class="summary-selection-container">
<div class="summary-selection">{{this.name}}</div> <div class="summary-selection">{{this.name}}</div>
<div class="summary-selection">{{this.domain}}</div> <div class="summary-selection">{{this.domain}}</div>
@ -176,9 +183,5 @@
{{/each}} {{/each}}
</div> </div>
</fieldset> </fieldset>
<footer class="levelup-footer">
<button data-action="save" {{#if (not this.levelup.allLevelsFinished)}}disabled{{/if}}>{{localize "Finish Levelup"}}</button>
</footer>
</div> </div>
</section> </section>

View file

@ -1,3 +1,4 @@
{{#unless tabs.summary.active}}
<section class='tab-navigation'> <section class='tab-navigation'>
{{#if levelupAuto}} {{#if levelupAuto}}
<line-div></line-div> <line-div></line-div>
@ -9,36 +10,19 @@
<div class="levelup-tab-container"> <div class="levelup-tab-container">
<a class='{{tab.id}} {{tab.cssClass}}' data-action='tab' data-group='{{tab.group}}' data-tab='{{tab.id}}'> <a class='{{tab.id}} {{tab.cssClass}}' data-action='tab' data-group='{{tab.group}}' data-tab='{{tab.id}}'>
{{localize tab.label}} {{localize tab.label}}
{{#if tab.progress}}
<span>{{tab.progress.selected}}/{{tab.progress.max}}</span>
{{/if}}
</a> </a>
{{#if tab.progress}}
<div>{{tab.progress.selected}}/{{tab.progress.max}}</div>
{{/if}}
</div> </div>
{{/if}} {{/if}}
{{/each}} {{/each}}
</nav> </nav>
{{/if}} {{/if}}
{{#if this.levelupAuto}}
<div class="levelup-navigation-actions {{#if (not this.showTabs)}}test{{/if}}">
{{#if this.navigate.previous.fromSummary}}
<button data-action="activatePart" data-part="advancements">{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToLevelup"}}</button>
{{else}}
{{#if (not this.navigate.previous.disabled)}}
<button data-action="updateCurrentLevel" >{{this.navigate.previous.label}}</button>
{{/if}}
{{/if}}
{{#if this.navigate.next.show}}
{{#if this.navigate.next.toSummary}}
<button data-action="activatePart" data-part="summary" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{localize "DAGGERHEART.APPLICATIONS.Levelup.navigateToSummary"}}</button>
{{else}}
<button data-action="updateCurrentLevel" data-forward="true" {{#if this.navigate.next.disabled}}disabled{{/if}}>{{this.navigate.next.label}}</button>
{{/if}}
{{else}}
<div></div>
{{/if}}
</div>
{{/if}}
</div> </div>
<line-div></line-div> <line-div></line-div>
{{/if}} {{/if}}
</section> </section>
{{else}}
<section></section>
{{/unless}}

View file

@ -0,0 +1,45 @@
<section
class="tab {{tabs.domains.cssClass}} {{tabs.domains.id}}"
data-tab="{{tabs.domains.id}}"
data-group="{{tabs.domains.group}}"
>
<div class="title-wrapper">
<side-line-div class="invert top-lines"></side-line-div>
<h2>{{localize "DAGGERHEART.SETTINGS.Homebrew.domains.domainsTitle"}}</h2>
<side-line-div class="top-lines"></side-line-div>
</div>
<div class="domains-container">
{{#each configDomains as | domain |}}
<div class="domain-container">
<div class="domain-label">{{localize domain.label}}</div>
<img src="{{domain.src}}" class="domain-icon" />
</div>
{{/each}}
</div>
<div class="title-wrapper">
<side-line-div class="invert"></side-line-div>
<h2>
{{localize "DAGGERHEART.SETTINGS.Homebrew.domains.homebrewDomains"}}
<button class="add-button" data-action="addDomain"><i class="fa-solid fa-plus"></i></button>
</h2>
<side-line-div></side-line-div>
</div>
<div class="domains-container">
{{#each homebrewDomains as | domain id |}}
<button class="domain-container selectable {{#unless (eq @root.selectedDomain.id id)}}inactive{{/unless}}" id="{{id}}" data-action="toggleSelectedDomain">
<div class="domain-label">{{localize domain.label}}</div>
<img src="{{domain.src}}" class="domain-icon" style="--domain-icon: url({{domain.src}})" />
</button>
{{/each}}
</div>
<div class="domain-edit-container {{#if @root.selectedDomain}}extended{{/if}}">
<fieldset>
<legend>{{localize "DAGGERHEART.SETTINGS.Homebrew.domains.editDomain"}} <button class="add-button" data-action="deleteDomain"><i class="fa-solid fa-x"></i></button></legend>
<div class="domain-filepicker-row">{{formGroup settingFields.schema.fields.domains.element.fields.src value=selectedDomain.src name=(concat "domains." selectedDomain.id ".src") localize=true}}</div>
<textarea name="{{concat "domains." selectedDomain.id ".description"}}">{{selectedDomain.description}}</textarea>
</fieldset>
</div>
</section>

View file

@ -0,0 +1,51 @@
<section
class="tab {{tabs.downtime.cssClass}} {{tabs.downtime.id}}"
data-tab="{{tabs.downtime.id}}"
data-group="{{tabs.downtime.group}}"
>
<fieldset class="two-columns even">
<legend>{{localize "DAGGERHEART.SETTINGS.Homebrew.downtimeMoves"}}</legend>
<fieldset class="start-align">
<legend>
{{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}}
<a data-action="addItem" data-type="longRest"><i class="fa-solid fa-plus"></i></a>
<a data-action="resetMoves" data-type="longRest"><i class="fa-solid fa-arrow-rotate-left"></i></a>
</legend>
<div class="form-group setting-group-field">
<label>{{localize "DAGGERHEART.SETTINGS.Homebrew.nrChoices"}}</label>
<div class="form-fields">
<input type="text" name="restMoves.longRest.nrChoices" value="{{settingFields._source.restMoves.longRest.nrChoices}}" />
</div>
</div>
<div class="settings-items">
{{#each settingFields._source.restMoves.longRest.moves as |move id|}}
{{> "systems/daggerheart/templates/settings/components/settings-item-line.hbs" this type="longRest" id=id }}
{{/each}}
</div>
</fieldset>
<fieldset class="start-align">
<legend>
{{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}}
<a data-action="addItem" data-type="shortRest"><i class="fa-solid fa-plus"></i></a>
<a data-action="resetMoves" data-type="shortRest"><i class="fa-solid fa-arrow-rotate-left"></i></a>
</legend>
<div class="form-group setting-group-field">
<label>{{localize "DAGGERHEART.SETTINGS.Homebrew.nrChoices"}}</label>
<div class="form-fields">
<input type="text" name="restMoves.shortRest.nrChoices" value="{{settingFields._source.restMoves.shortRest.nrChoices}}" />
</div>
</div>
<div class="settings-items">
{{#each settingFields._source.restMoves.shortRest.moves as |move id|}}
{{> "systems/daggerheart/templates/settings/components/settings-item-line.hbs" this type="shortRest" id=id }}
{{/each}}
</div>
</fieldset>
</fieldset>
</section>

View file

@ -0,0 +1,10 @@
<footer class="form-footer">
<button type="button" data-action="reset">
<i class="fa-solid fa-arrow-rotate-left"></i>
<span>{{localize "Reset"}}</span>
</button>
<button type="button" data-action="save" >
<i class="fa-solid fa-floppy-disk"></i>
<span>{{localize "Save Changes"}}</span>
</button>
</footer>

View file

@ -0,0 +1,38 @@
<section
class="tab {{tabs.settings.cssClass}} {{tabs.settings.id}}"
data-tab="{{tabs.settings.id}}"
data-group="{{tabs.settings.group}}"
>
<div class="scrollable">
<header class="dialog-header">
<h1>{{localize 'DAGGERHEART.SETTINGS.Menu.homebrew.name'}}</h1>
</header>
{{formGroup settingFields.schema.fields.maxFear value=settingFields._source.maxFear localize=true}}
{{formGroup settingFields.schema.fields.maxDomains value=settingFields._source.maxDomains localize=true}}
{{formGroup settingFields.schema.fields.maxLoadout value=settingFields._source.maxLoadout localize=true}}
<div class="settings-hint"><label>{{localize "DAGGERHEART.SETTINGS.Homebrew.FIELDS.maxLoadout.hint"}}</label></div>
<h4>{{localize "DAGGERHEART.SETTINGS.Homebrew.FIELDS.traitArray.label"}}</h4>
<div class="trait-array-container">
{{#each settingFields._source.traitArray as |trait index|}}
<div class="trait-array-item">
<label>{{localize "DAGGERHEART.GENERAL.Modifier.single"}} {{add index 1}}</label>
<input type="text" data-dtype="Number" name="{{concat "traitArray." index}}" value="{{this}}" />
</div>
{{/each}}
</div>
<fieldset>
<legend>
{{localize "DAGGERHEART.SETTINGS.Homebrew.currency.title"}}
</legend>
{{formGroup settingFields.schema.fields.currency.fields.enabled value=settingFields._source.currency.enabled localize=true}}
{{formGroup settingFields.schema.fields.currency.fields.title value=settingFields._source.currency.title localize=true}}
{{formGroup settingFields.schema.fields.currency.fields.coins value=settingFields._source.currency.coins localize=true}}
{{formGroup settingFields.schema.fields.currency.fields.handfulls value=settingFields._source.currency.handfulls localize=true}}
{{formGroup settingFields.schema.fields.currency.fields.bags value=settingFields._source.currency.bags localize=true}}
{{formGroup settingFields.schema.fields.currency.fields.chests value=settingFields._source.currency.chests localize=true}}
</fieldset>
</div>
</section>

View file

@ -7,7 +7,7 @@
<side-line-div></side-line-div> <side-line-div></side-line-div>
</div> </div>
{{#if document.system.partner}} {{#if document.system.partner}}
<ul class="item-list"> <ul class="items-list">
{{> 'daggerheart.inventory-item' {{> 'daggerheart.inventory-item'
item=document.system.partner item=document.system.partner
type='companion' type='companion'
@ -27,7 +27,7 @@
<h3>{{localize "DAGGERHEART.GENERAL.attack"}}</h3> <h3>{{localize "DAGGERHEART.GENERAL.attack"}}</h3>
<side-line-div></side-line-div> <side-line-div></side-line-div>
</div> </div>
<ul class="item-list"> <ul class="items-list">
{{> 'daggerheart.inventory-item' {{> 'daggerheart.inventory-item'
item=document.system.attack item=document.system.attack
type='action' type='action'

View file

@ -7,8 +7,8 @@
<i class="fa-solid fa-bolt"></i> <i class="fa-solid fa-bolt"></i>
</span> </span>
<span class="item-icon"> <span class="item-icon">
<span class="recall-label">{{localize (concat 'DAGGERHEART.GENERAL.Domain.' source.system.domain '.label')}}</span> <span class="recall-label">{{localize @root.domain.label}}</span>
<img src="{{concat 'systems/daggerheart/assets/icons/domains/' source.system.domain '.svg'}}" alt=""> <img src="{{@root.domain.src}}" alt="">
</span> </span>
</div> </div>
<div class='item-info'> <div class='item-info'>
@ -18,7 +18,7 @@
<h3> <h3>
{{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' source.system.type)}} {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' source.system.type)}}
<span>-</span> <span>-</span>
{{localize (concat 'DAGGERHEART.GENERAL.Domain.' source.system.domain '.label')}} {{localize @root.domain.label}}
<span>-</span> <span>-</span>
{{localize "DAGGERHEART.GENERAL.level"}}: {{localize "DAGGERHEART.GENERAL.level"}}:
{{source.system.level}} {{source.system.level}}

View file

@ -9,7 +9,7 @@
<span>{{localize "DAGGERHEART.GENERAL.type"}}</span> <span>{{localize "DAGGERHEART.GENERAL.type"}}</span>
{{formField systemFields.type value=source.system.type localize=true}} {{formField systemFields.type value=source.system.type localize=true}}
<span>{{localize "DAGGERHEART.GENERAL.Domain.single"}}</span> <span>{{localize "DAGGERHEART.GENERAL.Domain.single"}}</span>
{{formField systemFields.domain value=source.system.domain localize=true}} {{formField systemFields.domain value=source.system.domain choices=domainChoices valueAttr="id" labelAttr="label" localize=true}}
<span>{{localize "DAGGERHEART.GENERAL.level"}}</span> <span>{{localize "DAGGERHEART.GENERAL.level"}}</span>
{{formField systemFields.level value=source.system.level data-dtype="Number"}} {{formField systemFields.level value=source.system.level data-dtype="Number"}}
<span>{{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}</span> <span>{{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}</span>