From 013085299ffd30e7e1ea31f22d0dd87471f881ff Mon Sep 17 00:00:00 2001 From: WBHarry Date: Thu, 13 Nov 2025 19:24:15 +0100 Subject: [PATCH] Fixed deletion of characters in the world locking up the party actor --- lang/en.json | 3 ++- module/applications/ui/chatLog.mjs | 10 ++++++++++ module/data/actor/character.mjs | 12 +++++++++++- module/data/actor/party.mjs | 4 ++-- module/systemRegistration/migrations.mjs | 11 +++++++++++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lang/en.json b/lang/en.json index 14faa9d8..9de04f27 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2660,7 +2660,8 @@ "subclassAlreadyLinked": "{name} is already a subclass in the class {class}. Remove it from there if you want it to be a subclass to this class.", "gmRequired": "This action requires an online GM", "gmOnly": "This can only be accessed by the GM", - "noActorOwnership": "You do not have permissions for this character" + "noActorOwnership": "You do not have permissions for this character", + "documentIsMissing": "The {documentType} is missing from the world." }, "Sidebar": { "daggerheartMenu": { diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 6b05fe74..bcd6126e 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -195,6 +195,14 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo const { actor: actorData, trait } = foundry.utils.getProperty(message.system, path); const actor = game.actors.get(actorData._id); + if (!actor) { + return ui.notifications.error( + game.i18n.format('DAGGERHEART.UI.Notifications.documentIsMissing', { + documentType: game.i18n.localize('TYPES.Actor.character') + }) + ); + } + if (!actor.testUserPermission(game.user, 'OWNER')) { return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.noActorOwnership')); } @@ -225,6 +233,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo }) }); + if (!result) return; + const newMessageData = foundry.utils.deepClone(message.system); foundry.utils.setProperty(newMessageData, `${path}.result`, result.roll); const renderData = { system: new game.system.api.models.chatMessages.config.groupRoll(newMessageData) }; diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 1cf082f7..8afb1770 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -672,9 +672,19 @@ export default class DhCharacter extends BaseDataActor { if (this.companion) { this.companion.updateLevel(1); } + + if (this.parent.parties) { + for (const party of this.parent.parties) { + await party.update({ + 'system.partyMembers': party.system.partyMembers.filter(x => x.uuid !== this.parent.uuid) + }); + } + } } _getTags() { - return [this.class.value?.name, this.class.subclass?.name, this.community?.name, this.ancestry?.name].filter((t) => !!t); + return [this.class.value?.name, this.class.subclass?.name, this.community?.name, this.ancestry?.name].filter( + t => !!t + ); } } diff --git a/module/data/actor/party.mjs b/module/data/actor/party.mjs index 93fb3cde..8292296f 100644 --- a/module/data/actor/party.mjs +++ b/module/data/actor/party.mjs @@ -32,7 +32,7 @@ export default class DhParty extends BaseDataActor { // Register this party to all members if (game.actors.get(this.parent.id) === this.parent) { for (const member of this.partyMembers) { - member.parties?.add(this.parent); + member?.parties?.add(this.parent); } } } @@ -42,7 +42,7 @@ export default class DhParty extends BaseDataActor { // Clear this party from all members that aren't deleted for (const member of this.partyMembers) { - member.parties?.delete(this.parent); + member?.parties?.delete(this.parent); } } } diff --git a/module/systemRegistration/migrations.mjs b/module/systemRegistration/migrations.mjs index e3777a94..1e5652f6 100644 --- a/module/systemRegistration/migrations.mjs +++ b/module/systemRegistration/migrations.mjs @@ -4,6 +4,7 @@ export async function runMigrations() { let lastMigrationVersion = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion); if (!lastMigrationVersion) lastMigrationVersion = game.system.version; + //#region old migrations if (foundry.utils.isNewerVersion('1.1.0', lastMigrationVersion)) { const lockedPacks = []; const compendiumActors = []; @@ -190,6 +191,16 @@ export async function runMigrations() { lastMigrationVersion = '1.2.0'; } + //#endregion + + if (foundry.utils.isNewerVersion('1.2.2', lastMigrationVersion)) { + /* Delete any null party members caused by characters being deleted in the world prior to it being handled */ + for (let party of game.actors.filter(x => x.type === 'party')) { + await party.update({ 'system.partyMembers': party.system.partyMembers.filter(x => x) }); + } + + lastMigrationVersion = '1.2.2'; + } await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion); }