From 0f1ecacc3ef0615e5a88013747f61a895ab180a5 Mon Sep 17 00:00:00 2001 From: Jack Holloway Date: Wed, 13 Sep 2023 22:26:33 +0100 Subject: [PATCH] Move Iconizer functions --- src/api.js | 8 +- src/apps/DDBCharacterManager.js | 25 +- src/lib/Iconizer.js | 512 ++++++++++++++++++++--- src/muncher/adventure/ThirdPartyMunch.js | 4 +- src/muncher/import.js | 374 +---------------- src/muncher/importMonster.js | 13 +- src/muncher/items.js | 5 +- src/muncher/spells.js | 5 +- src/parser/DDBMonsterFactory.js | 5 +- 9 files changed, 479 insertions(+), 472 deletions(-) diff --git a/src/api.js b/src/api.js index e75b07ae5..5b33f2dd3 100644 --- a/src/api.js +++ b/src/api.js @@ -14,7 +14,7 @@ import { checkCobalt } from "./lib/Secrets.js"; // import { base64Check } from "./lib/base64Check.js"; import { getFeats } from "./muncher/feats/feats.js"; import { loadMacroFile, generateItemMacroFlag, createMacro, executeDDBMacro, MACROS } from "./effects/macros.js"; -import { iconPath, generateIcon } from "./lib/Iconizer.js"; +import Iconizer from "./lib/Iconizer.js"; import { loadSRDRules, importCacheLoad } from "./lib/DDBTemplateStrings.js"; import { getNPCImage } from "./muncher/importMonster.js"; import PatreonHelper from "./lib/PatreonHelper.js"; @@ -143,9 +143,9 @@ export function registerApi() { updateDDBCharacter, updateWorldMonsters, - getIconPath: iconPath, - iconPath, - generateIcon, + getIconPath: Iconizer.iconPath, + iconPath: Iconizer.iconPath, + generateIcon: Iconizer.generateIcon, loadSRDRules, importCacheLoad, diff --git a/src/apps/DDBCharacterManager.js b/src/apps/DDBCharacterManager.js index f01b75d41..f2980fef0 100755 --- a/src/apps/DDBCharacterManager.js +++ b/src/apps/DDBCharacterManager.js @@ -10,17 +10,10 @@ import { addMagicItemSpells, getCompendiumItems, getSRDCompendiumItems, - copySRDIcons, - getDDBEquipmentIcons, - getDDBSpellSchoolIcons, - getDDBGenericItemIcons, - addItemEffectIcons, - retainExistingIcons, getIndividualOverrideItems, - preFetchDDBIconImages, } from "../muncher/import.js"; import { addItemsDAESRD } from "../muncher/dae.js"; -import { copyInbuiltIcons } from "../lib/Iconizer.js"; +import Iconizer from "../lib/Iconizer.js"; import { updateDDBCharacter } from "../updater/character.js"; import { generateCharacterExtras } from "../parser/DDBExtras.js"; import DICTIONARY from "../dictionary.js"; @@ -682,7 +675,7 @@ export default class DDBCharacterManager extends FormApplication { const daeMidiInstalled = game.modules.get("midi-srd")?.active; const daeInstalled = game.modules.get("dae")?.active; - await preFetchDDBIconImages(); + await Iconizer.preFetchDDBIconImages(); // if we still have items to add, add them if (items.length > 0) { @@ -691,27 +684,27 @@ export default class DDBCharacterManager extends FormApplication { if (ddbItemIcons) { this.showCurrentTask("Fetching DDB Inventory Images"); - items = await getDDBEquipmentIcons(items, true); + items = await Iconizer.getDDBEquipmentIcons(items, true); } if (useInbuiltIcons) { this.showCurrentTask("Adding SRD Icons"); - items = await copyInbuiltIcons(items); + items = await Iconizer.copyInbuiltIcons(items); } if (useSRDCompendiumIcons && !useSRDCompendiumItems) { this.showCurrentTask("Adding SRD Icons"); - items = await copySRDIcons(items); + items = await Iconizer.copySRDIcons(items); } if (ddbSpellIcons) { this.showCurrentTask("Fetching DDB Spell School Images"); - items = await getDDBSpellSchoolIcons(items, true); + items = await Iconizer.getDDBSpellSchoolIcons(items, true); } if (ddbGenericItemIcons) { this.showCurrentTask("Fetching DDB Generic Item Images"); - items = await getDDBGenericItemIcons(items, true); + items = await Iconizer.getDDBGenericItemIcons(items, true); } if (this.settings.activeEffectCopy) { @@ -725,10 +718,10 @@ export default class DDBCharacterManager extends FormApplication { } if (daeInstalled && (this.settings.addItemEffects || this.settings.addCharacterEffects)) { - items = await addItemEffectIcons(items); + items = await Iconizer.addItemEffectIcons(items); } - items = await retainExistingIcons(items); + items = await Iconizer.retainExistingIcons(items); } items = items.map((item) => { diff --git a/src/lib/Iconizer.js b/src/lib/Iconizer.js index 8ce7bbb51..dd18804e1 100644 --- a/src/lib/Iconizer.js +++ b/src/lib/Iconizer.js @@ -1,5 +1,10 @@ +import DDBMuncher from "../apps/DDBMuncher.js"; +import DICTIONARY from "../dictionary.js"; import logger from "../logger.js"; +import SETTINGS from "../settings.js"; +import CompendiumHelper from "./CompendiumHelper.js"; import FileHelper from "./FileHelper.js"; +import NameMatcher from "./NameMatcher.js"; // const BASE_PATH = ROUTE_PREFIX ? `/${ROUTE_PREFIX}` : ""; @@ -149,62 +154,6 @@ async function loadIconMaps(types) { return Promise.all(promises); } -export async function iconPath(item, monster = false, monsterName = "") { - const itemTypes = [item.type]; - if (monster) itemTypes.push("monster"); - await loadIconMaps(itemTypes); - - let iconPath; - // logger.debug(`Inbuilt icon match started for ${item.name} [${item.type}]`); - // if we have a monster lets check the monster dict first - if (monster) { - const monsterPath = getIconPath(item, "monster", monsterName); - if (monsterPath) { - iconPath = monsterPath; - } - } - if (!iconPath) iconPath = getIconPath(item, item.type); - return iconPath; -} - -export async function copyInbuiltIcons(items, monster = false, monsterName = "") { - // get unique array of item types to be matching - const itemTypes = items.map((item) => item.type).filter((item, i, ar) => ar.indexOf(item) === i); - - if (monster) itemTypes.push("monster"); - await loadIconMaps(itemTypes); - - return new Promise((resolve) => { - const iconItems = items.map((item) => { - if (getProperty(item, "flags.ddbimporter.keepIcon") !== true) { - // logger.debug(`Inbuilt icon match started for ${item.name} [${item.type}]`); - // if we have a monster lets check the monster dict first - if (monster && !["spell"].includes(item.type)) { - const monsterPath = getIconPath(item, "monster", monsterName); - if (monsterPath) { - item.img = monsterPath; - return item; - } - } - const pathMatched = getIconPath(item, item.type); - if (pathMatched) { - item.img = pathMatched; - if (item.effects) { - item.effects.forEach((effect) => { - if (!effect.icon || effect.icon === "") { - effect.icon = pathMatched; - } - }); - } - } - } - return item; - }); - resolve(iconItems); - }); -} - - const STUBS = { 1: ` @@ -248,18 +197,443 @@ function unPad(match, p1) { } } -export async function generateIcon(adventure, title) { - // default path - let iconPath = "icons/svg/book.svg"; - let stub = title.trim().split(".")[0].split(" ")[0]; - stub = stub.replace(/(\d+)/, unPad); - if (stub.length <= 4) { - iconPath = `assets/icons/${stub}.svg`; - logger.info(stub); - let content = STUBS[stub.length]; - content = content.replace("REPLACEME", stub); - const uploadPath = await adventure.importRawFile(iconPath, content, "text/plain", true); - return uploadPath; +export default class Iconizer { + + static async generateIcon(adventure, title) { + // default path + let iconPath = "icons/svg/book.svg"; + let stub = title.trim().split(".")[0].split(" ")[0]; + stub = stub.replace(/(\d+)/, unPad); + if (stub.length <= 4) { + iconPath = `assets/icons/${stub}.svg`; + logger.info(stub); + let content = STUBS[stub.length]; + content = content.replace("REPLACEME", stub); + const uploadPath = await adventure.importRawFile(iconPath, content, "text/plain", true); + return uploadPath; + } + return iconPath; + } + + static async iconPath(item, monster = false, monsterName = "") { + const itemTypes = [item.type]; + if (monster) itemTypes.push("monster"); + await loadIconMaps(itemTypes); + + let iconPath; + // logger.debug(`Inbuilt icon match started for ${item.name} [${item.type}]`); + // if we have a monster lets check the monster dict first + if (monster) { + const monsterPath = getIconPath(item, "monster", monsterName); + if (monsterPath) { + iconPath = monsterPath; + } + } + if (!iconPath) iconPath = getIconPath(item, item.type); + return iconPath; + } + + static async copyInbuiltIcons(items, monster = false, monsterName = "") { + // get unique array of item types to be matching + const itemTypes = items.map((item) => item.type).filter((item, i, ar) => ar.indexOf(item) === i); + + if (monster) itemTypes.push("monster"); + await loadIconMaps(itemTypes); + + return new Promise((resolve) => { + const iconItems = items.map((item) => { + if (getProperty(item, "flags.ddbimporter.keepIcon") !== true) { + // logger.debug(`Inbuilt icon match started for ${item.name} [${item.type}]`); + // if we have a monster lets check the monster dict first + if (monster && !["spell"].includes(item.type)) { + const monsterPath = getIconPath(item, "monster", monsterName); + if (monsterPath) { + item.img = monsterPath; + return item; + } + } + const pathMatched = getIconPath(item, item.type); + if (pathMatched) { + item.img = pathMatched; + if (item.effects) { + item.effects.forEach((effect) => { + if (!effect.icon || effect.icon === "") { + effect.icon = pathMatched; + } + }); + } + } + } + return item; + }); + resolve(iconItems); + }); + } + + static async getSRDIconMatch(type) { + const compendiumName = SETTINGS.SRD_COMPENDIUMS.find((c) => c.type == type).name; + const srdPack = CompendiumHelper.getCompendium(compendiumName); + const srdIndices = ["name", "img", "prototypeToken.texture.src", "type", "system.activation", "prototypeToken.texture.scaleY", "prototypeToken.texture.scaleX"]; + const index = await srdPack.getIndex({ fields: srdIndices }); + return index; + } + + static async getSRDImageLibrary() { + if (CONFIG.DDBI.SRD_LOAD.mapLoaded) return CONFIG.DDBI.SRD_LOAD.iconMap; + const compendiumFeatureItems = await Iconizer.getSRDIconMatch("features"); + const compendiumInventoryItems = await Iconizer.getSRDIconMatch("inventory"); + const compendiumSpellItems = await Iconizer.getSRDIconMatch("spells"); + const compendiumMonsterFeatures = await Iconizer.getSRDIconMatch("monsterfeatures"); + const compendiumMonsters = await Iconizer.getSRDIconMatch("monsters"); + + // eslint-disable-next-line require-atomic-updates + CONFIG.DDBI.SRD_LOAD.iconMap = [ + ...compendiumInventoryItems, + ...compendiumSpellItems, + ...compendiumFeatureItems, + ...compendiumMonsterFeatures, + ...compendiumMonsters, + ]; + return CONFIG.DDBI.SRD_LOAD.iconMap; + } + + static async copySRDIcons(items, srdImageLibrary = null, nameMatchList = []) { + // eslint-disable-next-line require-atomic-updates + if (!srdImageLibrary) srdImageLibrary = await Iconizer.getSRDImageLibrary(); + + return new Promise((resolve) => { + const srdItems = items.map((item) => { + logger.debug(`Matching ${item.name}`); + const nameMatch = nameMatchList.find((m) => m.name === item.name); + if (nameMatch) { + item.img = nameMatch.img; + } else { + NameMatcher.looseItemNameMatch(item, srdImageLibrary, true).then((match) => { + if (match) { + srdImageLibrary.push({ name: item.name, img: match.img }); + item.img = match.img; + } + }); + } + return item; + + }); + resolve(srdItems); + }); + } + + static async retainExistingIcons(items) { + return new Promise((resolve) => { + const newItems = items.map((item) => { + if (item.flags.ddbimporter?.ignoreIcon) { + logger.debug(`Retaining icon for ${item.name} to ${item.flags.ddbimporter.matchedImg}`); + item.img = item.flags.ddbimporter.matchedImg; + } + return item; + }); + resolve(newItems); + }); + } + + static async getDDBItemImages(items, download) { + DDBMuncher.munchNote(`Fetching DDB Item Images`); + const downloadImages = (download) ? true : game.settings.get(SETTINGS.MODULE_ID, "munching-policy-download-images"); + const remoteImages = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-remote-images"); + const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); + const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); + + const itemMap = items.map(async (item) => { + let itemImage = { + name: item.name, + type: item.type, + img: null, + large: null, + }; + + const pathPostfix = useDeepPaths ? `/item/${item.type}` : ""; + + if (item.flags && item.flags.ddbimporter && item.flags.ddbimporter && item.flags.ddbimporter.dndbeyond) { + if (item.flags.ddbimporter.dndbeyond.avatarUrl) { + const avatarUrl = item.flags.ddbimporter.dndbeyond['avatarUrl']; + if (avatarUrl && avatarUrl != "") { + DDBMuncher.munchNote(`Downloading ${item.name} image`); + const imageNamePrefix = useDeepPaths ? "" : "item"; + const downloadOptions = { type: "item", name: item.name, download: downloadImages, remoteImages, targetDirectory, pathPostfix, imageNamePrefix }; + const smallImage = await FileHelper.getImagePath(avatarUrl, downloadOptions); + logger.debug(`Final image ${smallImage}`); + itemImage.img = smallImage; + } + } + if (item.flags.ddbimporter.dndbeyond.largeAvatarUrl) { + const largeAvatarUrl = item.flags.ddbimporter.dndbeyond['largeAvatarUrl']; + if (largeAvatarUrl && largeAvatarUrl != "") { + const imageNamePrefix = useDeepPaths ? "" : "item"; + const name = useDeepPaths ? `${item.name}-large` : item.name; + const downloadOptions = { type: "item-large", name, download: downloadImages, remoteImages, targetDirectory, pathPostfix, imageNamePrefix }; + const largeImage = await FileHelper.getImagePath(largeAvatarUrl, downloadOptions); + itemImage.large = largeImage; + if (!itemImage.img) itemImage.img = largeImage; + } + } + } + + DDBMuncher.munchNote(""); + return itemImage; + }); + + return Promise.all(itemMap); + } + + + static async getDDBGenericItemImages(download) { + DDBMuncher.munchNote(`Fetching DDB Generic Item icons`); + const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); + const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); + const imageNamePrefix = useDeepPaths ? "" : "item"; + const pathPostfix = useDeepPaths ? "/ddb/item" : ""; + + const itemMap = DICTIONARY.items.map(async (item) => { + const downloadOptions = { type: "item", name: item.filterType, download, targetDirectory, pathPostfix, imageNamePrefix }; + const img = await FileHelper.getImagePath(item.img, downloadOptions); + let itemIcons = { + filterType: item.filterType, + img: img, + }; + return itemIcons; + }); + + DDBMuncher.munchNote(""); + return Promise.all(itemMap); + } + + + static async getDDBGenericLootImages(download) { + DDBMuncher.munchNote(`Fetching DDB Generic Loot icons`); + const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); + const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); + const imageNamePrefix = useDeepPaths ? "" : "equipment"; + const pathPostfix = useDeepPaths ? "/ddb/loot" : ""; + + const itemMap = DICTIONARY.genericItemIcons.map(async (item) => { + const downloadOptions = { type: "equipment", name: item.name, download, targetDirectory, pathPostfix, imageNamePrefix }; + const img = await FileHelper.getImagePath(item.img, downloadOptions); + let itemIcons = { + name: item.name, + img: img, + }; + return itemIcons; + }); + + DDBMuncher.munchNote(""); + return Promise.all(itemMap); + } + + static async getDDBGenericItemIcons(items, download) { + const genericItems = await Iconizer.getDDBGenericItemImages(download); + const genericLoots = await Iconizer.getDDBGenericLootImages(download); + + let updatedItems = items.map((item) => { + // logger.debug(item.name); + // logger.debug(item.flags.ddbimporter.dndbeyond.filterType); + const excludedItems = ["spell", "feat", "class"]; + if (!excludedItems.includes(item.type) + && item.flags + && item.flags.ddbimporter + && item.flags.ddbimporter.dndbeyond) { + let generic = null; + if (item.flags.ddbimporter.dndbeyond.filterType) { + generic = genericItems.find((i) => i.filterType === item.flags.ddbimporter.dndbeyond.filterType); + } else if (item.flags.ddbimporter.dndbeyond.type) { + generic = genericLoots.find((i) => i.name === item.flags.ddbimporter.dndbeyond.type); + } + if (generic && (!item.img || item.img == "" || item.img == CONST.DEFAULT_TOKEN)) { + item.img = generic.img; + } + } + return item; + }); + return Promise.all(updatedItems); + } + + static async getDDBSchoolSpellImages(download) { + DDBMuncher.munchNote(`Fetching spell school icons`); + const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); + const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); + const imageNamePrefix = useDeepPaths ? "" : "spell"; + const pathPostfix = useDeepPaths ? "/spell/school" : ""; + + const schoolMap = DICTIONARY.spell.schools.map(async (school) => { + const downloadOptions = { type: "spell", name: school.name, download, targetDirectory, imageNamePrefix, pathPostfix }; + const img = await FileHelper.getImagePath(school.img, downloadOptions); + let schoolIcons = { + name: school.name, + img: img, + id: school.id, + }; + return schoolIcons; + }); + + DDBMuncher.munchNote(""); + return Promise.all(schoolMap); + } + + static async getDDBSpellSchoolIcons(items, download) { + const schools = await Iconizer.getDDBSchoolSpellImages(download); + + let updatedItems = items.map((item) => { + // logger.debug(item.name); + // logger.debug(item.flags.ddbimporter.dndbeyond); + if (item.type == "spell") { + const school = schools.find((school) => school.id === item.system.school); + if (school && (!item.img || item.img == "" || item.img == CONST.DEFAULT_TOKEN)) { + item.img = school.img; + } + } + return item; + }); + return Promise.all(updatedItems); + } + + static async getDDBEquipmentIcons(items, download) { + const itemImages = await Iconizer.getDDBItemImages(items.filter((item) => DICTIONARY.types.inventory.includes(item.type)), download); + + let updatedItems = items.map((item) => { + // logger.debug(item.name); + // logger.debug(item.flags.ddbimporter.dndbeyond); + if (DICTIONARY.types.inventory.includes(item.type)) { + if (!item.img || item.img == "" || item.img == CONST.DEFAULT_TOKEN) { + const imageMatch = itemImages.find((m) => m.name == item.name && m.type == item.type); + if (imageMatch && imageMatch.img) { + item.img = imageMatch.img; + setProperty(item, "flags.ddbimporter.keepIcon", true); + } + if (imageMatch && imageMatch.large) { + item.flags.ddbimporter.dndbeyond['pictureUrl'] = imageMatch.large; + } + } + } + return item; + }); + return Promise.all(updatedItems); + } + + static async updateMagicItemImages(items) { + const useSRDCompendiumIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-srd-icons"); + const ddbSpellIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-ddb-spell-icons"); + const inbuiltIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-inbuilt-icons"); + const ddbItemIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-ddb-item-icons"); + + // if we still have items to add, add them + if (items.length > 0) { + if (ddbItemIcons) { + logger.debug("Magic items: adding equipment icons"); + items = await Iconizer.getDDBEquipmentIcons(items, true); + } + + if (inbuiltIcons) { + logger.debug("Magic items: adding inbuilt icons"); + items = await Iconizer.copyInbuiltIcons(items); + } + + if (useSRDCompendiumIcons) { + logger.debug("Magic items: adding srd compendium icons"); + items = await Iconizer.copySRDIcons(items); + } + + if (ddbSpellIcons) { + logger.debug("Magic items: adding ddb spell school icons"); + items = await Iconizer.getDDBSpellSchoolIcons(items, true); + } + } + return items; } - return iconPath; + + static async preFetchDDBIconImages() { + await Iconizer.getDDBGenericItemImages(true); + await Iconizer.getDDBGenericLootImages(true); + await Iconizer.getDDBSchoolSpellImages(true); + } + + + /** + * Add an item to effects, if available + * @param {*} items + */ + static addItemEffectIcons(items) { + logger.debug("Adding Icons to effects"); + items.forEach((item) => { + if (item.effects && (item.img && (item.img !== "" || item.img !== CONST.DEFAULT_TOKEN))) { + item.effects.forEach((effect) => { + + if (!effect.icon || effect.icon === "" || effect.icon === CONST.DEFAULT_TOKEN) { + effect.icon = item.img; + } + }); + } + + }); + return items; + } + + static addActorEffectIcons(actor) { + if (!actor.effects) return actor; + logger.debug("Adding Icons to actor effects"); + actor.effects.forEach((effect) => { + const name = getProperty(effect, "flags.ddbimporter.originName"); + if (name) { + const actorItem = actor.items.find((i) => i.name === name); + if (actorItem) { + effect.icon = actorItem.img; + } + } + }); + return actor; + } + + static async updateIcons(items, srdIconUpdate = true, monster = false, monsterName = "") { + // this will use ddb item icons as a fall back + const ddbItemIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-ddb-item-icons"); + if (ddbItemIcons) { + logger.debug("DDB Equipment Icon Match"); + items = await Iconizer.getDDBEquipmentIcons(items); + } + + const inBuiltIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-inbuilt-icons"); + if (inBuiltIcons) { + logger.debug(`Inbuilt icon matching (Monster? ${monster ? monsterName : monster})`); + items = await Iconizer.copyInbuiltIcons(items, monster, monsterName); + } + + // check for SRD icons + const srdIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-srd-icons"); + // eslint-disable-next-line require-atomic-updates + if (srdIcons && srdIconUpdate) { + logger.debug("SRD Icon Matching"); + items = await Iconizer.copySRDIcons(items); + } + + // this will use ddb spell school icons as a fall back + const ddbSpellIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-ddb-spell-icons"); + if (ddbSpellIcons) { + logger.debug("DDB Spell School Icon Match"); + items = await Iconizer.getDDBSpellSchoolIcons(items, true); + } + + // this will use ddb generic icons as a fall back + const ddbGenericItemIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-ddb-generic-item-icons"); + if (ddbGenericItemIcons) { + logger.debug("DDB Generic Item Icon Match"); + items = await Iconizer.getDDBGenericItemIcons(items, true); + } + + // update any generated effects + const addEffects = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-add-effects"); + if (addEffects) { + items = Iconizer.addItemEffectIcons(items); + } + + return items; + } + + } diff --git a/src/muncher/adventure/ThirdPartyMunch.js b/src/muncher/adventure/ThirdPartyMunch.js index 7293fd91e..bcde2bf31 100644 --- a/src/muncher/adventure/ThirdPartyMunch.js +++ b/src/muncher/adventure/ThirdPartyMunch.js @@ -1,7 +1,7 @@ import AdventureMunchHelpers from "./AdventureMunchHelpers.js"; import logger from "../../logger.js"; import { generateAdventureConfig } from "../adventure.js"; -import { generateIcon } from "../../lib/Iconizer.js"; +import Iconizer from "../../lib/Iconizer.js"; import AdventureMunch from "./AdventureMunch.js"; import { PageFinder } from "./PageFinder.js"; import SETTINGS from "../../settings.js"; @@ -350,7 +350,7 @@ export default class ThirdPartyMunch extends FormApplication { logger.info(`Found note "${note.label}" matched to Journal with ID "${noteJournal.id}" (${noteJournal.name})`); note.flags.ddb.journalId = noteJournal.id; // eslint-disable-next-line require-atomic-updates - note.icon = await generateIcon(this.adventureMunch, note.label); + note.icon = await Iconizer.generateIcon(this.adventureMunch, note.label); if (noJournalPinNotes) { note.flags.ddb.labelName = `${note.label}`; note.flags.ddb.slugLink = note.label.replace(/[^\w\d]+/g, "").replace(/^([a-zA-Z]?)0+/, "$1"); diff --git a/src/muncher/import.js b/src/muncher/import.js index edff5cb61..e8f471e36 100644 --- a/src/muncher/import.js +++ b/src/muncher/import.js @@ -1,11 +1,10 @@ import logger from "../logger.js"; import DICTIONARY from "../dictionary.js"; import SETTINGS from "../settings.js"; -import FileHelper from "../lib/FileHelper.js"; import CompendiumHelper from "../lib/CompendiumHelper.js"; import DDBMuncher from "../apps/DDBMuncher.js"; import { addItemsDAESRD } from "./dae.js"; -import { copyInbuiltIcons } from "../lib/Iconizer.js"; +import Iconizer from "../lib/Iconizer.js"; import { DDBCompendiumFolders } from "../lib/DDBCompendiumFolders.js"; import NameMatcher from "../lib/NameMatcher.js"; import FolderHelper from "../lib/FolderHelper.js"; @@ -304,289 +303,6 @@ export async function updateCompendium(type, documents, updateExisting = false, } } -async function getSRDIconMatch(type) { - const compendiumName = SETTINGS.SRD_COMPENDIUMS.find((c) => c.type == type).name; - const srdPack = CompendiumHelper.getCompendium(compendiumName); - const srdIndices = ["name", "img", "prototypeToken.texture.src", "type", "system.activation", "prototypeToken.texture.scaleY", "prototypeToken.texture.scaleX"]; - const index = await srdPack.getIndex({ fields: srdIndices }); - return index; -} - -export async function getSRDImageLibrary() { - if (CONFIG.DDBI.SRD_LOAD.mapLoaded) return CONFIG.DDBI.SRD_LOAD.iconMap; - const compendiumFeatureItems = await getSRDIconMatch("features"); - const compendiumInventoryItems = await getSRDIconMatch("inventory"); - const compendiumSpellItems = await getSRDIconMatch("spells"); - const compendiumMonsterFeatures = await getSRDIconMatch("monsterfeatures"); - const compendiumMonsters = await getSRDIconMatch("monsters"); - - // eslint-disable-next-line require-atomic-updates - CONFIG.DDBI.SRD_LOAD.iconMap = [ - ...compendiumInventoryItems, - ...compendiumSpellItems, - ...compendiumFeatureItems, - ...compendiumMonsterFeatures, - ...compendiumMonsters, - ]; - return CONFIG.DDBI.SRD_LOAD.iconMap; -} - -export async function copySRDIcons(items, srdImageLibrary = null, nameMatchList = []) { - // eslint-disable-next-line require-atomic-updates - if (!srdImageLibrary) srdImageLibrary = await getSRDImageLibrary(); - - return new Promise((resolve) => { - const srdItems = items.map((item) => { - logger.debug(`Matching ${item.name}`); - const nameMatch = nameMatchList.find((m) => m.name === item.name); - if (nameMatch) { - item.img = nameMatch.img; - } else { - NameMatcher.looseItemNameMatch(item, srdImageLibrary, true).then((match) => { - if (match) { - srdImageLibrary.push({ name: item.name, img: match.img }); - item.img = match.img; - } - }); - } - return item; - - }); - resolve(srdItems); - }); -} - -export async function retainExistingIcons(items) { - return new Promise((resolve) => { - const newItems = items.map((item) => { - if (item.flags.ddbimporter?.ignoreIcon) { - logger.debug(`Retaining icon for ${item.name} to ${item.flags.ddbimporter.matchedImg}`); - item.img = item.flags.ddbimporter.matchedImg; - } - return item; - }); - resolve(newItems); - }); -} - -async function getDDBItemImages(items, download) { - DDBMuncher.munchNote(`Fetching DDB Item Images`); - const downloadImages = (download) ? true : game.settings.get(SETTINGS.MODULE_ID, "munching-policy-download-images"); - const remoteImages = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-remote-images"); - const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); - const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); - - const itemMap = items.map(async (item) => { - let itemImage = { - name: item.name, - type: item.type, - img: null, - large: null, - }; - - const pathPostfix = useDeepPaths ? `/item/${item.type}` : ""; - - if (item.flags && item.flags.ddbimporter && item.flags.ddbimporter && item.flags.ddbimporter.dndbeyond) { - if (item.flags.ddbimporter.dndbeyond.avatarUrl) { - const avatarUrl = item.flags.ddbimporter.dndbeyond['avatarUrl']; - if (avatarUrl && avatarUrl != "") { - DDBMuncher.munchNote(`Downloading ${item.name} image`); - const imageNamePrefix = useDeepPaths ? "" : "item"; - const downloadOptions = { type: "item", name: item.name, download: downloadImages, remoteImages, targetDirectory, pathPostfix, imageNamePrefix }; - const smallImage = await FileHelper.getImagePath(avatarUrl, downloadOptions); - logger.debug(`Final image ${smallImage}`); - itemImage.img = smallImage; - } - } - if (item.flags.ddbimporter.dndbeyond.largeAvatarUrl) { - const largeAvatarUrl = item.flags.ddbimporter.dndbeyond['largeAvatarUrl']; - if (largeAvatarUrl && largeAvatarUrl != "") { - const imageNamePrefix = useDeepPaths ? "" : "item"; - const name = useDeepPaths ? `${item.name}-large` : item.name; - const downloadOptions = { type: "item-large", name, download: downloadImages, remoteImages, targetDirectory, pathPostfix, imageNamePrefix }; - const largeImage = await FileHelper.getImagePath(largeAvatarUrl, downloadOptions); - itemImage.large = largeImage; - if (!itemImage.img) itemImage.img = largeImage; - } - } - } - - DDBMuncher.munchNote(""); - return itemImage; - }); - - return Promise.all(itemMap); -} - -async function getDDBGenericItemImages(download) { - DDBMuncher.munchNote(`Fetching DDB Generic Item icons`); - const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); - const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); - const imageNamePrefix = useDeepPaths ? "" : "item"; - const pathPostfix = useDeepPaths ? "/ddb/item" : ""; - - const itemMap = DICTIONARY.items.map(async (item) => { - const downloadOptions = { type: "item", name: item.filterType, download, targetDirectory, pathPostfix, imageNamePrefix }; - const img = await FileHelper.getImagePath(item.img, downloadOptions); - let itemIcons = { - filterType: item.filterType, - img: img, - }; - return itemIcons; - }); - - DDBMuncher.munchNote(""); - return Promise.all(itemMap); -} - -async function getDDBGenericLootImages(download) { - DDBMuncher.munchNote(`Fetching DDB Generic Loot icons`); - const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); - const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); - const imageNamePrefix = useDeepPaths ? "" : "equipment"; - const pathPostfix = useDeepPaths ? "/ddb/loot" : ""; - - const itemMap = DICTIONARY.genericItemIcons.map(async (item) => { - const downloadOptions = { type: "equipment", name: item.name, download, targetDirectory, pathPostfix, imageNamePrefix }; - const img = await FileHelper.getImagePath(item.img, downloadOptions); - let itemIcons = { - name: item.name, - img: img, - }; - return itemIcons; - }); - - DDBMuncher.munchNote(""); - return Promise.all(itemMap); -} - -export async function getDDBGenericItemIcons(items, download) { - const genericItems = await getDDBGenericItemImages(download); - const genericLoots = await getDDBGenericLootImages(download); - - let updatedItems = items.map((item) => { - // logger.debug(item.name); - // logger.debug(item.flags.ddbimporter.dndbeyond.filterType); - const excludedItems = ["spell", "feat", "class"]; - if (!excludedItems.includes(item.type) - && item.flags - && item.flags.ddbimporter - && item.flags.ddbimporter.dndbeyond) { - let generic = null; - if (item.flags.ddbimporter.dndbeyond.filterType) { - generic = genericItems.find((i) => i.filterType === item.flags.ddbimporter.dndbeyond.filterType); - } else if (item.flags.ddbimporter.dndbeyond.type) { - generic = genericLoots.find((i) => i.name === item.flags.ddbimporter.dndbeyond.type); - } - if (generic && (!item.img || item.img == "" || item.img == CONST.DEFAULT_TOKEN)) { - item.img = generic.img; - } - } - return item; - }); - return Promise.all(updatedItems); -} - -async function getDDBSchoolSpellImages(download) { - DDBMuncher.munchNote(`Fetching spell school icons`); - const targetDirectory = game.settings.get(SETTINGS.MODULE_ID, "other-image-upload-directory").replace(/^\/|\/$/g, ""); - const useDeepPaths = game.settings.get(SETTINGS.MODULE_ID, "use-deep-file-paths"); - const imageNamePrefix = useDeepPaths ? "" : "spell"; - const pathPostfix = useDeepPaths ? "/spell/school" : ""; - - const schoolMap = DICTIONARY.spell.schools.map(async (school) => { - const downloadOptions = { type: "spell", name: school.name, download, targetDirectory, imageNamePrefix, pathPostfix }; - const img = await FileHelper.getImagePath(school.img, downloadOptions); - let schoolIcons = { - name: school.name, - img: img, - id: school.id, - }; - return schoolIcons; - }); - - DDBMuncher.munchNote(""); - return Promise.all(schoolMap); -} - -export async function getDDBSpellSchoolIcons(items, download) { - const schools = await getDDBSchoolSpellImages(download); - - let updatedItems = items.map((item) => { - // logger.debug(item.name); - // logger.debug(item.flags.ddbimporter.dndbeyond); - if (item.type == "spell") { - const school = schools.find((school) => school.id === item.system.school); - if (school && (!item.img || item.img == "" || item.img == CONST.DEFAULT_TOKEN)) { - item.img = school.img; - } - } - return item; - }); - return Promise.all(updatedItems); -} - -export async function getDDBEquipmentIcons(items, download) { - const itemImages = await getDDBItemImages(items.filter((item) => DICTIONARY.types.inventory.includes(item.type)), download); - - let updatedItems = items.map((item) => { - // logger.debug(item.name); - // logger.debug(item.flags.ddbimporter.dndbeyond); - if (DICTIONARY.types.inventory.includes(item.type)) { - if (!item.img || item.img == "" || item.img == CONST.DEFAULT_TOKEN) { - const imageMatch = itemImages.find((m) => m.name == item.name && m.type == item.type); - if (imageMatch && imageMatch.img) { - item.img = imageMatch.img; - setProperty(item, "flags.ddbimporter.keepIcon", true); - } - if (imageMatch && imageMatch.large) { - item.flags.ddbimporter.dndbeyond['pictureUrl'] = imageMatch.large; - } - } - } - return item; - }); - return Promise.all(updatedItems); -} - - -export async function updateMagicItemImages(items) { - const useSRDCompendiumIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-srd-icons"); - const ddbSpellIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-ddb-spell-icons"); - const inbuiltIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-inbuilt-icons"); - const ddbItemIcons = game.settings.get(SETTINGS.MODULE_ID, "character-update-policy-use-ddb-item-icons"); - - // if we still have items to add, add them - if (items.length > 0) { - if (ddbItemIcons) { - logger.debug("Magic items: adding equipment icons"); - items = await getDDBEquipmentIcons(items, true); - } - - if (inbuiltIcons) { - logger.debug("Magic items: adding inbuilt icons"); - items = await copyInbuiltIcons(items); - } - - if (useSRDCompendiumIcons) { - logger.debug("Magic items: adding srd compendium icons"); - items = await copySRDIcons(items); - } - - if (ddbSpellIcons) { - logger.debug("Magic items: adding ddb spell school icons"); - items = await getDDBSpellSchoolIcons(items, true); - } - } - return items; -} - -export async function preFetchDDBIconImages() { - await getDDBGenericItemImages(true); - await getDDBGenericLootImages(true); - await getDDBSchoolSpellImages(true); -} - export function updateCharacterItemFlags(itemData, replaceData) { if (itemData.flags?.ddbimporter?.importId) setProperty(replaceData, "flags.ddbimporter.importId", itemData.flags.ddbimporter.importId); if (itemData.system.quantity) replaceData.system.quantity = itemData.system.quantity; @@ -814,86 +530,6 @@ export async function getSRDCompendiumItems(items, type, looseMatch = false, kee return results; } -/** - * Add an item to effects, if available - * @param {*} items - */ -export function addItemEffectIcons(items) { - logger.debug("Adding Icons to effects"); - items.forEach((item) => { - if (item.effects && (item.img && (item.img !== "" || item.img !== CONST.DEFAULT_TOKEN))) { - item.effects.forEach((effect) => { - - if (!effect.icon || effect.icon === "" || effect.icon === CONST.DEFAULT_TOKEN) { - effect.icon = item.img; - } - }); - } - - }); - return items; -} - -export function addActorEffectIcons(actor) { - if (!actor.effects) return actor; - logger.debug("Adding Icons to actor effects"); - actor.effects.forEach((effect) => { - const name = getProperty(effect, "flags.ddbimporter.originName"); - if (name) { - const actorItem = actor.items.find((i) => i.name === name); - if (actorItem) { - effect.icon = actorItem.img; - } - } - }); - return actor; -} - -export async function updateIcons(items, srdIconUpdate = true, monster = false, monsterName = "") { - // this will use ddb item icons as a fall back - const ddbItemIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-ddb-item-icons"); - if (ddbItemIcons) { - logger.debug("DDB Equipment Icon Match"); - items = await getDDBEquipmentIcons(items); - } - - const inBuiltIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-inbuilt-icons"); - if (inBuiltIcons) { - logger.debug(`Inbuilt icon matching (Monster? ${monster ? monsterName : monster})`); - items = await copyInbuiltIcons(items, monster, monsterName); - } - - // check for SRD icons - const srdIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-srd-icons"); - // eslint-disable-next-line require-atomic-updates - if (srdIcons && srdIconUpdate) { - logger.debug("SRD Icon Matching"); - items = await copySRDIcons(items); - } - - // this will use ddb spell school icons as a fall back - const ddbSpellIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-ddb-spell-icons"); - if (ddbSpellIcons) { - logger.debug("DDB Spell School Icon Match"); - items = await getDDBSpellSchoolIcons(items, true); - } - - // this will use ddb generic icons as a fall back - const ddbGenericItemIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-ddb-generic-item-icons"); - if (ddbGenericItemIcons) { - logger.debug("DDB Generic Item Icon Match"); - items = await getDDBGenericItemIcons(items, true); - } - - // update any generated effects - const addEffects = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-add-effects"); - if (addEffects) { - items = addItemEffectIcons(items); - } - - return items; -} - export async function srdFiddling(items, type) { const updateBool = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-update-existing"); const useSrd = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-srd"); @@ -904,7 +540,7 @@ export async function srdFiddling(items, type) { logger.debug("Removing compendium items"); const lessSrdItems = await removeItems(items, srdItems); const newIcons = lessSrdItems.concat(srdItems); - const iconedItems = await updateIcons(newIcons); + const iconedItems = await Iconizer.updateIcons(newIcons); // console.warn("Final Monsters", srdItems); return iconedItems; } else if (useSrd) { @@ -917,11 +553,11 @@ export async function srdFiddling(items, type) { // removed existing items from those to be imported return new Promise((resolve) => { removeItems(items, srdItems) - .then((cleanedItems) => updateIcons(cleanedItems)) + .then((cleanedItems) => Iconizer.updateIcons(cleanedItems)) .then((iconItems) => resolve(iconItems)); }); } else { - const iconItems = await updateIcons(items); + const iconItems = await Iconizer.updateIcons(items); return iconItems; } } @@ -976,7 +612,7 @@ export async function addMagicItemSpells(input) { const [compendiumSpells, compendiumItemSpells] = await getCompendiumItemSpells(input.itemSpells); // if spells not found create world version const remainingSpells = { - itemSpells: await updateMagicItemImages(await removeItems(input.itemSpells, compendiumSpells)), + itemSpells: await Iconizer.updateMagicItemImages(await removeItems(input.itemSpells, compendiumSpells)), }; const worldSpells = remainingSpells.length > 0 ? await FolderHelper.updateFolderItems("itemSpells", remainingSpells) diff --git a/src/muncher/importMonster.js b/src/muncher/importMonster.js index 132b9328e..577455a28 100644 --- a/src/muncher/importMonster.js +++ b/src/muncher/importMonster.js @@ -1,11 +1,12 @@ import logger from "../logger.js"; import CompendiumHelper from "../lib/CompendiumHelper.js"; import FileHelper from "../lib/FileHelper.js"; -import { updateIcons, addActorEffectIcons, getCompendiumItems, getSRDImageLibrary, copySRDIcons, compendiumFoldersV10, addCompendiumFolderIds } from "./import.js"; +import { getCompendiumItems, compendiumFoldersV10, addCompendiumFolderIds } from "./import.js"; import DDBMuncher from "../apps/DDBMuncher.js"; import { migrateItemsDAESRD } from "./dae.js"; import SETTINGS from "../settings.js"; import utils from "../lib/utils.js"; +import Iconizer from "../lib/Iconizer.js"; // check items to see if retaining item, img or resources async function existingItemRetentionCheck(currentItems, newItems, checkId = true) { @@ -369,8 +370,8 @@ export async function buildNPC(data, type = "monster", temporary = true, update logger.debug("Importing Icons"); // eslint-disable-next-line require-atomic-updates - data.items = await updateIcons(data.items, false, true, data.name); - data = addActorEffectIcons(data); + data.items = await Iconizer.updateIcons(data.items, false, true, data.name); + data = Iconizer.addActorEffectIcons(data); data = await linkResourcesConsumption(data); if (handleBuild) { @@ -424,7 +425,7 @@ export function addNPC(data, bulkImport, type) { export async function useSRDMonsterImages(monsters) { // eslint-disable-next-line require-atomic-updates if (game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-srd-monster-images")) { - const srdImageLibrary = await getSRDImageLibrary(); + const srdImageLibrary = await Iconizer.getSRDImageLibrary(); DDBMuncher.munchNote(`Updating SRD Monster Images`, true); monsters.forEach((monster) => { @@ -474,14 +475,14 @@ export async function generateIconMap(monsters) { const srdIcons = game.settings.get(SETTINGS.MODULE_ID, "munching-policy-use-srd-icons"); // eslint-disable-next-line require-atomic-updates if (srdIcons) { - const srdImageLibrary = await getSRDImageLibrary(); + const srdImageLibrary = await Iconizer.getSRDImageLibrary(); DDBMuncher.munchNote(`Updating SRD Icons`, true); let itemMap = []; monsters.forEach((monster) => { DDBMuncher.munchNote(`Processing ${monster.name}`); promises.push( - copySRDIcons(monster.items, srdImageLibrary, itemMap).then((items) => { + Iconizer.copySRDIcons(monster.items, srdImageLibrary, itemMap).then((items) => { monster.items = items; }) ); diff --git a/src/muncher/items.js b/src/muncher/items.js index 1db1c65e5..2b8238d65 100644 --- a/src/muncher/items.js +++ b/src/muncher/items.js @@ -1,5 +1,5 @@ // Main module class -import { updateCompendium, srdFiddling, daeFiddling, preFetchDDBIconImages } from "./import.js"; +import { updateCompendium, srdFiddling, daeFiddling } from "./import.js"; import DDBMuncher from "../apps/DDBMuncher.js"; import utils from "../lib/utils.js"; import FileHelper from "../lib/FileHelper.js"; @@ -13,6 +13,7 @@ import DDBCharacter from "../parser/DDBCharacter.js"; import { applyChrisPremadeEffects } from "../effects/chrisPremades.js"; import { addVision5eStubs } from "../effects/vision5e.js"; import { configureDependencies } from "../effects/macros.js"; +import Iconizer from "../lib/Iconizer.js"; async function getCharacterInventory(items) { return items.map((item) => { @@ -196,7 +197,7 @@ export async function parseItems(ids = null) { await addMagicItemSpells(items, itemSpells, updateBool); } - await preFetchDDBIconImages(); + await Iconizer.preFetchDDBIconImages(); const srdItems = await srdFiddling(items, "inventory"); const filteredItems = (ids !== null && ids.length > 0) diff --git a/src/muncher/spells.js b/src/muncher/spells.js index 08d477cb8..e6d9079d5 100644 --- a/src/muncher/spells.js +++ b/src/muncher/spells.js @@ -1,5 +1,5 @@ // Main module class -import { updateCompendium, srdFiddling, daeFiddling, preFetchDDBIconImages } from "./import.js"; +import { updateCompendium, srdFiddling, daeFiddling } from "./import.js"; import DDBMuncher from "../apps/DDBMuncher.js"; import { getSpells } from "../parser/spells/getGenericSpells.js"; import FileHelper from "../lib/FileHelper.js"; @@ -12,6 +12,7 @@ import { applyChrisPremadeEffects } from "../effects/chrisPremades.js"; import { addVision5eStubs } from "../effects/vision5e.js"; import PatreonHelper from "../lib/PatreonHelper.js"; import { configureDependencies } from "../effects/macros.js"; +import Iconizer from "../lib/Iconizer.js"; function getSpellData(className, sourceFilter) { const cobaltCookie = getCobalt(); @@ -120,7 +121,7 @@ export async function parseSpells(ids = null) { logger.error("Failed spell parsing", results); } - await preFetchDDBIconImages(); + await Iconizer.preFetchDDBIconImages(); let uniqueSpells = spells.filter((v, i, a) => a.findIndex((t) => t.name === v.name) === i); const srdSpells = await srdFiddling(uniqueSpells, "spells"); diff --git a/src/parser/DDBMonsterFactory.js b/src/parser/DDBMonsterFactory.js index 841f7638a..2ae93ff0f 100644 --- a/src/parser/DDBMonsterFactory.js +++ b/src/parser/DDBMonsterFactory.js @@ -6,7 +6,7 @@ import DDBProxy from "../lib/DDBProxy.js"; import PatreonHelper from "../lib/PatreonHelper.js"; import SETTINGS from "../settings.js"; import { DDBCompendiumFolders } from "../lib/DDBCompendiumFolders.js"; -import { srdFiddling, getCompendiumItems, removeItems, preFetchDDBIconImages } from "../muncher/import.js"; +import { srdFiddling, getCompendiumItems, removeItems } from "../muncher/import.js"; // targets for migration import { @@ -16,6 +16,7 @@ import { // addNPCsToCompendium, useSRDMonsterImages } from "../muncher/importMonster.js"; +import Iconizer from "../lib/Iconizer.js"; export default class DDBMonsterFactory { @@ -202,7 +203,7 @@ export default class DDBMonsterFactory { this.munchNote(`Checking existing image files...`); CONFIG.DDBI.KNOWN.TOKEN_LOOKUPS.clear(); CONFIG.DDBI.KNOWN.AVATAR_LOOKUPS.clear(); - await preFetchDDBIconImages(); + await Iconizer.preFetchDDBIconImages(); await FileHelper.generateCurrentFiles(uploadDirectory); await FileHelper.generateCurrentFiles("[data] modules/ddb-importer/data");