diff --git a/CHANGELOG.md b/CHANGELOG.md index 94f8876..6f9c1a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ __! Be certain to carefully back up any critical user data before installing thi - Updated the System to FoundryVTT v10. - Removed restriction on technique types when dropping a technique (Sheet and 20Q. #39). - Added a `game.user.isFirstGM` property for some traitements (socket and migration) to prevent multiple executions with multiple GM connected. +- Added `itemUuid` to Roll/RnK for technique and weapons to be readable in ChatMessage (use `fromUuid()` / `fromUuidSync()` to get the object). - Updated the initiative behaviour, he now open the DicePicker for connected players. - Added socket API `openDicePicker` to remotely open the DicePicker (see usage below). diff --git a/system/scripts/actors/base-character-sheet.js b/system/scripts/actors/base-character-sheet.js index af8fe17..73f0734 100644 --- a/system/scripts/actors/base-character-sheet.js +++ b/system/scripts/actors/base-character-sheet.js @@ -594,15 +594,21 @@ export class BaseCharacterSheetL5r5e extends BaseSheetL5r5e { } /** - * Get the skillId for this weaponId + * Get the skillId and uuid for this weaponId * @private */ - _getWeaponSkillId(weaponId) { - const item = this.actor.items.get(weaponId); - if (!!item && item.type === "weapon") { - return item.system.skill; + _getWeaponInfos(weaponId) { + if (!weaponId) { + return null; } - return null; + const item = this.actor.items.get(weaponId); + if (!item || item.type !== "weapon") { + return null; + } + return { + uuid: item.uuid, + skill: item.system.skill, + }; } /** @@ -614,19 +620,15 @@ export class BaseCharacterSheetL5r5e extends BaseSheetL5r5e { event.preventDefault(); event.stopPropagation(); const li = $(event.currentTarget); - let skillId = li.data("skill") || null; - - const weaponId = li.data("weapon-id") || null; - if (weaponId) { - skillId = this._getWeaponSkillId(weaponId); - } + const weapon = this._getWeaponInfos(li.data("weapon-id") || null); new game.l5r5e.DicePickerDialog({ ringId: li.data("ring") || null, - skillId: skillId, + skillId: weapon?.skill || li.data("skill") || null, skillCatId: li.data("skillcat") || null, isInitiativeRoll: li.data("initiative") || false, actor: this.actor, + itemUuid: weapon?.uuid, }).render(true); } @@ -651,6 +653,7 @@ export class BaseCharacterSheetL5r5e extends BaseSheetL5r5e { ringId: itemData.ring || null, difficulty: itemData.difficulty || null, skillsList: itemData.skill || null, + itemUuid: item.uuid, }).render(true); } } diff --git a/system/scripts/dice/dice-picker-dialog.js b/system/scripts/dice/dice-picker-dialog.js index 0a0aa10..4aca5f6 100644 --- a/system/scripts/dice/dice-picker-dialog.js +++ b/system/scripts/dice/dice-picker-dialog.js @@ -45,6 +45,7 @@ export class DicePickerDialog extends FormApplication { targetInfos: null, useVoidPoint: false, isInitiativeRoll: false, + itemUuid: null, }; /** @@ -107,8 +108,9 @@ export class DicePickerDialog extends FormApplication { * difficulty number (0-9) * difficultyHidden boolean * isInitiativeRoll boolean + * itemUuid string * - * @param options actor, actorId, ringId, actorName, skillId, skillCatId, difficulty, difficultyHidden, isInitiativeRoll + * @param options actor, actorId, ringId, actorName, skillId, skillCatId, difficulty, difficultyHidden, isInitiativeRoll, itemUuid */ constructor(options = {}) { super({}, options); @@ -165,6 +167,11 @@ export class DicePickerDialog extends FormApplication { // InitiativeRoll this.object.isInitiativeRoll = !!options.isInitiativeRoll; + + // Item UUID (weapon/technique) + if (options.itemUuid) { + this.object.itemUuid = options.itemUuid; + } } /** @@ -533,11 +540,12 @@ export class DicePickerDialog extends FormApplication { // Initiative roll let msgOptions = { skillId: this.object.skill.id, + itemUuid: this.object.itemUuid, + rnkMessage: null, difficulty: this.object.difficulty.value, - difficultyHidden: this.object.difficulty.hidden, useVoidPoint: this.object.useVoidPoint, skillAssistance: this.object.skill.assistance, - rnkMessage: null, + difficultyHidden: this.object.difficulty.hidden, }; await this._actor.rollInitiative({ @@ -558,12 +566,13 @@ export class DicePickerDialog extends FormApplication { roll.actor = this._actor; roll.l5r5e.stance = this.object.ring.id; roll.l5r5e.skillId = this.object.skill.id; + roll.l5r5e.itemUuid = this.object.itemUuid; roll.l5r5e.skillCatId = this.object.skill.cat; roll.l5r5e.difficulty = this.object.difficulty.value; - roll.l5r5e.difficultyHidden = this.object.difficulty.hidden; + roll.l5r5e.targetInfos = this.object.targetInfos; roll.l5r5e.voidPointUsed = this.object.useVoidPoint; roll.l5r5e.skillAssistance = this.object.skill.assistance; - roll.l5r5e.targetInfos = this.object.targetInfos; + roll.l5r5e.difficultyHidden = this.object.difficulty.hidden; await roll.roll(); message = await roll.toMessage(); diff --git a/system/scripts/dice/roll.js b/system/scripts/dice/roll.js index 5c4f58d..f056fe9 100644 --- a/system/scripts/dice/roll.js +++ b/system/scripts/dice/roll.js @@ -25,6 +25,7 @@ export class RollL5r5e extends Roll { skillCatId: "", skillId: "", stance: "", + itemUuid: null, strifeApplied: 0, summary: { totalSuccess: 0, @@ -359,7 +360,7 @@ export class RollL5r5e extends Roll { rollMode: rMode, temporary: !create, }); - return create ? message : message.data; + return message; } /** @override */ diff --git a/system/scripts/item.js b/system/scripts/item.js index 8c7513f..3c10adb 100644 --- a/system/scripts/item.js +++ b/system/scripts/item.js @@ -15,6 +15,44 @@ export class ItemL5r5e extends Item { return super.actor || game.actors.get(this.system.parent_id?.actor_id) || null; } + /** + * A Universally Unique Identifier (uuid) for this Document instance patched for embedded items on items + * @type {string} + * @memberof ClientDocumentMixin# + */ + get uuid() { + const uuid = []; + const parents = this.system.parent_id; + + if (parents?.item_id) { + if (parents?.actor_id) { + uuid.push(`Actor.${parents.actor_id}`); + } + uuid.push(`Item.${parents.item_id}`); + } + uuid.push(super.uuid); + + return uuid.join("."); + } + + /** + * Obtain a reference to the Array of source data within the data object for a certain embedded Document name + * + * TODO probably useless if we can add "items" in metadata.embedded, but no clue how to. + * + * @param {string} embeddedName The name of the embedded Document type + * @return {Collection} The Collection instance of embedded Documents of the requested type + */ + getEmbeddedCollection(embeddedName) { + const collectionName = embeddedName === "Item" ? "items" : this.constructor.metadata.embedded[embeddedName]; + if (!collectionName) { + throw new Error( + `${embeddedName} is not a valid embedded Document within the ${this.documentName} Document` + ); + } + return this[collectionName]; + } + /** * Create a new entity using provided input data * @override