Improved domainremoval cleanup

This commit is contained in:
WBHarry 2025-08-06 12:01:22 +02:00
parent d01965e5b9
commit 902bfac490
6 changed files with 86 additions and 35 deletions

View file

@ -2146,9 +2146,13 @@
"domainsTitle": "Base Domains", "domainsTitle": "Base Domains",
"homebrewDomains": "Homebrew Domains", "homebrewDomains": "Homebrew Domains",
"newDomain": "New Domain", "newDomain": "New Domain",
"newDomainInputTitle": "Create Homebrew Domain",
"newDomainInputLabel": "New Domain Name",
"newDomainInputHint": "This cannot be altered later",
"editDomain": "Active Domain", "editDomain": "Active Domain",
"deleteDomain": "Delete Domain", "deleteDomain": "Delete Domain",
"deleteDomainText": "Are you sure you want to delete the {name} domain? It will be removed from all Actors in this world where it's currently used." "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

@ -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) {
@ -199,20 +200,52 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
this.render(); this.render();
} }
static async addDomain() { static async addDomain(event) {
const id = foundry.utils.randomID(); 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({ this.settings.updateSource({
[`domains.${id}`]: { [`domains.${newSlug}`]: {
id: id, id: newSlug,
label: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.newDomain'), label: domainName,
src: 'icons/svg/portal.svg' src: 'icons/svg/portal.svg'
} }
}); });
this.selected.domain = id; this.selected.domain = newSlug;
this.render(); 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) { static toggleSelectedDomain(_, target) {
this.selected.domain = this.selected.domain === target.id ? null : target.id; this.selected.domain = this.selected.domain === target.id ? null : target.id;
this.render(); this.render();
@ -230,33 +263,40 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
if (!confirmed) return; if (!confirmed) return;
const updateClasses = game.items.filter( await this.settings.updateSource({
x => x.type === 'class' && x.system.domains.includes(this.selected.domain) [`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) { for (let actor of game.actors) {
updateClasses.push( updateClasses.push(...actor.items.filter(x => x.type === 'class'));
...actor.items.filter(x => x.type === 'class' && x.system.domains.includes(this.selected.domain))
);
} }
for (let c of updateClasses) { for (let c of updateClasses) {
const newDomains = c.system.domains.map(x => if (c.system.domains.includes(this.selected.domain)) {
x === this.selected.domain ? CONFIG.DH.DOMAIN.domains.arcana.id : x 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 }); await c.update({ 'system.domains': newDomains });
} }
c.sheet.render();
}
const updateDomainCards = game.items.filter( const updateDomainCards = game.items.filter(
x => x.type === 'domainCard' && x.system.domain === this.selected.domain x => x.type === 'domainCard' && x.system.domain === this.selected.domain
); );
for (let d of updateDomainCards) { for (let d of updateDomainCards) {
await d.update({ 'system.domain': CONFIG.DH.DOMAIN.domains.arcana.id }); await d.update({ 'system.domain': CONFIG.DH.DOMAIN.domains.arcana.id });
d.sheet.render();
} }
await this.settings.updateSource({
[`domains.-=${this.selected.domain}`]: null
});
this.selected.domain = null; this.selected.domain = null;
this.render(); this.render();
} }

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.allDomains(), 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

@ -370,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

@ -127,13 +127,20 @@
} }
.domain-filepicker-row { .domain-filepicker-row {
display: flex; width: 100%;
justify-content: space-between;
gap: 8px;
.form-group { .form-group {
flex: 1; flex: 1;
gap: 8px; gap: 8px;
.form-fields {
flex: 1;
display: flex;
file-picker {
flex: 1;
}
}
} }
} }

View file

@ -38,11 +38,7 @@
<fieldset> <fieldset>
<legend>{{localize "DAGGERHEART.SETTINGS.Homebrew.domains.editDomain"}} <button class="add-button" data-action="deleteDomain"><i class="fa-solid fa-x"></i></button></legend> <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"> <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>
{{formGroup settingFields.schema.fields.domains.element.fields.label value=selectedDomain.label name=(concat "domains." selectedDomain.id ".label") localize=true}}
{{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> <textarea name="{{concat "domains." selectedDomain.id ".description"}}">{{selectedDomain.description}}</textarea>
</fieldset> </fieldset>
</div> </div>