diff --git a/patches/@league-of-foundry-developers+foundry-vtt-types+9.269.0.patch b/patches/@league-of-foundry-developers+foundry-vtt-types+9.269.0.patch index a3fa929b0..1e8afd554 100644 --- a/patches/@league-of-foundry-developers+foundry-vtt-types+9.269.0.patch +++ b/patches/@league-of-foundry-developers+foundry-vtt-types+9.269.0.patch @@ -1,26 +1,39 @@ +diff --git a/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/apps/forms/actor.d.ts b/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/apps/forms/actor.d.ts +index ab8be64..b10d652 100644 +--- a/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/apps/forms/actor.d.ts ++++ b/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/apps/forms/actor.d.ts +@@ -87,7 +87,7 @@ declare global { + protected _onDropActiveEffect(event: DragEvent, data: ActorSheet.DropData.ActiveEffect): Promise; + + /** +- * Handle dropping of an item reference or item data onto an Actor Sheet ++ * Handle dropping of an actor reference or actor data onto an Actor Sheet + * @param event - The concluding DragEvent which contains drop data + * @param data - The data transfer extracted from the event + * @returns A data object which describes the result of the drop diff --git a/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/config.d.ts b/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/config.d.ts index da561df..3665779 100644 --- a/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/config.d.ts +++ b/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/config.d.ts @@ -128,6 +128,9 @@ declare global { - + /** @defaultValue `{}` */ typeLabels: Record; + + /** @defaultValue `{}` */ + typeIcons: Record; }; - + /** @@ -332,6 +335,9 @@ declare global { - + /** @defaultValue `{}` */ typeLabels: Record; + + /** @defaultValue `{}` */ + typeIcons: Record; }; - + /** @@ -1485,6 +1491,7 @@ declare global { }; @@ -28,7 +41,7 @@ index da561df..3665779 100644 sidebarIcon: "fas fa-book-open"; + coreTypes: ["image", "pdf", "text", "video"] }; - + /** diff --git a/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/data/documents/table.d.ts b/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/data/documents/table.d.ts index ca6d3f2..34792e6 100644 @@ -40,35 +53,35 @@ index ca6d3f2..34792e6 100644 */ - roll: Roll; + roll?: Roll; - + /** * Allow drawing recursively from inner RollTable results * @defaultValue `true` */ - recursive: boolean; + recursive?: boolean; - + /** * One or more table results which have been drawn * @defaultValue `[]` */ - results: foundry.data.TableResultData[]; + results?: foundry.data.TableResultData[]; - + /** * Whether to automatically display the results in chat * @defaultValue `true` */ - displayChat: boolean; + displayChat?: boolean; - + /** * The chat roll mode to use when displaying the result */ - rollMode: keyof CONFIG.Dice.RollModes | "roll"; + rollMode?: keyof CONFIG.Dice.RollModes | "roll"; } - + /** diff --git a/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/journalEntryPageData.d.ts b/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/journalEntryPageData.d.ts index e1da7b2..c865bb4 100644 @@ -77,7 +90,7 @@ index e1da7b2..c865bb4 100644 @@ -165,9 +165,12 @@ declare global { */ name: string; - + + /** * The type of this page, in {@link BaseJournalEntryPage.TYPES}. @@ -85,7 +98,7 @@ index e1da7b2..c865bb4 100644 + type: ValueOf + content: ValueOf; - + /** @@ -217,6 +220,7 @@ declare global { * @defaultValue `{}` @@ -93,11 +106,11 @@ index e1da7b2..c865bb4 100644 flags: ConfiguredFlags<"JournalEntryPage">; + } - + namespace JournalEntryPageDataProperties { @@ -315,4 +319,10 @@ export class JournalEntryPageData extends DocumentData< } - + // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface JournalEntryPageData extends JournalEntryPageDataProperties {} +export interface JournalEntryPageData extends JournalEntryPageDataProperties { @@ -118,10 +131,10 @@ index 25cb406..ce8ce9b 100644 + isEmbedded: true } >; - + @@ -43,4 +44,24 @@ export declare class BaseJournalEntryPage extends Document< static get TYPES(): DocumentSubTypes<"JournalEntryPage">[]; - + getUserLevel(user: BaseUser): ValueOf | null; + + /** @@ -158,7 +171,7 @@ index eb3fa4c..f45b1d5 100644 +> + ? InstanceType>["type"] : typeof foundry.CONST.BASE_DOCUMENT_TYPE; - + export type ConfiguredDocumentClassForName = CONFIG[Name]["documentClass"]; diff --git a/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/types/utils.d.ts b/node_modules/@league-of-foundry-developers/foundry-vtt-types/src/types/utils.d.ts index 8cc4b52..197c630 100644 @@ -188,5 +201,5 @@ index 8cc4b52..197c630 100644 + } ) + : T[P]; }; - + /** diff --git a/src/config.ts b/src/config.ts index cd4dc268d..d278c1c97 100644 --- a/src/config.ts +++ b/src/config.ts @@ -20,13 +20,18 @@ import { registerOracleTree } from './module/features/customoracles' import { OracleTable } from './module/roll-table/oracle-table' +import type { ConfiguredData } from '@league-of-foundry-developers/foundry-vtt-types/src/types/helperTypes' + +export type SystemSubtype = ConfiguredData< + 'Actor' | 'Item' | 'JournalEntryPage' +>['type'] export interface EmitterEvents extends Record { highlightMove: string // Foundry UUID highlightOracle: string // DF ID globalConditionChanged: { name: string; enabled: boolean } // info about condition that changed - dragStart: string // type of item - dragEnd: string // type of item + dragStart: SystemSubtype // type of item + dragEnd: SystemSubtype // type of item } export type IronswornEmitter = Emitter diff --git a/src/index.ts b/src/index.ts index 65287193c..b2478933b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -88,6 +88,9 @@ Hooks.once('init', async () => { CONFIG.RollTable.resultIcon = 'icons/dice/d10black.svg' CONFIG.TableResult.documentClass = OracleTableResult + // configure index fields + CONFIG.Actor.compendiumIndexFields.push('system.dfid') + // CONFIG.RollTable.resultTemplate = // 'systems/foundry-ironsworn/templates/rolls/oracle-roll-message.hbs' diff --git a/src/module/actor/sheets/sitesheet.ts b/src/module/actor/sheets/sitesheet.ts index 2578b91c8..772eb06bb 100644 --- a/src/module/actor/sheets/sitesheet.ts +++ b/src/module/actor/sheets/sitesheet.ts @@ -1,6 +1,5 @@ import { VueActorSheet } from '../../vue/vueactorsheet' import siteSheetVue from '../../vue/site-sheet.vue' - export class IronswornSiteSheet extends VueActorSheet { static get defaultOptions() { return mergeObject(super.defaultOptions, { @@ -10,6 +9,15 @@ export class IronswornSiteSheet extends VueActorSheet { }) as any } + async _onDropActor(event: DragEvent, data: ActorSheet.DropData.Actor) { + // Fetch the actor. We only want to override denizens (foe-type actors) + const droppedActor = await Actor.fromDropData(data as any) + if (droppedActor == null) return false + if (droppedActor.type !== 'foe') { + return await super._onDropActor(event, data) + } + } + async _onDropItem(event: DragEvent, data: ActorSheet.DropData.Item) { if (!this.actor.assert('site')) throw new Error( @@ -27,13 +35,13 @@ export class IronswornSiteSheet extends VueActorSheet { '.ironsworn__denizen__drop' )[0] if (dropTarget == null) return false - const idx = parseInt(dropTarget.dataset.idx || '') - const { denizens } = this.actor.system + const idx = parseInt(dropTarget?.dataset.idx || '') + const { denizens } = this.actor.system as SiteDataSourceData if (!denizens[idx]) return false // Set the denizen description - denizens[idx].text = item.link - void this.actor.update({ system: { denizens } }, { render: true }) + denizens[idx].text = droppedActor.link + this.actor.update({ system: { denizens } }, { render: true }) return true } } diff --git a/src/module/dataforged/import.ts b/src/module/dataforged/import.ts index 1a3b27161..e818b3742 100644 --- a/src/module/dataforged/import.ts +++ b/src/module/dataforged/import.ts @@ -2,25 +2,26 @@ import type { ItemDataConstructorData } from '@league-of-foundry-developers/foun import type { RollTableDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/rollTableData' import type { IAssetType, + IEncounterIronsworn, + IEncounterStarforged, + IEncounterVariant, IMoveCategory, IOracle, IOracleCategory, Ironsworn, - IRow, ISettingTruth, Starforged } from 'dataforged' // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { starforged, ironsworn } from 'dataforged' -import { isArray, isObject, max } from 'lodash-es' +import type { ActorDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/actorData' +import { ironsworn, starforged } from 'dataforged' +import { isArray, isObject } from 'lodash-es' import shajs from 'sha.js' import { renderLinksInMove, renderLinksInStr } from '.' import { IronswornActor } from '../actor/actor' -import type { IronswornItem } from '../item/item' -import { OracleTable } from '../roll-table/oracle-table' import { IronswornJournalEntry } from '../journal/journal-entry' import { IronswornJournalPage } from '../journal/journal-entry-page' -import { OracleTableResult } from '../roll-table/oracle-table-result' +import { OracleTable } from '../roll-table/oracle-table' import { ISAssetTypes, ISMoveCategories, @@ -65,16 +66,80 @@ export function hash(str: string): string { const PACKS = [ 'foundry-ironsworn.starforgedassets', - 'foundry-ironsworn.starforgedencounters', 'foundry-ironsworn.starforgedmoves', 'foundry-ironsworn.starforgedoracles', 'foundry-ironsworn.starforgedtruths', - 'foundry-ironsworn.foeactorssf', + 'foundry-ironsworn.starforged-encounters', 'foundry-ironsworn.ironswornassets', 'foundry-ironsworn.ironswornoracles', 'foundry-ironsworn.ironswornmoves', - 'foundry-ironsworn.ironsworntruths' -] as const + 'foundry-ironsworn.ironsworntruths', + 'foundry-ironsworn.ironsworn-encounters' +] + +const FOE_IMAGES = { + Broken: 'icons/creatures/mammals/humanoid-fox-cat-archer.webp', + 'Common Folk': 'icons/tools/hand/shovel-spade-steel-blue-brown.webp', + Hunter: 'icons/environment/people/archer.webp', + Mystic: 'icons/environment/people/cleric-orange.webp', + Raider: 'icons/sundries/flags/banner-flag-pirate.webp', + Warrior: 'icons/skills/melee/hand-grip-sword-red.webp', + Husk: 'icons/magic/earth/strike-body-stone-crumble.webp', + Zealot: 'icons/environment/people/cleric-grey.webp', + Elf: 'icons/creatures/magical/humanoid-horned-rider.webp', + Giant: 'icons/creatures/magical/humanoid-giant-forest-blue.webp', + Primordial: 'icons/creatures/magical/spirit-undead-horned-blue.webp', + Troll: 'icons/creatures/mammals/bull-horns-eyes-glowin-orange.webp', + Varou: 'icons/creatures/mammals/wolf-shadow-black.webp', + Atanya: 'icons/magic/air/wind-weather-sailing-ship.webp', + Merrow: 'icons/creatures/fish/fish-man-eye-green.webp', + Bear: 'icons/creatures/abilities/bear-roar-bite-brown-green.webp', + Boar: 'icons/commodities/treasure/figurine-boar.webp', + Gaunt: 'icons/magic/fire/elemental-creature-horse.webp', + 'Marsh Rat': 'icons/creatures/mammals/rodent-rat-diseaed-gray.webp', + Wolf: 'icons/creatures/abilities/wolf-howl-moon-purple.webp', + Bladewing: 'icons/creatures/magical/spirit-undead-winged-ghost.webp', + 'Carrion Newt': + 'icons/creatures/reptiles/chameleon-camouflage-green-brown.webp', + 'Cave Lion': 'icons/creatures/abilities/lion-roar-yellow.webp', + 'Deep Rat': 'icons/creatures/mammals/rodent-rat-green.webp', + 'Nightmare Spider': + 'icons/creatures/invertebrates/spider-mandibles-brown.webp', + 'Shroud Crab': 'icons/consumables/meat/claw-crab-lobster-serrated-pink.webp', + Trog: 'icons/creatures/reptiles/lizard-iguana-green.webp', + Basilisk: 'icons/creatures/reptiles/snake-poised-white.webp', + 'Elder Beast': + 'icons/creatures/mammals/beast-horned-scaled-glowing-orange.webp', + 'Harrow Spider': 'icons/creatures/invertebrates/spider-web-black.webp', + Leviathan: 'icons/creatures/reptiles/serpent-horned-green.webp', + Mammoth: 'icons/commodities/leather/fur-white.webp', + Wyvern: 'icons/creatures/abilities/wolf-heads-swirl-purple.webp', + Chitter: 'icons/creatures/invertebrates/bug-sixlegged-gray.webp', + Gnarl: 'icons/magic/nature/tree-animated-strike.webp', + 'Iron-Wracked Beast': 'icons/environment/wilderness/statue-hound-horned.webp', + Kraken: 'icons/creatures/fish/squid-kraken-orange.webp', + Nightspawn: 'icons/creatures/unholy/demon-horned-black-yellow.webp', + Rhaskar: 'icons/creatures/fish/fish-marlin-swordfight-blue.webp', + Wyrm: 'icons/creatures/eyes/lizard-single-slit-pink.webp', + Bonewalker: 'icons/magic/death/undead-skeleton-worn-blue.webp', + Frostbound: 'icons/creatures/magical/spirit-undead-ghost-blue.webp', + Chimera: 'icons/creatures/magical/spirit-earth-stone-magma-yellow.webp', + Haunt: 'icons/magic/death/undead-ghost-strike-white.webp', + Hollow: 'icons/consumables/plants/grass-leaves-green.webp', + 'Iron Revenant': 'icons/creatures/magical/construct-golem-stone-blue.webp', + Sodden: 'icons/magic/death/undead-ghost-scream-teal.webp', + Blighthound: 'icons/commodities/treasure/figurine-dog.webp', + 'Bog Rot': 'icons/magic/death/hand-dirt-undead-zombie.webp', + Bonehorde: 'icons/skills/trades/academics-study-archaeology-bones.webp', + Thrall: 'icons/creatures/abilities/mouth-teeth-human.webp', + Wight: 'icons/creatures/magical/humanoid-silhouette-green.webp', + 'Blood Thorn': 'icons/consumables/plants/thorned-stem-vine-green.webp', + 'Circle of Stones': 'icons/environment/wilderness/arch-stone.webp', + Glimmer: 'icons/magic/nature/elemental-plant-humanoid.webp', + Gloom: 'icons/magic/perception/silhouette-stealth-shadow.webp', + Maelstrom: 'icons/magic/water/vortex-water-whirlpool.webp', + Tempest: 'icons/magic/lightning/bolts-salvo-clouds-sky.webp' +} as const /** * Converts JSON from dataforged resources into foundry packs. Requires packs to @@ -105,9 +170,7 @@ export async function importFromDataforged() { processISOracles(), // processISTruths(), // Re-enable when DF includes them processSFTruths(), - processSFEncounters().then(async () => { - await processSFFoes() - }) + processSFEncounters() ]) // Lock the packs again @@ -291,84 +354,99 @@ async function processISOracles() { }) } -async function processSFEncounters() { - const encountersToCreate = [] as Array< - ItemDataConstructorData & Record - > - for (const encounter of starforged.Encounters) { - const description = await renderTemplate( - 'systems/foundry-ironsworn/templates/item/sf-foe.hbs', - { - ...encounter, - variantLinks: encounter.Variants.map((x) => - renderLinksInStr(`[${x.Name}](${x.$id})`) - ) - } - ) +type EncounterConstructorData = Omit< + ActorDataConstructorData & DeepPartial>, + 'data' +> - encountersToCreate.push({ - _id: hashLookup(encounter.$id), - type: 'progress', - name: encounter.Name, - img: DATAFORGED_ICON_MAP.starforged.foe[encounter.$id], - system: { - description, - rank: encounter.Rank - } - }) +function hasVariants(data: unknown): data is IEncounterStarforged { + return Array.isArray((data as any).Variants) +} - for (const variant of encounter.Variants) { - const variantDescription = await renderTemplate( - 'systems/foundry-ironsworn/templates/item/sf-foe.hbs', - { - ...encounter, - ...variant, - Category: variant.Nature ?? encounter.Nature, - CategoryDescription: (variant as any).Summary ?? encounter.Summary - } - ) +async function processEncounter( + encounter: IEncounterIronsworn | IEncounterStarforged | IEncounterVariant, + img: string +): Promise { + let variantLinks: string[] = [] + if (hasVariants(encounter)) { + variantLinks = encounter.Variants.map((x) => + renderLinksInStr(`[${x.Name}](${x.$id})`) + ) + } + const description = await renderTemplate( + 'systems/foundry-ironsworn/templates/item/sf-foe.hbs', + { ...encounter, variantLinks } + ) - encountersToCreate.push({ - _id: hashLookup(variant.$id), - type: 'progress', - name: variant.Name, - img: DATAFORGED_ICON_MAP.starforged.foe[variant.$id], - system: { - description: variantDescription, - rank: variant.Rank ?? encounter.Rank - } - }) + const progressTrack: Omit< + ItemDataConstructorData & DeepPartial>, + 'data' + > = { + type: 'progress', + name: encounter.Name, + img, + system: { + subtype: 'foe', + starred: false, + hasTrack: true, + rank: encounter.Rank, + description } } - await Item.createDocuments(encountersToCreate, { - pack: 'foundry-ironsworn.starforgedencounters', - keepId: true + return { + _id: hashLookup(encounter.$id), + type: 'foe', + name: encounter.Name, + img, + items: [progressTrack], + system: { + dfid: encounter.$id + } + } +} + +async function processISFoes() { + const encountersToCreate: Array> = [] + for (const encounterType of ironsworn.Encounters) { + for (const encounter of encounterType.Encounters) { + const img = FOE_IMAGES[encounter.Name] + encountersToCreate.push(processEncounter(encounter, img)) + } + } + await IronswornActor.createDocuments(await Promise.all(encountersToCreate), { + pack: 'foundry-ironsworn.ironswornfoes', + keepId: true, + keepEmbeddedIds: true, + recursive: true }) } -/** Processes *existing* Starforged encounter Items into actors. Run it immediately after processSFEncounters or it won't work! */ -async function processSFFoes() { - const foesPack = game.packs.get('foundry-ironsworn.starforgedencounters') - const foeItems = (await foesPack?.getDocuments()) as Array< - StoredDocument - > - for (const foeItem of foeItems ?? []) { - const actor = await IronswornActor.create( - { - name: foeItem.name ?? 'wups', - img: foeItem.img, - type: 'foe' - }, - { pack: 'foundry-ironsworn.foeactorssf' } +async function processSFEncounters() { + const encountersToCreate: Array> = [] + for (const encounter of starforged.Encounters) { + encountersToCreate.push( + processEncounter( + encounter, + DATAFORGED_ICON_MAP.starforged.foe[encounter.$id] + ) ) - await actor?.createEmbeddedDocuments('Item', [ - { - name: foeItem.name ?? 'wups', - type: 'progress', - system: foeItem.system as unknown as Record - } - ]) + + for (const variant of encounter.Variants) { + encountersToCreate.push( + processEncounter( + variant, + DATAFORGED_ICON_MAP.starforged.foe[encounter.$id] + ) + ) + } } + + await IronswornActor.createDocuments(await Promise.all(encountersToCreate), { + pack: 'foundry-ironsworn.starforged-encounters', + keepId: true, + keepEmbeddedIds: true, + recursive: true + }) } async function processTruths( diff --git a/src/module/dataforged/links.ts b/src/module/dataforged/links.ts new file mode 100644 index 000000000..64a1dfe64 --- /dev/null +++ b/src/module/dataforged/links.ts @@ -0,0 +1,128 @@ +function getCanonicalUUID(id: string, packIndices: CompendiumIndex[]) { + for (const index of packIndices) { + const entry = index.get(id) + if (entry == null) continue + else return entry.uuid + } + throw new Error(`Couldn't find a pack entry with the key ${id}`) +} + +/** + * + * @param str The string field value. + * @param packIndices The "canonical" pack indices to use for local ID lookup. + */ +export function migrateLinksInString( + str: string, + packIndices: CompendiumIndex[] +) { + const legacyLinkPointerPattern = + /@Compendium\[[A-Za-z0-9-_]+?\.[A-Za-z0-9-_]+?\.(?[a-zA-Z0-9]{16})\]/g + + return str.replaceAll( + legacyLinkPointerPattern, + (_match, _p1, _offset, _string, groups: { id: string }) => { + // get the local ID from the link + const { id } = groups + // search pack indices for entries keyed with the local id + const targetUUID = getCanonicalUUID(id, packIndices) + return `@UUID[${targetUUID}]` + } + ) +} + +/** + * Iterates over the HTML fields of a document, and applies a transform to each field's string value. + * @param document The document whose HTMLFields will be updated. + * @param transform The function to apply to each HTML field's value. + * @returns A document update delta, suitable for use with {@link foundry.abstract.Document.updateDocuments} + */ +export function migrateHTMLFields< + T extends foundry.abstract.Document +>(document: T, transform: (str: string) => string) { + const schema = ( + document as unknown as foundry.abstract.DataModel + ).schema + + function updateLinks(this: foundry.data.fields.DataField, value: unknown) { + if ( + this instanceof foundry.data.fields.HTMLField && + typeof value === 'string' + ) + return transform(value) + return undefined + } + + const updateData = schema.apply(updateLinks, document as any) as Partial + + if (foundry.utils.isEmpty(updateData)) return null + + return { _id: document.id, ...updateData } +} + +async function loadReferencePackIndices(...referencePackIDs: string[]) { + const packIndices: CompendiumIndex[] = [] + for await (const id of referencePackIDs) { + const refPack = game.packs.get(id) + if (refPack == null) throw new Error(`Could not find pack ${id}`) + if (!refPack.indexed) await refPack.getIndex() + packIndices.push(refPack.index as unknown as CompendiumIndex) + } + return packIndices +} + +/** + * + * @param packID The ID of the pack to update. + * @param referencePackIDs The packs to reference for canonical UUIDs when updating the links. (default: all) + * @param dryRun When true, don't update the documents; instead, return the raw document update deltas. + */ +export async function updatePackDocumentLinks( + packID: string, + referencePackIDs: string[] = Array.from(game?.packs?.keys()) ?? [], + { dryRun = false }: { dryRun: boolean } +) { + if (!game.user!.isGM) + return ui.notifications?.warn( + 'You must be GM to run updatePackDocumentLinks' + ) + + const pack = game.packs.get(packID) + if (pack == null) throw new Error(`Could not find pack ${packID}`) + + // load packs to be used for reference and make sure they're indexed + const [packIndices, docs] = await Promise.all([ + loadReferencePackIndices(...referencePackIDs), + pack.getDocuments() + ]) + const updates: any[] = [] + + // begin constructing update deltas for each document + for (const doc of docs) { + const updateDelta = migrateHTMLFields(doc, (str: string) => + migrateLinksInString(str, packIndices) + ) + if (updateDelta != null) updates.push(updateDelta) + } + + if (updates.length === 0) return + + if (dryRun) return updates + + const cls = pack.documentClass as typeof foundry.abstract.Document + + return await cls.updateDocuments(updates, { + pack: packID + }) +} + +export async function updateWorldDocumentLinks() { + const { actors, items, journal } = game +} + +type CompendiumIndex = Collection<{ + id: string + uuid: string + name: string + img: string +}> diff --git a/src/module/dataforged/rendering.ts b/src/module/dataforged/rendering.ts index bab461904..b1df458c3 100644 --- a/src/module/dataforged/rendering.ts +++ b/src/module/dataforged/rendering.ts @@ -6,6 +6,7 @@ import { hash } from '.' const COMPENDIUM_KEY_MAP = { 'Ironsworn/Moves': 'ironswornmoves', 'Ironsworn/Oracles': 'ironswornoracles', + 'Ironsworn/Encounters': 'ironswornfoes', 'Starforged/Moves': 'starforgedmoves', 'Starforged/Oracles': 'starforgedoracles', 'Starforged/Encounters': 'starforgedencounters' diff --git a/src/module/datasworn.ts b/src/module/datasworn.ts index 58df8c2be..c470914f4 100644 --- a/src/module/datasworn.ts +++ b/src/module/datasworn.ts @@ -1,5 +1,20 @@ +import type { ActorDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/actorData' +import { ItemDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/itemData' +import type { ConfiguredSource } from '@league-of-foundry-developers/foundry-vtt-types/src/types/helperTypes' +import { IEncounterIronsworn, ironsworn } from 'dataforged' +import { omit } from 'lodash-es' +import { IronswornActor } from './actor/actor' +import { hashLookup } from './dataforged' +import { IronswornItem } from './item/item.js' +import type { DelveSiteFeatureOrDanger } from './item/itemtypes' import type { DelveSiteFeatureOrDanger } from './item/subtypes/common' +const PACKS = [ + 'foundry-ironsworn.ironsworndelvethemes', + 'foundry-ironsworn.ironsworndelvedomains', + 'foundry-ironsworn.ironswornoracles' +] as const + const THEME_IMAGES = { Ancient: 'icons/environment/wilderness/carved-standing-stone.webp', Corrupted: 'icons/magic/unholy/beam-impact-purple.webp', @@ -52,78 +67,6 @@ const DOMAIN_IDS = { Underkeep: 'vyyrG8pPtDQ6FAgG' } as const -export const FOE_IMAGES = { - Broken: 'icons/creatures/mammals/humanoid-fox-cat-archer.webp', - 'Common Folk': 'icons/tools/hand/shovel-spade-steel-blue-brown.webp', - Hunter: 'icons/environment/people/archer.webp', - Mystic: 'icons/environment/people/cleric-orange.webp', - Raider: 'icons/sundries/flags/banner-flag-pirate.webp', - Warrior: 'icons/skills/melee/hand-grip-sword-red.webp', - Husk: 'icons/magic/earth/strike-body-stone-crumble.webp', - Zealot: 'icons/environment/people/cleric-grey.webp', - Elf: 'icons/creatures/magical/humanoid-horned-rider.webp', - Giant: 'icons/creatures/magical/humanoid-giant-forest-blue.webp', - Primordial: 'icons/creatures/magical/spirit-undead-horned-blue.webp', - Troll: 'icons/creatures/mammals/bull-horns-eyes-glowin-orange.webp', - Varou: 'icons/creatures/mammals/wolf-shadow-black.webp', - Atanya: 'icons/magic/air/wind-weather-sailing-ship.webp', - Merrow: 'icons/creatures/fish/fish-man-eye-green.webp', - Bear: 'icons/creatures/abilities/bear-roar-bite-brown-green.webp', - Boar: 'icons/commodities/treasure/figurine-boar.webp', - Gaunt: 'icons/magic/fire/elemental-creature-horse.webp', - 'Marsh Rat': 'icons/creatures/mammals/rodent-rat-diseaed-gray.webp', - Wolf: 'icons/creatures/abilities/wolf-howl-moon-purple.webp', - Bladewing: 'icons/creatures/magical/spirit-undead-winged-ghost.webp', - 'Carrion Newt': - 'icons/creatures/reptiles/chameleon-camouflage-green-brown.webp', - 'Cave Lion': 'icons/creatures/abilities/lion-roar-yellow.webp', - 'Deep Rat': 'icons/creatures/mammals/rodent-rat-green.webp', - 'Nightmare Spider': - 'icons/creatures/invertebrates/spider-mandibles-brown.webp', - 'Shroud Crab': 'icons/consumables/meat/claw-crab-lobster-serrated-pink.webp', - Trog: 'icons/creatures/reptiles/lizard-iguana-green.webp', - Basilisk: 'icons/creatures/reptiles/snake-poised-white.webp', - 'Elder Beast': - 'icons/creatures/mammals/beast-horned-scaled-glowing-orange.webp', - 'Harrow Spider': 'icons/creatures/invertebrates/spider-web-black.webp', - Leviathan: 'icons/creatures/reptiles/serpent-horned-green.webp', - Mammoth: 'icons/commodities/leather/fur-white.webp', - Wyvern: 'icons/creatures/abilities/wolf-heads-swirl-purple.webp', - Chitter: 'icons/creatures/invertebrates/bug-sixlegged-gray.webp', - Gnarl: 'icons/magic/nature/tree-animated-strike.webp', - 'Iron-Wracked Beast': 'icons/environment/wilderness/statue-hound-horned.webp', - Kraken: 'icons/creatures/fish/squid-kraken-orange.webp', - Nightspawn: 'icons/creatures/unholy/demon-horned-black-yellow.webp', - Rhaskar: 'icons/creatures/fish/fish-marlin-swordfight-blue.webp', - Wyrm: 'icons/creatures/eyes/lizard-single-slit-pink.webp', - Bonewalker: 'icons/magic/death/undead-skeleton-worn-blue.webp', - Frostbound: 'icons/creatures/magical/spirit-undead-ghost-blue.webp', - Chimera: 'icons/creatures/magical/spirit-earth-stone-magma-yellow.webp', - Haunt: 'icons/magic/death/undead-ghost-strike-white.webp', - Hollow: 'icons/consumables/plants/grass-leaves-green.webp', - 'Iron Revenant': 'icons/creatures/magical/construct-golem-stone-blue.webp', - Sodden: 'icons/magic/death/undead-ghost-scream-teal.webp', - Blighthound: 'icons/commodities/treasure/figurine-dog.webp', - 'Bog Rot': 'icons/magic/death/hand-dirt-undead-zombie.webp', - Bonehorde: 'icons/skills/trades/academics-study-archaeology-bones.webp', - Thrall: 'icons/creatures/abilities/mouth-teeth-human.webp', - Wight: 'icons/creatures/magical/humanoid-silhouette-green.webp', - 'Blood Thorn': 'icons/consumables/plants/thorned-stem-vine-green.webp', - 'Circle of Stones': 'icons/environment/wilderness/arch-stone.webp', - Glimmer: 'icons/magic/nature/elemental-plant-humanoid.webp', - Gloom: 'icons/magic/perception/silhouette-stealth-shadow.webp', - Maelstrom: 'icons/magic/water/vortex-water-whirlpool.webp', - Tempest: 'icons/magic/lightning/bolts-salvo-clouds-sky.webp' -} as const - -const PACKS = [ - 'foundry-ironsworn.ironsworndelvethemes', - 'foundry-ironsworn.ironsworndelvedomains', - 'foundry-ironsworn.ironswornfoes', - 'foundry-ironsworn.foeactorsis', - 'foundry-ironsworn.ironswornoracles' -] as const - interface RawFeatureOrDanger { Chance: number Description: string diff --git a/src/module/features/drag-and-drop.ts b/src/module/features/drag-and-drop.ts index ab04afca7..e4272ed20 100644 --- a/src/module/features/drag-and-drop.ts +++ b/src/module/features/drag-and-drop.ts @@ -1,3 +1,5 @@ +import type { SystemSubtype } from '../../config' + function getIndexEntry(el: HTMLElement) { const { documentId } = el.dataset const packId = $(el).parents('.compendium').data('pack') @@ -17,7 +19,10 @@ export function registerDragAndDropHooks() { typeof getIndexEntry > & { type: string } - CONFIG.IRONSWORN.emitter.emit('dragStart', indexEntry?.type) + CONFIG.IRONSWORN.emitter.emit( + 'dragStart', + indexEntry?.type as SystemSubtype + ) } ) .on( @@ -27,7 +32,10 @@ export function registerDragAndDropHooks() { typeof getIndexEntry > & { type: string } - CONFIG.IRONSWORN.emitter.emit('dragEnd', indexEntry?.type) + CONFIG.IRONSWORN.emitter.emit( + 'dragEnd', + indexEntry?.type as SystemSubtype + ) } ) }) diff --git a/src/module/vue/components/asset/player-assets.vue b/src/module/vue/components/asset/player-assets.vue index 742c9cfc8..96b2b8904 100644 --- a/src/module/vue/components/asset/player-assets.vue +++ b/src/module/vue/components/asset/player-assets.vue @@ -1,7 +1,7 @@