Skip to content

Commit

Permalink
Merge branch 'v9-ready' into '1.5.x'
Browse files Browse the repository at this point in the history
Update system for compatibility with v9

See merge request foundrynet/dnd5e!457
  • Loading branch information
Fyorl committed Dec 14, 2021
2 parents 7a6763c + ee80a16 commit 160fdd7
Show file tree
Hide file tree
Showing 14 changed files with 460 additions and 460 deletions.
7 changes: 4 additions & 3 deletions dnd5e.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,12 @@ Hooks.once("init", function() {
},
macros: macros,
migrations: migrations,
rollItemMacro: macros.rollItemMacro
rollItemMacro: macros.rollItemMacro,
isV9: !foundry.utils.isNewerVersion("9.224", game.version ?? game.data.version)
};

// This will be removed when dnd5e minimum core version is updated to v9.
if ( foundry.utils.isNewerVersion("9.224", game.data.version) ) dice.shimIsDeterministic();
if ( !game.dnd5e.isV9 ) dice.shimIsDeterministic();

// Record Configuration Values
CONFIG.DND5E = DND5E;
Expand Down Expand Up @@ -266,7 +267,7 @@ Hooks.once("ready", function() {
// Determine whether a system migration is required and feasible
if ( !game.user.isGM ) return;
const currentVersion = game.settings.get("dnd5e", "systemMigrationVersion");
const NEEDS_MIGRATION_VERSION = "1.5.5";
const NEEDS_MIGRATION_VERSION = "1.5.6";
const COMPATIBLE_MIGRATION_VERSION = 0.80;
const totalDocuments = game.actors.size + game.scenes.size + game.items.size;
if ( !currentVersion && totalDocuments === 0 ) return game.settings.set("dnd5e", "systemMigrationVersion", game.system.data.version);
Expand Down
2 changes: 1 addition & 1 deletion json/icon-migration.json
Original file line number Diff line number Diff line change
Expand Up @@ -849,4 +849,4 @@
"systems/dnd5e/icons/skills/yellow_41.jpg": "icons/sundries/documents/document-torn-diagram-tan.webp",
"systems/dnd5e/icons/skills/yellow_42.jpg": "icons/magic/nature/tree-bare-glow-yellow.webp",
"systems/dnd5e/icons/skills/yellow_43.jpg": "icons/magic/death/skeleton-dinosaur-skull-tan.webp"
}
}
404 changes: 404 additions & 0 deletions json/spell-icon-migration.json

Large diffs are not rendered by default.

404 changes: 0 additions & 404 deletions json/undo-icons.json

This file was deleted.

2 changes: 1 addition & 1 deletion module/active-effect.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class ActiveEffect5e extends ActiveEffect {
/**
* Manage Active Effect instances through the Actor Sheet via effect control buttons.
* @param {MouseEvent} event The left-click event on the effect control
* @param {Actor|Item} owner The owning entity which manages this effect
* @param {Actor|Item} owner The owning document which manages this effect
* @returns {Promise|null} Promise that resolves when the changes are complete.
*/
static onManageActiveEffect(event, owner) {
Expand Down
8 changes: 5 additions & 3 deletions module/actor/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -1820,22 +1820,24 @@ export default class Actor5e extends Actor {
/* -------------------------------------------- */

/**
* Add additional system-specific sidebar directory context menu options for Actor entities
* Add additional system-specific sidebar directory context menu options for Actor documents
* @param {jQuery} html The sidebar HTML
* @param {Array} entryOptions The default array of context menu options
*/
static addDirectoryContextOptions(html, entryOptions) {
const useEntity = foundry.utils.isNewerVersion("9", game.version ?? game.data.version);
const idAttr = useEntity ? "entityId" : "documentId";
entryOptions.push({
name: "DND5E.PolymorphRestoreTransformation",
icon: '<i class="fas fa-backward"></i>',
callback: li => {
const actor = game.actors.get(li.data("entityId"));
const actor = game.actors.get(li.data(idAttr));
return actor.revertOriginalForm();
},
condition: li => {
const allowed = game.settings.get("dnd5e", "allowPolymorphing");
if ( !allowed && !game.user.isGM ) return false;
const actor = game.actors.get(li.data("entityId"));
const actor = game.actors.get(li.data(idAttr));
return actor && actor.isPolymorphed;
}
});
Expand Down
2 changes: 1 addition & 1 deletion module/actor/sheets/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ export default class ActorSheet5e extends ActorSheet {
let sourceActor = null;
if (data.pack) {
const pack = game.packs.find(p => p.collection === data.pack);
sourceActor = await pack.getEntity(data.id);
sourceActor = await pack.getDocument(data.id);
} else {
sourceActor = game.actors.get(data.id);
}
Expand Down
2 changes: 1 addition & 1 deletion module/actor/sheets/npc.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export default class ActorSheet5eNPC extends ActorSheet5e {
event.preventDefault();
const formula = this.actor.data.data.attributes.hp.formula;
if ( !formula ) return;
const hp = new Roll(formula).roll().total;
const hp = new Roll(formula).roll({async: false}).total;
AudioHelper.play({src: CONFIG.sounds.dice});
this.actor.update({"data.attributes.hp.value": hp, "data.attributes.hp.max": hp});
}
Expand Down
2 changes: 1 addition & 1 deletion module/apps/ability-use-dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class AbilityUseDialog extends Dialog {
this.options.classes = ["dnd5e", "dialog"];

/**
* Store a reference to the Item entity being used
* Store a reference to the Item document being used
* @type {Item5e}
*/
this.item = item;
Expand Down
2 changes: 1 addition & 1 deletion module/apps/select-items-prompt.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class SelectItemsPrompt extends Dialog {
this.options.classes = ["dnd5e", "dialog", "select-items-prompt", "sheet"];

/**
* Store a reference to the Item entities being used
* Store a reference to the Item documents being used
* @type {Array<Item5e>}
*/
this.items = items;
Expand Down
2 changes: 1 addition & 1 deletion module/apps/short-rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default class ShortRestDialog extends Dialog {
super(dialogData, options);

/**
* Store a reference to the Actor entity which is resting
* Store a reference to the Actor document which is resting
* @type {Actor}
*/
this.actor = actor;
Expand Down
16 changes: 8 additions & 8 deletions module/item/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ export default class Item5e extends Item {
/**
* Update a label to the Item detailing its total to hit bonus.
* Sources:
* - item entity's innate attack bonus
* - item document's innate attack bonus
* - item's actor's proficiency bonus if applicable
* - item's actor's global bonuses to the given item type
* - item's ammunition if applicable
Expand Down Expand Up @@ -427,8 +427,8 @@ export default class Item5e extends Item {
/**
* Retrieve an item's critical hit threshold. Uses the smallest value from among the
* following sources:
* - item entity
* - item entity's actor (if it has one)
* - item document
* - item document's actor (if it has one)
* - the constant '20'
*
* @returns {number|null} The minimum value that must be rolled to be considered a critical hit.
Expand Down Expand Up @@ -737,7 +737,7 @@ export default class Item5e extends Item {
* Display the chat card for an Item as a Chat Message
* @param {object} [options] Options which configure the display of the item chat card
* @param {string} [options.rollMode] The message visibility mode to apply to the created card
* @param {boolean} [options.createMessage] Whether to automatically create a ChatMessage entity (if true), or only
* @param {boolean} [options.createMessage] Whether to automatically create a ChatMessage document (if true), or only
* return the prepared message data (if false)
* @returns {ChatMessage|object} Chat message if `createMessage` is true, otherwise an object containing message data.
*/
Expand Down Expand Up @@ -1214,7 +1214,7 @@ export default class Item5e extends Item {
const title = `${this.name} - ${game.i18n.localize("DND5E.OtherFormula")}`;

// Invoke the roll and submit it to chat
const roll = new Roll(rollData.item.formula, rollData).roll();
const roll = await new Roll(rollData.item.formula, rollData).roll({async: true});
roll.toMessage({
speaker: ChatMessage.getSpeaker({actor: this.actor}),
flavor: title,
Expand All @@ -1235,7 +1235,7 @@ export default class Item5e extends Item {
if ( !data.recharge.value ) return;

// Roll the check
const roll = new Roll("1d6").roll();
const roll = await new Roll("1d6").roll({async: true});
const success = roll.total >= parseInt(data.recharge.value);

// Display a Chat Message
Expand Down Expand Up @@ -1450,7 +1450,7 @@ export default class Item5e extends Item {
/**
* Get the Actor which is the author of a chat card
* @param {HTMLElement} card The chat card being used
* @returns {Actor|null} The Actor entity or null
* @returns {Actor|null} The Actor document or null
* @private
*/
static async _getChatCardActor(card) {
Expand All @@ -1472,7 +1472,7 @@ export default class Item5e extends Item {
/**
* Get the Actor which is the author of a chat card
* @param {HTMLElement} card The chat card being used
* @returns {Actor[]} An Array of Actor entities, if any
* @returns {Actor[]} An Array of Actor documents, if any
* @private
*/
static _getChatCardTargets(card) {
Expand Down
61 changes: 29 additions & 32 deletions module/migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const migrateWorld = async function() {
// Migrate World Compendium Packs
for ( let p of game.packs ) {
if ( p.metadata.package !== "world" ) continue;
if ( !["Actor", "Item", "Scene"].includes(p.metadata.entity) ) continue;
if ( !["Actor", "Item", "Scene"].includes(p.documentName) ) continue;
await migrateCompendium(p);
}

Expand All @@ -81,13 +81,13 @@ export const migrateWorld = async function() {
/* -------------------------------------------- */

/**
* Apply migration rules to all Entities within a single Compendium pack
* @param {Compendium} pack Pack to be migrated.
* Apply migration rules to all Documents within a single Compendium pack
* @param {CompendiumCollection} pack Pack to be migrated.
* @returns {Promise}
*/
export const migrateCompendium = async function(pack) {
const entity = pack.metadata.entity;
if ( !["Actor", "Item", "Scene"].includes(entity) ) return;
const documentName = pack.documentName;
if ( !["Actor", "Item", "Scene"].includes(documentName) ) return;

const migrationData = await getMigrationData();

Expand All @@ -103,7 +103,7 @@ export const migrateCompendium = async function(pack) {
for ( let doc of documents ) {
let updateData = {};
try {
switch (entity) {
switch (documentName) {
case "Actor":
updateData = migrateActorData(doc.toObject(), migrationData);
break;
Expand All @@ -118,30 +118,30 @@ export const migrateCompendium = async function(pack) {
// Save the entry, if data was changed
if ( foundry.utils.isObjectEmpty(updateData) ) continue;
await doc.update(updateData);
console.log(`Migrated ${entity} entity ${doc.name} in Compendium ${pack.collection}`);
console.log(`Migrated ${documentName} document ${doc.name} in Compendium ${pack.collection}`);
}

// Handle migration failures
catch(err) {
err.message = `Failed dnd5e system migration for entity ${doc.name} in pack ${pack.collection}: ${err.message}`;
err.message = `Failed dnd5e system migration for document ${doc.name} in pack ${pack.collection}: ${err.message}`;
console.error(err);
}
}

// Apply the original locked status for the pack
await pack.configure({locked: wasLocked});
console.log(`Migrated all ${entity} entities from Compendium ${pack.collection}`);
console.log(`Migrated all ${documentName} documents from Compendium ${pack.collection}`);
};

/**
* Apply 'smart' AC migration to a given Actor compendium. This will perform the normal AC migration but additionally
* check to see if the actor has armor already equipped, and opt to use that instead.
* @param {Compendium|string} pack Pack or name of pack to migrate.
* @param {CompendiumCollection|string} pack Pack or name of pack to migrate.
* @returns {Promise}
*/
export const migrateArmorClass = async function(pack) {
if ( typeof pack === "string" ) pack = game.packs.get(pack);
if ( pack.metadata.entity !== "Actor" ) return;
if ( pack.documentName !== "Actor" ) return;
const wasLocked = pack.locked;
await pack.configure({locked: false});
const actors = await pack.getDocuments();
Expand Down Expand Up @@ -178,11 +178,11 @@ export const migrateArmorClass = async function(pack) {
};

/* -------------------------------------------- */
/* Entity Type Migration Helpers */
/* Document Type Migration Helpers */
/* -------------------------------------------- */

/**
* Migrate a single Actor entity to incorporate latest data model changes
* Migrate a single Actor document to incorporate latest data model changes
* Return an Object of updateData to be applied
* @param {object} actor The actor data object to update
* @param {object} [migrationData] Additional data to perform the migration
Expand Down Expand Up @@ -257,7 +257,7 @@ function cleanActorData(actorData) {
/* -------------------------------------------- */

/**
* Migrate a single Item entity to incorporate latest data model changes
* Migrate a single Item document to incorporate latest data model changes
*
* @param {object} item Item data to migrate
* @param {object} [migrationData] Additional data to perform the migration
Expand Down Expand Up @@ -342,12 +342,14 @@ export const getMigrationData = async function() {
try {
let res = await fetch("systems/dnd5e/json/icon-migration.json");
data.iconMap = await res.json();
res = await fetch("systems/dnd5e/json/undo-icons.json");
data.undoMap = await res.json();
if ( game.dnd5e.isV9 ) {
res = await fetch("systems/dnd5e/json/spell-icon-migration.json");
const spellIcons = await res.json();
data.iconMap = {...data.iconMap, ...spellIcons};
}
} catch(err) {
console.warn(`Failed to retrieve icon migration data: ${err.message}`);
}

return data;
};

Expand Down Expand Up @@ -679,24 +681,19 @@ function _migrateItemCriticalData(item, updateData) {
* @returns {object} The updateData to apply
* @private
*/
function _migrateItemIcon(item, updateData, {iconMap, undoMap}={}) {
function _migrateItemIcon(item, updateData, {iconMap}={}) {
if ( iconMap && item.img?.startsWith("systems/dnd5e/icons/") ) {
const rename = iconMap[item.img];
if ( rename ) updateData.img = rename;
}

if ( undoMap ) {
const rename = undoMap[item.img];
if ( rename ) updateData.img = rename;
}
return updateData;
}

/* -------------------------------------------- */

/**
* A general tool to purge flags from all entities in a Compendium pack.
* @param {Compendium} pack The compendium pack to clean.
* A general tool to purge flags from all documents in a Compendium pack.
* @param {CompendiumCollection} pack The compendium pack to clean.
* @private
*/
export async function purgeFlags(pack) {
Expand All @@ -705,17 +702,17 @@ export async function purgeFlags(pack) {
return flags5e ? {dnd5e: flags5e} : {};
};
await pack.configure({locked: false});
const content = await pack.getContent();
for ( let entity of content ) {
const update = {_id: entity.id, flags: cleanFlags(entity.data.flags)};
if ( pack.entity === "Actor" ) {
update.items = entity.data.items.map(i => {
const content = await pack.getDocuments();
for ( let doc of content ) {
const update = {flags: cleanFlags(doc.data.flags)};
if ( pack.documentName === "Actor" ) {
update.items = doc.data.items.map(i => {
i.flags = cleanFlags(i.flags);
return i;
});
}
await pack.updateEntity(update, {recursive: false});
console.log(`Purged flags from ${entity.name}`);
await doc.update(update, {recursive: false});
console.log(`Purged flags from ${doc.name}`);
}
await pack.configure({locked: true});
}
Expand Down
6 changes: 3 additions & 3 deletions system.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "dnd5e",
"title": "DnD5e - Fifth Edition System",
"description": "A system for playing the fifth edition of the worlds most popular role-playing game in the Foundry Virtual Tabletop environment.",
"version": "1.5.5",
"version": "1.5.6",
"author": "Atropos",
"scripts": [],
"esmodules": ["dnd5e.js"],
Expand Down Expand Up @@ -92,8 +92,8 @@
"primaryTokenAttribute": "attributes.hp",
"secondaryTokenAttribute": null,
"minimumCoreVersion": "0.8.9",
"compatibleCoreVersion": "0.8.9",
"compatibleCoreVersion": "9",
"url": "https://gitlab.com/foundrynet/dnd5e",
"manifest": "https://gitlab.com/api/v4/projects/foundrynet%2Fdnd5e/packages/generic/dnd5e/latest/system.json",
"download": "https://gitlab.com/foundrynet/dnd5e/-/releases/release-1.5.5/downloads/dnd5e-release-1.5.5.zip"
"download": "https://gitlab.com/foundrynet/dnd5e/-/releases/release-1.5.6/downloads/dnd5e-release-1.5.6.zip"
}

0 comments on commit 160fdd7

Please sign in to comment.