diff --git a/package-lock.json b/package-lock.json index 7056b606d..d3fcfc520 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,6 @@ "buffer": "^6.0.3", "chroma-js": "^2.4.2", "cssnano": "^6.0.1", - "dataforged": "^1.5", "eslint": "^8.57.0", "eslint-config-prettier": "^8.8.0", "eslint-config-standard-with-typescript": "^43", @@ -5772,11 +5771,6 @@ "node": ">= 12" } }, - "node_modules/dataforged": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dataforged/-/dataforged-1.5.3.tgz", - "integrity": "sha512-+0B/G1PIz+Fnx+WVCKYYQ2ujrBeYmm1WTn9gQ7Kh00Bm/JcLBBx1OqMzsxeow5AI1GgBld6oF3XJiNDN0rSPwQ==" - }, "node_modules/de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", diff --git a/package.json b/package.json index 09f0794e1..03ef53f82 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "buffer": "^6.0.3", "chroma-js": "^2.4.2", "cssnano": "^6.0.1", - "dataforged": "^1.5", "eslint": "^8.57.0", "eslint-config-prettier": "^8.8.0", "eslint-config-standard-with-typescript": "^43", diff --git a/src/config.ts b/src/config.ts index 334461a41..82325e444 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,7 +1,5 @@ import { IronswornActor } from './module/actor/actor' -import * as dataforgedHelpers from './module/dataforged' // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { starforged } from 'dataforged' import type { Emitter, EventType } from 'mitt' import Mitt from 'mitt' import { @@ -49,9 +47,6 @@ export interface IronswornConfig { IronswornRollMessage: typeof IronswornRollMessage } - Dataforged: typeof starforged - dataforgedHelpers: typeof dataforgedHelpers - emitter: IronswornEmitter registerOracleTree: typeof registerOracleTree @@ -82,9 +77,6 @@ export const IRONSWORN: IronswornConfig = { IronswornRollMessage }, - Dataforged: starforged, - dataforgedHelpers, - emitter: Mitt(), registerOracleTree, diff --git a/src/module/dataforged/data.ts b/src/module/dataforged/data.ts deleted file mode 100644 index 9fb57f743..000000000 --- a/src/module/dataforged/data.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { Starforged, Ironsworn } from 'dataforged' -import { starforged, ironsworn } from 'dataforged' - -// For some reason, rollupJs mangles this -export const SFMoveCategories = ((starforged as any).default as Starforged)[ - 'Move Categories' -] -export const ISMoveCategories = ((ironsworn as any).default as Ironsworn)[ - 'Move Categories' -] -export const SFOracleCategories = ((starforged as any).default as Starforged)[ - 'Oracle Categories' -] -export const ISOracleCategories = ((ironsworn as any).default as Ironsworn)[ - 'Oracle Categories' -] -export const SFAssetTypes = ((starforged as any).default as Starforged)[ - 'Asset Types' -] -export const ISAssetTypes = ((ironsworn as any).default as Ironsworn)[ - 'Asset Types' -] diff --git a/src/module/dataforged/images.ts b/src/module/dataforged/images.ts deleted file mode 100644 index 55adba52a..000000000 --- a/src/module/dataforged/images.ts +++ /dev/null @@ -1,208 +0,0 @@ -export const DATAFORGED_ICON_MAP = { - ironsworn: { - theme: { - Ancient: 'icons/environment/wilderness/carved-standing-stone.webp', - Corrupted: 'icons/magic/unholy/beam-impact-purple.webp', - Fortified: 'icons/environment/settlement/watchtower-cliff.webp', - Hallowed: 'icons/magic/holy/angel-wings-gray.webp', - Haunted: 'icons/creatures/magical/spirit-undead-horned-blue.webp', - Infested: 'icons/creatures/eyes/icy-cluster-blue.webp', - Ravaged: 'icons/environment/settlement/building-rubble.webp', - Wild: 'icons/magic/nature/root-vines-grow-brown.webp' - }, - domain: { - Barrow: 'icons/environment/wilderness/cave-entrance-dwarven-hill.webp', - Cavern: 'icons/environment/wilderness/cave-entrance-mountain-blue.webp', - 'Frozen Cavern': 'icons/magic/water/water-iceberg-bubbles.webp', - Icereach: 'icons/magic/water/barrier-ice-crystal-wall-jagged-blue.webp', - Mine: 'icons/environment/settlement/mine-cart-rocks-red.webp', - Pass: 'icons/environment/wilderness/cave-entrance-rocky.webp', - Ruin: 'icons/environment/wilderness/wall-ruins.webp', - 'Sea Cave': 'icons/environment/wilderness/cave-entrance-island.webp', - Shadowfen: 'icons/environment/wilderness/cave-entrance.webp', - Stronghold: 'icons/environment/settlement/castle.webp', - Tanglewood: 'icons/environment/wilderness/terrain-forest-gray.webp', - Underkeep: 'icons/environment/wilderness/mine-interior-dungeon-door.webp' - }, - foe: { - 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' - } - }, - starforged: { - foe: { - 'Starforged/Encounters/Chiton': - 'icons/creatures/invertebrates/spider-large-white-green.webp', - 'Starforged/Encounters/Chiton/Chiton_Drone_Pack': - 'icons/creatures/invertebrates/spider-large-white-green.webp', - 'Starforged/Encounters/Chiton/Chiton_Queen': - 'icons/creatures/invertebrates/spider-large-white-green.webp', - 'Starforged/Encounters/Colossus': - 'icons/creatures/magical/construct-iron-stomping-yellow.webp', - 'Starforged/Encounters/Colossus/Devotant_of_the_Colossi': - 'icons/creatures/magical/construct-iron-stomping-yellow.webp', - 'Starforged/Encounters/Crystallid': - 'icons/magic/water/ice-crystal-white.webp', - 'Starforged/Encounters/Crystallid/Convergent_Crystallid': - 'icons/magic/water/ice-crystal-white.webp', - 'Starforged/Encounters/Drift_Pirate': - 'icons/skills/trades/profession-sailing-pirate.webp', - 'Starforged/Encounters/Drift_Pirate/Pirate_Boarding_Party': - 'icons/skills/trades/profession-sailing-pirate.webp', - 'Starforged/Encounters/Drift_Pirate/Pirate_Cutlass': - 'icons/skills/trades/profession-sailing-pirate.webp', - 'Starforged/Encounters/Ember_Wisp': - 'icons/magic/light/orbs-smoke-pink.webp', - 'Starforged/Encounters/Ember_Wisp/Wisp_Congregation': - 'icons/magic/light/orbs-smoke-pink.webp', - 'Starforged/Encounters/Firestorm_Trooper': - 'icons/equipment/head/helm-barbute-white.webp', - 'Starforged/Encounters/Firestorm_Trooper/Firestorm_Raiding_Team': - 'icons/equipment/head/helm-barbute-white.webp', - 'Starforged/Encounters/Firestorm_Trooper/Firestorm_Dropship': - 'icons/equipment/head/helm-barbute-white.webp', - 'Starforged/Encounters/Flarewing_Shark': - 'icons/creatures/fish/fish-shark-swimming.webp', - 'Starforged/Encounters/Flarewing_Shark/Mega_Flarewing': - 'icons/creatures/fish/fish-shark-swimming.webp', - 'Starforged/Encounters/Ghost': - 'icons/creatures/magical/spirit-undead-horned-blue.webp', - 'Starforged/Encounters/Ghost/Ghost_Ship': - 'icons/creatures/magical/spirit-undead-horned-blue.webp', - 'Starforged/Encounters/Gnawling': - 'icons/creatures/mammals/rodent-rat-green.webp', - 'Starforged/Encounters/Gnawling/Gnawling_Brood_Mother': - 'icons/creatures/mammals/rodent-rat-green.webp', - 'Starforged/Encounters/Howlcat': - 'icons/creatures/mammals/cat-hunched-glowing-red.webp', - 'Starforged/Encounters/Howlcat/Howlcat_Pack': - 'icons/creatures/mammals/cat-hunched-glowing-red.webp', - 'Starforged/Encounters/Iron_Auger': - 'icons/creatures/fish/squid-kraken-orange.webp', - 'Starforged/Encounters/Iron_Auger/Machine_Mites': - 'icons/creatures/fish/squid-kraken-orange.webp', - 'Starforged/Encounters/Iron_Auger/Planet-Eater': - 'icons/creatures/fish/squid-kraken-orange.webp', - 'Starforged/Encounters/Puppet_Vine': - 'icons/magic/nature/plant-vines-skull-green.webp', - 'Starforged/Encounters/Puppet_Vine/Flowering_Puppet_Vine': - 'icons/magic/nature/plant-vines-skull-green.webp', - 'Starforged/Encounters/Pyralis': - 'icons/creatures/invertebrates/fly-wasp-mosquito-green.webp', - 'Starforged/Encounters/Pyralis/Pyralis_Youngling': - 'icons/creatures/invertebrates/fly-wasp-mosquito-green.webp', - 'Starforged/Encounters/Risen': - 'icons/magic/death/undead-skeleton-rags-fire-green.webp', - 'Starforged/Encounters/Risen/Chimera': - 'icons/magic/death/undead-skeleton-rags-fire-green.webp', - 'Starforged/Encounters/Scrap_Bandit': - 'icons/equipment/head/hat-belted-simple.webp', - 'Starforged/Encounters/Scrap_Bandit/Hover_Prowlers': - 'icons/equipment/head/hat-belted-simple.webp', - 'Starforged/Encounters/Scrap_Bandit/War_Rig': - 'icons/equipment/head/hat-belted-simple.webp', - 'Starforged/Encounters/Servitor': - 'icons/creatures/magical/construct-stone-earth-gray.webp', - 'Starforged/Encounters/Servitor/Enforcer': - 'icons/creatures/magical/construct-stone-earth-gray.webp', - 'Starforged/Encounters/Sicklehorn': - 'icons/creatures/mammals/goat-horned-blue.webp', - 'Starforged/Encounters/Sicklehorn/Sicklehorn_Matriarch': - 'icons/creatures/mammals/goat-horned-blue.webp', - 'Starforged/Encounters/Sicklehorn/Sicklehorn_Stampede': - 'icons/creatures/mammals/goat-horned-blue.webp', - 'Starforged/Encounters/Sky_Roost': - 'icons/magic/nature/root-vine-caduceus-healing.webp', - 'Starforged/Encounters/Sky_Roost/Roost_Swarm': - 'icons/magic/nature/root-vine-caduceus-healing.webp', - 'Starforged/Encounters/Technoplasm': - 'icons/creatures/slimes/slime-movement-pseudopods-blue.webp', - 'Starforged/Encounters/Technoplasm/Infected_Bot': - 'icons/creatures/slimes/slime-movement-pseudopods-blue.webp', - 'Starforged/Encounters/Technoplasm/Scourge_Ship': - 'icons/creatures/slimes/slime-movement-pseudopods-blue.webp', - 'Starforged/Encounters/Void_Shepherd': - 'icons/creatures/fish/fish-bioluminous-blue.webp', - 'Starforged/Encounters/Void_Shepherd/Shepherd_Pod': - 'icons/creatures/fish/fish-bioluminous-blue.webp', - 'Starforged/Encounters/Warden': - 'icons/magic/holy/angel-winged-humanoid-blue.webp', - 'Starforged/Encounters/Warden/Warden_Cohort': - 'icons/magic/holy/angel-winged-humanoid-blue.webp', - 'Starforged/Encounters/Warden/Fury': - 'icons/magic/holy/angel-winged-humanoid-blue.webp', - 'Starforged/Encounters/Water_Witcher': - 'icons/creatures/mammals/elk-moose-marked-green.webp', - 'Starforged/Encounters/Water_Witcher/Dowser': - 'icons/creatures/mammals/elk-moose-marked-green.webp', - 'Starforged/Encounters/Worldbreaker': - 'icons/creatures/abilities/mouth-teeth-rows-white.webp', - 'Starforged/Encounters/Worldbreaker/Worldbreaker_Brood': - 'icons/creatures/abilities/mouth-teeth-rows-white.webp', - 'Starforged/Encounters/Worldbreaker/Elder_Worm': - 'icons/creatures/abilities/mouth-teeth-rows-white.webp' - } - } -} diff --git a/src/module/dataforged/import.ts b/src/module/dataforged/import.ts deleted file mode 100644 index 7cbede78a..000000000 --- a/src/module/dataforged/import.ts +++ /dev/null @@ -1,560 +0,0 @@ -import type { ItemDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/itemData' -import type { RollTableDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/rollTableData' -import type { - IAssetType, - IMoveCategory, - IOracle, - IOracleCategory, - Ironsworn, - ISettingTruth, - Starforged -} from 'dataforged' -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import { starforged, ironsworn } 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 { - ISAssetTypes, - ISMoveCategories, - ISOracleCategories, - SFAssetTypes, - SFMoveCategories, - SFOracleCategories -} from './data' -import { DATAFORGED_ICON_MAP } from './images' -import { renderMarkdown } from './rendering' -import type { FolderDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/folderData' -import { MoveCategoryColor } from '../features/custommoves' -import { IronswornHandlebarsHelpers } from '../helpers/handlebars' - -export function cleanDollars(obj): any { - if (isArray(obj)) { - const ret = [] as any[] - for (const item of obj) { - ret.push(cleanDollars(item)) - } - return ret - } else if (isObject(obj)) { - const ret = {} as any - for (const k of Object.keys(obj)) { - let newK = k - if (newK.startsWith('$')) { - newK = 'df' + k.substring(1) - } - ret[newK] = cleanDollars(obj[k]) - } - return ret - } - return obj -} - -const HASH_CACHE = {} as Record -export function hashLookup(str: string): string { - HASH_CACHE[str] ||= hash(str) - return HASH_CACHE[str] -} - -export function hash(str: string): string { - return shajs('sha256').update(str).digest('hex').substring(48) -} - -const PACKS = [ - 'foundry-ironsworn.starforgedassets', - 'foundry-ironsworn.starforgedencounters', - 'foundry-ironsworn.starforgedmoves', - 'foundry-ironsworn.starforgedoracles', - 'foundry-ironsworn.starforgedtruths', - 'foundry-ironsworn.foeactorssf', - 'foundry-ironsworn.ironswornassets', - 'foundry-ironsworn.ironswornoracles', - 'foundry-ironsworn.ironswornmoves' -] as const - -/** - * Converts JSON from dataforged resources into foundry packs. Requires packs to - * already exist, but will empty them prior to repopulating. In a perfect world - * we would retain dataforged's $id as Foundry's _id, but Foundry validates that - * those fields meet with its UID expectations (/[a-zA-Z0-9]{16}/) - */ -export async function importFromDataforged() { - // Empty out the packs - for (const key of PACKS) { - const pack = game.packs.get(key) - if (pack == null) continue - - // Unlock all the packs - await pack.configure({ locked: false }) - - // Delete all the contents - const idsToDelete = pack.index.map((x) => x._id) - await getDocumentClass(pack.metadata.type).deleteDocuments(idsToDelete, { - pack: key - }) - // @ts-expect-error outdated typing - if (pack.folders.size > 0) - // @ts-expect-error outdated typing - await Folder.deleteDocuments(Array.from(pack.folders.keys()), { - pack: key - }) - } - - await Promise.all([ - processSFMoves(), - processSFAssets(), - processISAssets(), - processSFOracles(), - processISMoves(), - processISOracles(), - // processISTruths(), // Re-enable when DF includes them - processSFTruths(), - processSFEncounters().then(async () => { - await processSFFoes() - }) - ]) - - // Lock the packs again - for (const key of PACKS) { - await game.packs.get(key)?.configure({ locked: true }) - } -} - -/** - * MOVES - */ - -function getMoveFolderData( - moveCategory: IMoveCategory -): FolderDataConstructorData { - return { - name: `${moveCategory.Name} Moves`, - type: 'Item', - _id: hashLookup(moveCategory.$id), - // workaround for incorrect move colors in DFv1 - color: MoveCategoryColor[moveCategory.Name], - description: moveCategory.Description, - sort: - (moveCategory.Source.Page ?? 0) + - (moveCategory.Source.Title.includes('Delve') ? 1000 : 0), - flags: { 'foundry-ironsworn': { dfid: moveCategory.$id } } - } -} - -function movesForCategories( - categories: IMoveCategory[] -): Array> { - const movesToCreate = [] as Array< - ItemDataConstructorData & Record - > - for (const category of categories) { - const folder = hashLookup(category.$id) - for (const move of category.Moves) { - renderLinksInMove(move) - const cleanMove = cleanDollars(move) - - console.log(move.Name, move.$id) - movesToCreate.push({ - _id: hashLookup(cleanMove.dfid), - type: 'sfmove', - name: move.Name + (move.$id.endsWith('_alt') ? ' (alt)' : ''), - img: 'icons/dice/d10black.svg', - system: cleanMove, - sort: move.Source.Page, - folder - }) - } - } - return movesToCreate -} - -async function processISMoves() { - const pack = 'foundry-ironsworn.ironswornmoves' - await Folder.createDocuments( - ISMoveCategories.map((moveCategory) => getMoveFolderData(moveCategory)), - { pack, keepId: true } - ) - const movesToCreate = movesForCategories(ISMoveCategories) - await Item.createDocuments(movesToCreate, { - pack, - keepId: true - }) -} -async function processSFMoves() { - const pack = 'foundry-ironsworn.starforgedmoves' - await Folder.createDocuments( - SFMoveCategories.map((moveCategory) => getMoveFolderData(moveCategory)), - { pack, keepId: true } - ) - const movesToCreate = movesForCategories(SFMoveCategories) - await Item.createDocuments(movesToCreate, { - pack, - keepId: true - }) -} - -/** - * ASSSETS - */ - -function getAssetFolderData(assetType: IAssetType): FolderDataConstructorData { - return { - name: assetType.Name, - color: assetType.Display.Color, - description: assetType.Description, - type: 'Item', - _id: hashLookup(assetType.$id), - sort: assetType.Source.Page, - flags: { 'foundry-ironsworn': { dfid: assetType.$id } } - } -} - -function assetsForTypes(types: IAssetType[]) { - const assetsToCreate = [] as Array< - ItemDataConstructorData & Record - > - for (const assetType of types) { - const folder = hashLookup(assetType.$id) - for (const asset of assetType.Assets) { - // Inputs map to fields and exclusive options - const fields = [] as Array<{ name: string; value: string }> - const exclusiveOptions = [] as Array<{ name: string; selected: boolean }> - // TODO: "Number" - for (const input of asset.Inputs ?? []) { - if (input['Input Type'] === 'Text') { - fields.push({ name: input.Name, value: '' }) - } - if (input['Input Type'] === 'Select') { - for (const option of input.Options) { - exclusiveOptions.push({ name: option.Name, selected: false }) - } - } - } - - const data = { - requirement: renderMarkdown(asset.Requirement ?? ''), - category: assetType.Name, - color: assetType.Display.Color ?? '', - fields, - abilities: (asset.Abilities ?? []).map((ability) => { - const ret = { - enabled: ability.Enabled || false, - description: renderMarkdown(ability.Text) - } as any - - for (const input of ability.Inputs ?? []) { - if (input['Input Type'] === 'Clock') { - const ic = input - ret.hasClock = true - ret.clockMax = ic.Segments - ret.clockTicks = ic.Filled - } - } - - return ret - }), - track: { - enabled: asset['Condition Meter'] != null, - name: asset['Condition Meter']?.Name, - current: asset['Condition Meter']?.Value, - max: asset['Condition Meter']?.Max - }, - exclusiveOptions, - conditions: (asset['Condition Meter']?.Conditions ?? []).map( - (name) => ({ name, selected: false }) - ) - } - assetsToCreate.push({ - type: 'asset', - _id: hashLookup(asset.$id), - folder, - name: asset.Name, - system: data - }) - } - } - return assetsToCreate -} - -async function processSFAssets() { - const pack = 'foundry-ironsworn.starforgedassets' - await Folder.createDocuments( - SFAssetTypes.map((assetType) => getAssetFolderData(assetType)), - { pack, keepId: true } - ) - const assetsToCreate = assetsForTypes(SFAssetTypes) - await Item.createDocuments(assetsToCreate, { - pack, - keepId: true - }) -} - -async function processISAssets() { - const pack = 'foundry-ironsworn.ironswornassets' - await Folder.createDocuments( - ISAssetTypes.map((assetType) => getAssetFolderData(assetType)), - { pack, keepId: true } - ) - const assetsToCreate = assetsForTypes(ISAssetTypes) - await Item.createDocuments(assetsToCreate, { - pack, - keepId: true - }) -} - -/** - * ORACLES - */ - -function getOracleFolderData( - oracleBranch: IOracleCategory | IOracle, - parent?: string -): FolderDataConstructorData { - if ('Oracles' in oracleBranch) - return { - name: oracleBranch.Name, - _id: hashLookup(oracleBranch.$id), - type: 'RollTable', - description: oracleBranch.Description, - sort: - (oracleBranch.Source.Page ?? 0) + - (oracleBranch.Source.Title.includes('Delve') ? 1000 : 0), - flags: { 'foundry-ironsworn': { dfid: oracleBranch.$id } }, - parent - } - console.log(oracleBranch) - throw new Error("Data isn't an oracle tree branch") -} - -async function processOracle( - oracle: IOracle, - output: { - RollTable: RollTableDataConstructorData[] - Folder: FolderDataConstructorData[] - }, - folder: string -) { - // Oracles JSON is a tree we wish to iterate through depth first adding - // parents prior to their children, and children in order - if (oracle.Table != null) - output.RollTable.push({ - ...OracleTable.getConstructorData(oracle as any), - folder, - name: oracle.Name + (oracle.$id.endsWith('_alt') ? ' (alt)' : ''), - sort: - (oracle.Source.Page ?? 0) + - (oracle.Source.Title.includes('Delve') ? 1000 : 0) - }) - - if ('Oracles' in oracle) - output.Folder.push(getOracleFolderData(oracle, folder)) - - for (const child of oracle.Oracles ?? []) - await processOracle(child, output, hashLookup(oracle.$id)) -} -async function processOracleCategory( - cat: IOracleCategory, - output: { - RollTable: RollTableDataConstructorData[] - Folder: FolderDataConstructorData[] - }, - /** The Foundry ID of the parent folder, if any. */ - parent?: string -) { - const folderData = getOracleFolderData(cat, parent) - output.Folder.push(folderData) - for (const oracle of cat.Oracles ?? []) - await processOracle(oracle, output, folderData._id as string) - for (const child of cat.Categories ?? []) - await processOracleCategory(child, output, folderData._id as string) -} - -async function processSFOracles() { - const toCreate: { - RollTable: RollTableDataConstructorData[] - Folder: FolderDataConstructorData[] - } = { RollTable: [], Folder: [] } - const pack = 'foundry-ironsworn.starforgedoracles' - - for (const category of SFOracleCategories) { - await processOracleCategory(category, toCreate) - } - await Folder.createDocuments(toCreate.Folder, { pack, keepId: true }) - await OracleTable.createDocuments(toCreate.RollTable, { - pack, - keepId: true - }) -} - -async function processISOracles() { - const toCreate: { - RollTable: RollTableDataConstructorData[] - Folder: FolderDataConstructorData[] - } = { RollTable: [], Folder: [] } - - const pack = 'foundry-ironsworn.ironswornoracles' - - for (const category of ISOracleCategories) { - await processOracleCategory(category, toCreate) - } - await Folder.createDocuments(toCreate.Folder, { pack, keepId: true }) - await OracleTable.createDocuments(toCreate.RollTable, { - pack, - keepId: true - }) -} - -async function processSFEncounters() { - const encountersToCreate = [] as Array< - ItemDataConstructorData & Record - > - for (const encounter of starforged.Encounters) { - const renderedDescription = await IronswornHandlebarsHelpers.enrichMarkdown( - encounter.Description - ) - const description = await renderTemplate( - 'systems/foundry-ironsworn/templates/item/sf-foe.hbs', - { - ...encounter, - Description: renderedDescription, - variantLinks: encounter.Variants.map((x) => - renderLinksInStr(`[${x.Name}](${x.$id})`) - ) - } - ) - - encountersToCreate.push({ - _id: hashLookup(encounter.$id), - type: 'progress', - name: encounter.Name, - img: DATAFORGED_ICON_MAP.starforged.foe[encounter.$id], - system: { - description, - rank: encounter.Rank - } - }) - - 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 - } - ) - - 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 - } - }) - } - } - await Item.createDocuments(encountersToCreate, { - pack: 'foundry-ironsworn.starforgedencounters', - keepId: 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' } - ) - await actor?.createEmbeddedDocuments('Item', [ - { - name: foeItem.name ?? 'wups', - type: 'progress', - system: foeItem.system as unknown as Record - } - ]) - } -} - -async function processTruths( - truths: ISettingTruth[], - outputCompendium: string -) { - const pack = game.packs.get(outputCompendium) - if (pack == null) throw new Error(`Couldn't find ${outputCompendium}`) - - for (const truth of truths) { - const je = await IronswornJournalEntry.create( - { - name: truth.Display.Title, - flags: { - 'foundry-ironsworn': { dfid: truth.$id, type: 'truth-category' } - } - }, - { pack: outputCompendium } - ) - - for (const entry of truth.Table) { - await IronswornJournalPage.create( - { - type: 'truth', - name: entry.Result, - system: cleanDollars({ - Subtable: [], // work around a Foundry bug - ...entry, - Quest: entry['Quest Starter'], - 'Quest Starter': undefined - }) - }, - { parent: je } - ) - } - - await IronswornJournalPage.create( - { - name: 'Character Inspiration', - type: 'text', - text: { - markdown: truth.Character, - format: 2 // JOURNAL_ENTRY_PAGE_FORMATS.MARKDOWN - }, - flags: { - 'foundry-ironsworn': { - assets: truth.Suggestions?.Assets ?? [] - } - } - }, - { parent: je } - ) - } -} - -async function processSFTruths() { - await processTruths( - ((starforged as any).default as Starforged)['Setting Truths'], - 'foundry-ironsworn.starforgedtruths' - ) -} - -async function processISTruths() { - await processTruths( - ((ironsworn as any).default as Ironsworn)['Setting Truths']!, - 'foundry-ironsworn.starforgedtruths' - ) -} diff --git a/src/module/dataforged/index.ts b/src/module/dataforged/index.ts deleted file mode 100644 index d82a1e415..000000000 --- a/src/module/dataforged/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './import' -export * from './rendering' diff --git a/src/module/dataforged/rendering.ts b/src/module/dataforged/rendering.ts deleted file mode 100644 index 23b940e1a..000000000 --- a/src/module/dataforged/rendering.ts +++ /dev/null @@ -1,71 +0,0 @@ -import type { IMove } from 'dataforged' -import { get, set } from 'lodash-es' -import { hash } from '.' - -const COMPENDIUM_KEY_MAP = { - 'Ironsworn/Moves': 'ironswornmoves', - 'Ironsworn/Oracles': 'ironswornoracles', - 'Starforged/Moves': 'starforgedmoves', - 'Starforged/Oracles': 'starforgedoracles', - 'Starforged/Encounters': 'starforgedencounters' - // TODO: Sundered Isles -} -const MARKDOWN_LINK_RE = /\[(.*?)\]\((.*?)\)/g -const DESCRIPTOR_FOCUS_RE = /\[Descriptor \+ Focus\]\(.*?\)/ -const ACTION_THEME_RE = /\[Action \+ Theme\]\(.*?\)/ - -function idIsOracleLink(dfid: string): boolean { - return /^(Starforged|Ironsworn)\/Oracle/.test(dfid) -} - -export function renderLinksInStr(text: string): string { - // Strip "Black Medium Right-Pointing Triangle" characters - text = text.replace('\u23f5', '') - - // Strip brackets from e.g. factions/name template - text = text.replace(/\[(\[.*?\))\]/g, '$1') - - // Catch "Descriptor+Focus" or "Action+Theme" and replace with two links - text = text.replace( - DESCRIPTOR_FOCUS_RE, - '[Descriptor](Starforged/Oracles/Core/Descriptor) + [Focus](Starforged/Oracles/Core/Focus)' - ) - text = text.replace( - ACTION_THEME_RE, - '[Action](Starforged/Oracles/Core/Action) + [Theme](Starforged/Oracles/Core/Theme)' - ) - - return text.replace(MARKDOWN_LINK_RE, (match, text, url) => { - const parts = url.split('/') - const kind = `${parts[0]}/${parts[1]}` - const compendiumKey = COMPENDIUM_KEY_MAP[kind] - if (!compendiumKey) return match - if (idIsOracleLink(url)) { - return ` ${text}` - } - return `@Compendium[foundry-ironsworn.${compendiumKey}.${hash( - url - )}]{${text}}` - }) -} - -export function renderMarkdown(md: string) { - return CONFIG.IRONSWORN.showdown.makeHtml(renderLinksInStr(md)) -} - -export function renderLinksInMove(move: IMove) { - const textProperties = [ - 'Text', - 'Trigger.Text', - 'Outcomes.Strong Hit.Text', - 'Outcomes.Strong Hit.With a Match.Text', - 'Outcomes.Weak Hit.Text', - 'Outcomes.Miss.Text', - 'Outcomes.Miss.With a Match.Text' - ] - for (const prop of textProperties) { - const text = get(move, prop) - if (!text) continue - set(move, prop, renderLinksInStr(text)) - } -} diff --git a/src/module/datasworn2/import/index.ts b/src/module/datasworn2/import/index.ts index 6dc671a1c..05d5136fc 100644 --- a/src/module/datasworn2/import/index.ts +++ b/src/module/datasworn2/import/index.ts @@ -353,10 +353,7 @@ for (const collection of collections) { Date: move._source.date, Page: move._source.page }, - Suggestions: {}, - Display: { - Images: [] - } + Suggestions: {} }, sort: move._source.page ?? 0, flags: { diff --git a/src/module/features/customoracles.ts b/src/module/features/customoracles.ts index 9ff4d9d7f..75862ab11 100644 --- a/src/module/features/customoracles.ts +++ b/src/module/features/customoracles.ts @@ -4,19 +4,15 @@ import type { OracleTablesCollection, RulesetId } from '@datasworn/core/dist/Datasworn' -import type { IOracle, IOracleCategory } from 'dataforged' import { cloneDeep, compact } from 'lodash-es' import { - COMPENDIUM_KEY_MAP, DataswornTree, getPackAndIndexForCompendiumKey, IdParser } from '../datasworn2' import { DataswornRulesetKey, IronswornSettings } from '../helpers/settings' -import { OracleTable } from '../roll-table/oracle-table' export interface IOracleTreeNode { - dataforgedNode?: IOracle | IOracleCategory dataswornNode?: OracleCollection | OracleRollableTable dsIdentifier?: string // the last part of the dsid tables: string[] // UUIDs @@ -123,22 +119,6 @@ export function findPathToNodeByTableUuid( return ret } -export function findPathToNodeByDfId(rootNode: IOracleTreeNode, dfid: string) { - const ret: IOracleTreeNode[] = [] - function walk(node: IOracleTreeNode) { - ret.push(node) - if (node.dataforgedNode?.$id === dfid) return true - for (const child of node.children) { - if (walk(child)) return true - } - ret.pop() - return false - } - - walk(rootNode) - return ret -} - const ORACLES: Record = {} export function registerOracleTreeInternal( diff --git a/src/module/fields/DisplayField.ts b/src/module/fields/DisplayField.ts deleted file mode 100644 index 6ac81b202..000000000 --- a/src/module/fields/DisplayField.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { IDisplay } from 'dataforged' - -export class DisplayField extends foundry.data.fields.SchemaField { - constructor() { - const fields = foundry.data.fields - super({ - // @ts-expect-error - Color: new fields.ColorField({ required: false, nullable: true }), - // @ts-expect-error - Images: new fields.ArrayField( - new fields.FilePathField({ categories: ['IMAGE'] }) - ) - }) - } -} - -export interface Display extends Omit {} diff --git a/src/module/fields/SourceField.ts b/src/module/fields/SourceField.ts index 13f449fc4..b810e2e61 100644 --- a/src/module/fields/SourceField.ts +++ b/src/module/fields/SourceField.ts @@ -1,6 +1,6 @@ -import type { ISource } from 'dataforged' +import type { DFISource } from '../item/types' -export class SourceField extends foundry.data.fields.SchemaField { +export class SourceField extends foundry.data.fields.SchemaField { constructor() { const fields = foundry.data.fields diff --git a/src/module/fields/types/StringField.ts b/src/module/fields/types/StringField.ts index 51c9e90a9..81f1ad3d0 100644 --- a/src/module/fields/types/StringField.ts +++ b/src/module/fields/types/StringField.ts @@ -1,7 +1,5 @@ /* eslint-disable @typescript-eslint/no-namespace */ -import type { RequireKey } from 'dataforged' - declare global { namespace foundry { namespace data { @@ -159,9 +157,7 @@ declare global { base64: boolean wildcard: boolean - constructor( - options: RequireKey>, 'categories'> - ) + constructor(options: Partial>) } export interface FilePathField< T extends FilePathField.FileCategory = FilePathField.FileCategory diff --git a/src/module/helpers/util.ts b/src/module/helpers/util.ts index a56ea6cfa..fc2267452 100644 --- a/src/module/helpers/util.ts +++ b/src/module/helpers/util.ts @@ -1,5 +1,6 @@ +import shajs from 'sha.js' import type { Metadata } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/abstract/document.mjs' -import type { KeysWithValuesOfType } from 'dataforged' +import type { DFKeysWithValuesOfType } from '../item/types' /** * @remarks A document-subtype-sensitive replacement for the FVTT document deletion dialog. @@ -11,7 +12,7 @@ export async function typedDeleteDialog< } >(document: T, options: Partial = {}): Promise { const docType = document.documentName as T['documentName'] & - KeysWithValuesOfType< + DFKeysWithValuesOfType< typeof CONFIG, { typeLabels: Record } > @@ -35,3 +36,13 @@ export async function typedDeleteDialog< options })) as any } + +const HASH_CACHE = {} as Record +export function hashLookup(str: string): string { + HASH_CACHE[str] ||= hash(str) + return HASH_CACHE[str] +} + +export function hash(str: string): string { + return shajs('sha256').update(str).digest('hex').substring(48) +} diff --git a/src/module/item/config.ts b/src/module/item/config.ts index 95b86bd3f..5d089f000 100644 --- a/src/module/item/config.ts +++ b/src/module/item/config.ts @@ -1,5 +1,4 @@ import type { ConfiguredData } from '@league-of-foundry-developers/foundry-vtt-types/src/types/helperTypes' -import type { PartialDeep } from 'dataforged' import { IronswornItem } from './item' import { AssetModel } from './subtypes/asset' import { BondsetModel } from './subtypes/bondset' @@ -25,7 +24,8 @@ import type { ProgressDataSource } from './subtypes/progress' import type { SFMoveDataProperties, SFMoveDataSource } from './subtypes/sfmove' -import { ChallengeRank } from '../fields/ChallengeRank' +import type { ChallengeRank } from '../fields/ChallengeRank' +import type { DFPartialDeep } from './types' const dataModels: Partial< Record< @@ -56,7 +56,7 @@ export interface ItemConfig extends _itemConfig { typeIcons: Record } -const config: PartialDeep = { +const config: DFPartialDeep = { documentClass: IronswornItem, dataModels, typeLabels: { @@ -114,6 +114,7 @@ declare global { interface FlagConfig { Item: { 'foundry-ironsworn'?: { + dsid?: string expanded?: boolean muteBroadcast?: boolean 'edit-mode'?: boolean diff --git a/src/module/item/subtypes/sfmove.ts b/src/module/item/subtypes/sfmove.ts index 3adec5a09..da407fef1 100644 --- a/src/module/item/subtypes/sfmove.ts +++ b/src/module/item/subtypes/sfmove.ts @@ -1,15 +1,13 @@ -import type { - IMove, - IMoveTrigger, - IMoveTriggerOptionAction, - IMoveTriggerOptionProgress, - IOutcomeInfo -} from 'dataforged' import { DataforgedIDField } from '../../fields/DataforgedIDField' -import type { Display } from '../../fields/DisplayField' -import { DisplayField } from '../../fields/DisplayField' import { SourceField } from '../../fields/SourceField' import type { IronswornItem } from '../item' +import type { + DFIMove, + DFIMoveTrigger, + DFIMoveTriggerOptionAction, + DFIMoveTriggerOptionProgress, + DFIOutcomeInfo +} from '../types' export class SFMoveModel extends foundry.abstract.TypeDataModel< SFMoveDataSourceData, @@ -97,7 +95,6 @@ export class SFMoveModel extends foundry.abstract.TypeDataModel< Category: new DataforgedIDField(), Source: new SourceField(), 'Progress Move': new fields.BooleanField(), - Display: new DisplayField(), Text: new fields.HTMLField(), Oracles: new fields.ArrayField(new DataforgedIDField()), dsOracleIds: new fields.ArrayField(new fields.StringField()), @@ -115,7 +112,7 @@ export class SFMoveModel extends foundry.abstract.TypeDataModel< } export interface SFMoveOutcome - extends Omit {} + extends Omit {} export interface SFMoveOutcomeMatchable extends SFMoveOutcome { 'With a Match'?: SFMoveOutcome } @@ -183,11 +180,10 @@ export interface SFMoveModel extends SFMoveDataSourceData {} export interface SFMoveDataSourceData extends Required< - Pick + Pick > { dfid: string Trigger: SFMoveTrigger - Display: Display Outcomes?: { 'Strong Hit': SFMoveOutcomeMatchable 'Weak Hit': SFMoveOutcome @@ -196,12 +192,12 @@ export interface SFMoveDataSourceData dsOracleIds: string[] } -export interface SFMoveTrigger extends Pick { +export interface SFMoveTrigger extends Pick { Options: SFMoveTriggerOption[] } type SFMoveTriggerOption = Omit< - IMoveTriggerOptionAction | IMoveTriggerOptionProgress, + DFIMoveTriggerOptionAction | DFIMoveTriggerOptionProgress, '$id' | 'Custom stat' > diff --git a/src/module/item/types.d.ts b/src/module/item/types.d.ts new file mode 100644 index 000000000..31cf09253 --- /dev/null +++ b/src/module/item/types.d.ts @@ -0,0 +1,683 @@ +/** + * @public + */ +export declare type DFDelveCardType = 'Theme' | 'Domain' + +/** +* Describes an attribute key/value pair, set by an oracle row. The key-value pair should be set on any game object for which that row is generated. +* +* Attributes exist to describe prerequisites that might be fulfilled by more than one table, that don't exist on tables at all, or that a generated game object might want to 'force' as one of it's roll results. +* +* See documentation for a list of available values. +* @public +* @see {@link AttributeKey}, {@link Atmosphere}, {@link Authority}, {@link Behavior}, {@link CreatureScale}, {@link DerelictType}, {@link Disposition}, {@link Dominion}, {@link Environment}, {@link FactionType}, {@link FringeGroup}, {@link Guild}, {@link Influence}, {@link Leadership}, {@link Life}, {@link Location}, {@link LocationTheme}, {@link PlanetaryClass}, {@link Population}, {@link Region}, {@link Role}, {@link SettlementInitialContact}, {@link StarshipInitialContact}, {@link Zone} + +*/ + +/** + * Interface for items with rendering information. + * @public + */ +export declare interface DFIHasDisplay { + /** + * Data relevant to this item's display/rendering. + */ + Display: DFIDisplay +} + +/** + * Interface for items that have associated game objects. + * @public + */ +export declare interface DFIHasGameObjects { + /** + * Any game objects that are explicitly pointed to by the original text. For most implementations, it is *not* recommended to generate them automatically - see "Peeling the Onion", p. 293. + */ + 'Game objects': DFIGameObject[] +} + +/** + * Interface for items with a Name key. + * @public + */ +export declare interface DFDFIHasName { + /** + * The item's internal name. Should be unique among its sibling elements, as this key is often used (along with the object's ancestors) to generate its $id. + * + * If the item has Display.Title, that should be preferred for most user-facing labels. + */ + Name: string +} + +/** + * @public + */ +export declare interface DFIHasOptional { + /** + * Whether or not the source material presents this rules item as optional. + * @default false + */ + Optional: boolean +} + +/** + * Interface for items with metadata that describes an oracle's semantic or lexical content. + * @public + */ +export declare interface DFIHasOracleContent { + /** + * Metadata that describes an oracle's semantic or lexical content. + */ + Content: DFIOracleContent +} + +/** + * Interface for items that include roll string templates. + * @public + */ +export declare interface DFIHasRollTemplate { + /** + * Describes the string values of this item that should be replaced with template strings and filled with the results of one or more oracle rolls. + */ + 'Roll template': DFIRollTemplate +} + +/** + * Interface for items with sourcing information. + * @public + */ +export declare interface DFIHasSource { + /** + * Information on this item's source. + */ + Source: DFISource +} + +/** + * Interface for items that include "non-canonical" suggestions of related items. + * @public + */ +export declare interface DFIHasSuggestions { + /** + * "Non-canonical" suggestions of related items. They might be convenient to present to the user, but in most implementations rolling them automatically is not recommended. + */ + Suggestions: DFISuggestions +} + +/** + * Interface for items that reproduce Starforged rules text in markdown. + * @public + */ +export declare interface DFIHasText { + /** + * The item's rules text as a markdown string. + * @markdown + */ + Text: string +} + +/** + * Interface representing a Starforged move. + * @public + */ +export declare interface DFIMove + extends DFIHasId, + DFIHasName, + DFIHasText, + DFIHasDisplay, + DFIHasSource, + DFIHasOptional, + Partial { + /** + * @example "Starforged/Moves/Adventure/Face_Danger" + * @pattern ^(Starforged|Ironsworn)/Moves/([A-z_-]+|Assets/[A-z_-]+/[A-z_-]+/Abilities/[1-3])/[A-z_-]+$ + */ + $id: string + /** + * @example "Face Danger" + */ + Name: string + /** + * The ID of the parent Asset of the move, if any. + */ + Asset?: DFIAsset['$id'] | undefined + /** + * The ID of the move's category. + * @example "Starforged/Moves/Adventure" + */ + Category: DFIMoveCategory['$id'] + /** + * Whether or not the move is a Progress Move. Progress moves roll two challenge dice against a progress score. + */ + 'Progress Move'?: boolean | undefined + /** + * The ID of the move that this move is a variant of, if any. + */ + 'Variant of'?: DFIMove['$id'] | undefined + /** + * The move's trigger data. + */ + Trigger: DFIMoveTrigger + /** + * The IDs of any oracles directly referenced by the move, or vice versa. + */ + Oracles?: DFIOracle['$id'][] | undefined + /** + * Outcome information for the move. + */ + Outcomes?: DFIMoveOutcomes | undefined + Display: DFIDisplayWithTitle + Tags?: string[] | undefined +} + +/** + * Describes the trigger conditions of the move. + * @public + */ +export declare interface DFIMoveTrigger extends DFIHasId, Partial { + /** + * @pattern ^(Starforged|Ironsworn)/(Moves/[A-z_-]+/[A-z_-]+|Assets/[A-z_-]+/[A-z_-]+/Abilities/[1-3]/Alter_Moves/[0-9]+|Moves/Assets/[A-z_-]+/[A-z_-]+/Abilities/[1-3]/[A-z_-]+)/Trigger$ + */ + $id: string + /** + * A markdown string containing the primary trigger text for this move. + * + * Secondary triggers (for specific stats or uses of an asset ability) are described in `Options`. + * + * @markdown + * @example "When you attempt something risky or react to an imminent threat..." + */ + Text?: string | undefined + /** + * Information on who can trigger this item. Used mainly by asset abilities, some of which can trigger from an Ally's move. + * + * If unspecified, assume `Ally` is `false` and `Player` is `true`. + */ + By?: DFIMoveTriggerBy | undefined + /** + * Information on any action rolls or progress rolls that are made when this move is triggered (which may describe a specific subset of the primary trigger in their own `Text` property). + * + * If there's no action rolls or progress rolls attached to this move, this is `undefined`. + */ + Options?: + | (DFIMoveTriggerOptionAction | DFIMoveTriggerOptionProgress)[] + | undefined +} + +/** + * @public + */ +export declare interface DFIMoveTriggerOptionAction + extends DFIMoveTriggerOptionBase { + 'Roll type': DFRollType.Action + Using: DFRollableStat[] +} + +/** + * @public + */ +export declare interface DFIMoveTriggerOptionBase + extends DFIHasId, + Partial { + /** + * @pattern ^(Starforged|Ironsworn)/(Moves/[A-z_-]+/[A-z_-]+|Assets/[A-z_-]+/[A-z_-]+/Abilities/[1-3]/Alter_Moves/[0-9]+|Moves/Assets/[A-z_-]+/[A-z_-]+/Abilities/[1-3]/[A-z_-]+)/Trigger/Options/[0-9]+$ + */ + $id: string + /** + * Whether this option is an action roll or progress roll. + */ + 'Roll type': DFRollType + /** + * The method used to choose the stat or track in the `Using` array. + */ + Method: RollMethod + /** + * The stat(s) or progress track(s) that may be rolled with this move trigger option. + */ + Using: (DFRollableStat | DFProgressTypeStarforged | DFProgressTypeIronsworn)[] + /** + * Defines a custom stat, if one is included in this object's `With` array. + */ + 'Custom stat'?: ICustomStat | undefined +} + +/** + * @public + */ +export declare interface DFIMoveTriggerOptionProgress + extends DFIMoveTriggerOptionBase { + 'Roll type': DFRollType.Progress + Using: (DFProgressTypeStarforged | DFProgressTypeIronsworn)[] +} + +/** + * Represents an oracle, which may have a Table or multiple child Oracles. + * + * If you're looking for a way to crawl the oracle hierarchy in search of a specific ID, see {@link DFIOracleBase}. + * + * @public + */ +export declare interface DFIOracle extends DFIOracleBase { + /** + * @pattern ^(Ironsworn|Starforged)/Oracles/[A-z_-]+((/[A-z_-]+)+)?$ + */ + $id: string + Display: DFIDisplayOracle + Category: DFIOracleCategory['$id'] + 'Member of'?: DFIOracle['$id'] | undefined + Table?: DFIRow[] | undefined + + /** + * Describes the match behaviour of this oracle's table, if any, and provides a `Text` string describing it. Only appears on a handful of move oracles like Ask the Oracle and Advance a Threat. + */ + 'On a Match'?: DFIOracleMatch | undefined +} + +/** + * Interface with elements common to various Oracle-related interfaces and classes. + * + * If you're trying to crawl the tree for a specific ID, I'd recommend using some flavour of JSONpath (I like `jsonpath-plus`) - it's purpose-made for this sort of nested data structure. + * + * But if for some reason you can't, you can use this interface to type both {@link DFIOracle} and {@link DFIOracleCategory} as you recurse the oracle hierarchy. Objects with `Categories` and `Oracles` are "branches", and objects with `Table` are "leaves". + * @public + */ +export declare interface DFIOracleBase + extends Partial, + DFIHasId, + DFIHasDisplay, + DFIHasSource, + DFIHasName { + /** + * The ID of the most recent OracleCategory ancestor of this item, if any. + * @pattern ^(Ironsworn|Starforged)/Oracles/[A-z_-/]+$ + */ + Category?: DFIOracleCategory['$id'] | undefined + /** + * The ID of the most recent Oracle ancestor of this item, if any. + * @pattern ^(Ironsworn|Starforged)/Oracles/[A-z_-]+/[A-z_-]+$ + */ + 'Member of'?: DFIOracle['$id'] | undefined + Display: DFIDisplayWithTitle + /** + * Information on the usage of this oracle: recommended number of rolls, etc. + */ + Usage?: DFIOracleUsage | undefined + /** + * Represents a single oracle table, where 'table' is defined as being something with a single roll range. + * + * This key appears only on 'leaf' nodes of the oracle hierarchy 'tree' - in other words, many (but not all) {@link DFIOracle} objects. + */ + Table?: DFIRow[] | undefined + /** + * Oracle objects contained by this object. + * + * This key appears only on 'branch' nodes of the oracle hierarchy 'tree': {@link DFIOracleCategory}, and {@link DFIOracle} (when it contains multiple closely-related tables). + */ + Oracles?: DFIOracle[] | undefined + /** + * Subcategories contained by this oracle category. + * + * This key appears only on {@link DFIOracleCategory}, and thus only on 'branch' nodes of the oracle hierarchy 'tree. + */ + Categories?: DFIOracleCategory[] | undefined + /** + * Describes the match behaviour of this oracle's table, if any, and provides a `Text` string describing it. Only appears on a handful of move oracles like Ask the Oracle and Advance a Threat. + * + * This key appears only on {@link DFIOracle}s that have a `Table`. + */ + 'On a Match'?: DFIOracleMatch | undefined +} + +/** + * @public + */ +export declare interface DFIOutcomeInfo extends DFIHasId, DFIHasText { + /** + * @pattern ^(Starforged|Ironsworn)/(Moves/[A-z_-]+/[A-z_-]+|Assets/[A-z_-]+/[A-z_-]+/Abilities/[1-3]/Alter_Moves/[0-9]+|Moves/Assets/[A-z_-]+/[A-z_-]+/Abilities/[1-3]/[A-z_-]+)/Outcomes/((Miss|Strong_Hit)(/With_a_Match)?|Weak_Hit)$ + */ + $id: string + /** + * Defines a different outcome for this result with a match. Its text should replace the text of this object. + */ + 'With a Match'?: DFIOutcomeInfo | undefined + /** + * Count this roll as another roll outcome, e.g. "Count a weak hit as a miss" + */ + 'Count as'?: keyof typeof DFMoveOutcome | undefined + /** + * Information on rerolls offered by this move. + */ + Reroll?: DFIMoveReroll | undefined + /** + * Whether this outcome leaves the player character in control or not. If unspecified, assume that it's `true` on a Strong Hit, and `false` on a Weak Hit or Miss. + */ + 'In Control'?: boolean | undefined +} + +/** + * Interface representing a single row in an oracle table. + * @public + */ +export declare interface DFIRow + extends Partial< + DFNullable & + DFIHasRollTemplate & + DFIHasSuggestions & + DFIHasOracleContent & + DFIHasGameObjects & + DFIHasDisplay + > { + /** + * The ID of this row. + * @pattern ^(Ironsworn|Starforged)/Oracles(/[A-z_-]+)+/[1-9][0-9]*(-[1-9][0-9]*)?(/Subtable/[1-9][0-9]*(-[1-9][0-9]*)?)?$ + * @nullable + */ + $id?: string | null + /** + * The low end of the dice range for this row. + * @minimum 1 + * @maximum 100 + * @nullable + */ + Floor: number | null + /** + * The high end of the dice range for this row. + * @minimum 1 + * @maximum 100 + * @nullable + */ + Ceiling: number | null + /** + * The primary result text for the row, annotated in Markdown. + * In the book, this is frequently the only column aside from the roll column. Otherwise, it is the first column. + * Some tables label this column as something other than Result; see the parent (or grandparent) Oracle.Display for more information. + */ + Result: string + /** + * A secondary markdown string that must be presented to the user for the implementation to be complete, but may benefit from progressive disclosure (such as a collapsible element, popover/tooltip, etc). + * + * Generally, `Summary` is longer than `Result`. + * + * Some tables label this column as something other than `Result`; see the parent (or grandparent) `DFIOracle.Display.Table` for more information. + * + * `null` is used in cases where an 'empty' `Summary` exists (example: Starship Type, p. 326). In the book, these table cells are rendered with the text `--` (and this is the recommended placeholder for tabular display). For display as a single result (e.g. VTT table roll output), however, `null` values can be safely omitted. + * @nullable + */ + Summary?: string | null | undefined + /** + * Additional oracle tables that should be rolled when this row is selected. + */ + 'Oracle rolls'?: DFIOracle['$id'][] | undefined + /** + * A table to be rolled when this row is selected. If this row references an external oracle, the `Oracles` property is used instead. + */ + Subtable?: DFIRow[] | undefined + /** + * Data for rows that call for multiple rolls, e.g. on `Roll twice` results. + */ + 'Multiple rolls'?: DFIMultipleRolls | undefined + /** + * The attributes set by this row. + */ + Attributes?: IAttribute[] | undefined +} + +/** + * Interface for 'canonical' options within a SettingTruth category. + * @see {@link DFISettingTruth} + * @public + */ +export declare interface DFISettingTruthOption + extends DFIRow, + DFIHasQuestStarter, + DFIHasDescription { + /** + * @pattern ^(Starforged|Ironsworn)/Setting_Truths/[A-z_-]+/(1-33|34-67|68-100|[1-3])$ + */ + $id: string + 'Roll template'?: DFIRollTemplate | undefined + Subtable?: DFIRow[] | undefined +} + +/** + * Interface representing data on this item's source. For 'canonical' content, this is usually a book with numbered pages, but it might also be a link to a web site. + * @public + */ +export declare interface DFISource { + /** + * The title of the source. + * + * For 'canonical' content, use one of the enumerated `DFSourceTitle` strings. + * + * For 3rd-party content (including homebrew) that's been released as part of a titled document, use the title of that document (e.g. "Steelforged", "Ironsmith"). + * + * If the source has no particular title (for instance, it's a single custom element in a VTT implementation), use "Custom". + */ + Title: DFSourceTitle | string + /** + * The author(s) of this item. For 'canonical' content, this one's usually pretty obvious 😉 However, it's included so that homebrew content can use the same interface/schema. + * @default ["Shawn Tomkin"] + */ + Authors: string[] + /** + * The 6-number date string formatted as `MMDDYY`. Relevant only during Starforged development; it will be deprecated once the game is released. + * @pattern ^(0[1-9]|1[0-2])([0-2][1-9]|3[0-1])([0-9][0-9])$ + */ + Date?: string | undefined + /** + * The page on which the item appears most prominently in the source material (if it's in a format that uses page numbers). + */ + Page?: number | undefined + /** + * The URL where the source material is available. + * @pattern ^https?://.*$ + */ + Url?: string | undefined +} + +/** + * @public + */ +export declare type DFKeysMatching = { + [K in keyof T]-?: T[K] extends V ? K : never +}[keyof T] + +/** + * @public + */ +export declare type DFKeysWithValuesOfType = keyof { + [P in keyof Required as Required[P] extends V ? P : never]: P +} + +/** + * @public + */ +export declare type DFNullable = { + [P in keyof T]: T[P] | null +} + +/** + * @public + */ +export declare type DFNullableKey = { + [P in keyof T]: P extends K ? T[P] | null : T[P] +} + +/** + * @public + */ +export declare type DFOmitNever = { + [K in keyof T as T[K] extends never ? never : K]: T[K] +} + +/** + * @public + */ +export declare type DFOptionalKeys = { + [K in keyof T]-?: Record extends Pick ? K : never +}[keyof T] + +/** + * Makes a type where K is nullable. + * @public + */ +export declare type DFPartialBy = Omit & + Partial> + +/** + * Only recurses a couple times so it doesn't cause an infinite loop during schema generation. + * @public + */ +export declare type DFPartialDeep = Partial<{ + [P in keyof T]: T[P] extends Array ? T[P] | undefined : Partial +}> + +/** + * Makes a type where K and its properties are nullable. + * @public + */ +export declare type DFPartialDeepBy = Omit & + DFPartialDeep> + +/** + * Make all properties of T nullable except for K, which is required. + * @public + */ +export declare type DFPartialExcept = RequireKey< + { + [P in keyof T]?: T[P] + }, + K +> + +/** + * @public + */ +export declare enum DFProgressTypeIronsworn { + Combat = 'Combat', + Vow = 'Vow', + Journey = 'Journey', + Delve = 'Delve', + SceneChallenge = 'Scene Challenge', + Bonds = 'Bonds' +} + +/** + * @public + */ +export declare enum DFProgressTypeStarforged { + Combat = 'Combat', + Vow = 'Vow', + Expedition = 'Expedition', + Connection = 'Connection', + SceneChallenge = 'Scene Challenge', + Quests = 'Quests Legacy', + Bonds = 'Bonds Legacy', + Discoveries = 'Discoveries Legacy' +} + +/** + * @public + */ +export declare type DFRequiredKeys = { + [K in keyof T]-?: Record extends Pick ? never : K +}[keyof T] + +/** + * Generic type: require specific keys to be NonNullable. + * @public + */ +export declare type DFRequireKey = T & { + [P in K]-?: NonNullable +} + +/** + * Standard player character stats or condition meters that can be used as +stat in an action roll. + * @public + */ +export declare type DFRollableStat = + | Stat + | ICustomStat['$id'] + | PlayerConditionMeter + | IConditionMeter['$id'] + +/** + * The stat(s) or progress track(s) that may be rolled with the parent move trigger option. + * @public + */ +export declare enum DFRollMethod { + /** + * When rolling with this move trigger option, *every* stat or progress track of the `Using` key is rolled. + */ + All = 'All', + /** + * When rolling with this move trigger option, use the highest/best option from the `Using` key. + */ + Highest = 'Highest', + /** + * When rolling with this move trigger option, use the lowest/worst option from the `Using` key. + */ + Lowest = 'Lowest', + /** + * When rolling with this move trigger option, the user picks which stat to use. + * + * This is the default option for triggers that offer a single stat. + */ + Any = 'Any', + /** + * This move trigger option has no roll method of its own, and must inherit its roll from another move trigger option. + * + * If the parent's `Using` is defined, the inherited roll must use one of those stats/progress tracks. + * + * Typically appears on children of `IAlterMove`. + */ + Inherit = 'Inherit', + /** + * The move trigger option results in an automatic strong hit - no roll required. + */ + StrongHit = 'Strong Hit', + /** + * The move trigger option results in an automatic weak hit - no roll required. + */ + WeakHit = 'Weak Hit' +} + +/** + * @public + */ +export declare enum DFRollType { + Action = 'Action roll', + Progress = 'Progress roll' +} + +/** + * Make a stub of T where PartialKey is nullable, OmitK is omitted, and all other keys are required. + * + * @public + */ +export declare type DFStubBy< + T, + PartialKey extends keyof any = '', + OmitKey extends keyof any = '' +> = Omit, OmitKey> + +/** + * Make a stub of T where ReqK is required, OmitK is omitted, and all other keys are optional. + * @public + */ +export declare type DFStubExcept< + T, + ReqKey extends keyof any = '', + OmitKey extends keyof any = '' +> = Omit, OmitKey> + +/** + * Represents a tuple: a typed array with a fixed length. + * @public + */ +export declare type DFTuple = [ + TItem, + ...TItem[] +] & { + length: TLength +} diff --git a/src/module/journal/journal-entry-page-types.ts b/src/module/journal/journal-entry-page-types.ts index 7699cc9bf..8dd705d0b 100644 --- a/src/module/journal/journal-entry-page-types.ts +++ b/src/module/journal/journal-entry-page-types.ts @@ -1,5 +1,5 @@ -import type { ISettingTruthOption } from 'dataforged' import type { ChallengeRank } from '../fields/ChallengeRank' +import type { DFISettingTruthOption } from '../item/types' import type { IronswornJournalPage } from './journal-entry-page' interface CounterBase { @@ -66,7 +66,7 @@ export interface ClockDataProperties { } /// ///////// SETTING TRUTH OPTION -export interface TruthOptionDataSourceData extends ISettingTruthOption { +export interface TruthOptionDataSourceData extends DFISettingTruthOption { dfid: string Summary: string Quest: string diff --git a/src/module/journal/journal-entry-page.ts b/src/module/journal/journal-entry-page.ts index 6506e4db2..a1f592919 100644 --- a/src/module/journal/journal-entry-page.ts +++ b/src/module/journal/journal-entry-page.ts @@ -1,11 +1,10 @@ import type { DocumentModificationOptions } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/abstract/document.mjs' -import type { RollTableDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/rollTableData' import type { TableResultDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/tableResultData' import type { BaseUser } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/documents.mjs' -import type { IRow } from 'dataforged' import { clamp } from 'lodash-es' import { RANK_INCREMENTS } from '../constants' import { typedDeleteDialog } from '../helpers/util' +import { DFIRow } from '../item/types' import { OracleTable } from '../roll-table/oracle-table' import { OracleTableResult } from '../roll-table/oracle-table-result' import type { @@ -70,7 +69,7 @@ export class IronswornJournalPage< formula: '1d100', results: pageSystem.Subtable.map((row) => OracleTableResult.getConstructorData( - row as IRow & { Floor: number; Ceiling: number } + row as DFIRow & { Floor: number; Ceiling: number } ) ), flags: { diff --git a/src/module/roll-table/oracle-table-result.ts b/src/module/roll-table/oracle-table-result.ts index a3133405f..55c40b1d4 100644 --- a/src/module/roll-table/oracle-table-result.ts +++ b/src/module/roll-table/oracle-table-result.ts @@ -1,7 +1,7 @@ import type { TableResultDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/tableResultData' -import type { IRow } from 'dataforged' +import type { DFIRow } from '../item/types' import { inRange } from 'lodash-es' -import { hashLookup, renderLinksInStr } from '../dataforged' +import { hashLookup } from '../helpers/util' /** Extends FVTT's default TableResult with functionality specific to this system. */ export class OracleTableResult extends TableResult { @@ -46,7 +46,7 @@ export class OracleTableResult extends TableResult { /** Converts a Dataforged IRow object into OracleTableResult constructor data. */ static getConstructorData( - tableRow: IRow & { Floor: number; Ceiling: number; dfid?: string } + tableRow: DFIRow & { Floor: number; Ceiling: number; dfid?: string } ): TableResultDataConstructorData { let text: string if (tableRow.Result && tableRow.Summary) { @@ -55,7 +55,7 @@ export class OracleTableResult extends TableResult { const data: TableResultDataConstructorData = { range: [tableRow.Floor, tableRow.Ceiling], - text: tableRow.Result && renderLinksInStr(text) + text: tableRow.Result } const _id = diff --git a/src/module/roll-table/oracle-table.ts b/src/module/roll-table/oracle-table.ts index 1c69b812f..20410c9ef 100644 --- a/src/module/roll-table/oracle-table.ts +++ b/src/module/roll-table/oracle-table.ts @@ -1,9 +1,7 @@ import type { RollTableDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/rollTableData' import type { ConfiguredFlags } from '@league-of-foundry-developers/foundry-vtt-types/src/types/helperTypes' -import type { IOracle, IRow } from 'dataforged' import { max } from 'lodash-es' import type { IronswornActor } from '../actor/actor' -import { hashLookup, renderLinksInStr } from '../dataforged' import { getPackAndIndexForCompendiumKey, IdParser } from '../datasworn2' import { findPathToNodeByTableUuid, @@ -11,6 +9,8 @@ import { IOracleTreeNode } from '../features/customoracles' import { DataswornRulesetKey } from '../helpers/settings' +import { hashLookup } from '../helpers/util' +import { DFIOracle, DFIRow } from '../item/types' import type { IronswornJournalEntry } from '../journal/journal-entry' import type { IronswornJournalPage } from '../journal/journal-entry-page' @@ -161,7 +161,7 @@ export class OracleTable extends RollTable { oracle: OracleTable.IOracleLeaf ): RollTableDataConstructorData { const description = CONFIG.IRONSWORN.showdown.makeHtml( - renderLinksInStr(oracle.Description ?? '') + oracle.Description ?? '' ) const maxRoll = max(oracle.Table.map((x) => x.Ceiling ?? 0)) // oracle.Table && maxBy(oracle.Table, (x) => x.Ceiling)?.Ceiling const data: RollTableDataConstructorData = { @@ -177,7 +177,7 @@ export class OracleTable extends RollTable { /* folder: // would require using an additional module */ results: oracle.Table?.filter((x) => x.Floor !== null).map((tableRow) => OracleTableResult.getConstructorData( - tableRow as IRow & { Floor: number; Ceiling: number } + tableRow as DFIRow & { Floor: number; Ceiling: number } ) ) } @@ -428,5 +428,5 @@ export class OracleTable extends RollTable { } export namespace OracleTable { - export type IOracleLeaf = IOracle & { Table: IRow[] } + export type IOracleLeaf = DFIOracle & { Name: string; Table: DFIRow[] } } diff --git a/src/module/rolls/ironsworn-roll-message.ts b/src/module/rolls/ironsworn-roll-message.ts index 2b3b262b6..ed320e322 100644 --- a/src/module/rolls/ironsworn-roll-message.ts +++ b/src/module/rolls/ironsworn-roll-message.ts @@ -1,8 +1,7 @@ -import type { IOutcomeInfo, RollMethod } from 'dataforged' +import type { DFIOutcomeInfo, DFRollMethod } from '../item/types' import { compact, fromPairs, isUndefined, kebabCase } from 'lodash-es' import { IronswornRoll } from '.' import { IronswornActor } from '../actor/actor' -import { IronswornItem } from '../item/item' import { OracleTable } from '../roll-table/oracle-table' import { enrichMarkdown } from '../vue/vue-plugin' import { DfRollOutcome, RollOutcome } from './ironsworn-roll' @@ -40,7 +39,7 @@ export function formatRollPlusStat(stat: string, initialCaps = false) { * @example formatRollMethod("Highest", ["Spirit", "Heart", "Wits"]) * // returns "roll highest of spirit, heart, wits" for en.json */ -export function formatRollMethod(rollMethod: RollMethod, stats: string[]) { +export function formatRollMethod(rollMethod: DFRollMethod, stats: string[]) { // skip if there's no choice to be made if (stats.length === 1) { return formatRollPlusStat(stats[0]) @@ -258,7 +257,7 @@ export class IronswornRollMessage { const key = DfRollOutcome[theOutcome] const moveSystem = move.system - let moveOutcome = moveSystem.Outcomes?.[key] as IOutcomeInfo | undefined + let moveOutcome = moveSystem.Outcomes?.[key] as DFIOutcomeInfo | undefined if (this.roll.isMatch && moveOutcome?.['With a Match']?.Text) moveOutcome = moveOutcome['With a Match'] if (moveOutcome) { diff --git a/src/module/rolls/preroll-dialog.ts b/src/module/rolls/preroll-dialog.ts index c032f1bee..2fac7bb38 100644 --- a/src/module/rolls/preroll-dialog.ts +++ b/src/module/rolls/preroll-dialog.ts @@ -1,4 +1,8 @@ -import type { ProgressTypeIronsworn, RollMethod, RollType } from 'dataforged' +import type { + DFProgressTypeIronsworn, + DFRollMethod, + DFRollType +} from '../item/types' import { cloneDeep, maxBy, minBy, sortBy } from 'lodash-es' import { IronswornActor } from '../actor/actor' import { IronswornItem } from '../item/item' @@ -106,7 +110,7 @@ export function getStatData( } function chooseStatToRoll( - mode: RollMethod, + mode: DFRollMethod, stats: string[], actor: IronswornActor<'character'> | IronswornActor<'starship'> ): SourcedValue | undefined { @@ -365,9 +369,9 @@ export class IronswornPrerollDialog extends Dialog< // Add this so it generates a button, but it won't be passed to // the IronswornRoll object as a stat options.push({ - 'Roll type': 'Progress roll' as RollType, - Method: 'Any' as RollMethod, - Using: ['Progress' as ProgressTypeIronsworn] + 'Roll type': 'Progress roll' as DFRollType, + Method: 'Any' as DFRollMethod, + Using: ['Progress' as DFProgressTypeIronsworn] }) } @@ -394,7 +398,7 @@ export class IronswornPrerollDialog extends Dialog< action: true }) const buttons = {} - const addButton = (i: number, mode: RollMethod, stats: string[]) => { + const addButton = (i: number, mode: DFRollMethod, stats: string[]) => { const localizedStats = stats.map((s) => game.i18n.localize(`IRONSWORN.${s.capitalize()}`) ) diff --git a/src/module/vue/components/foe-browser/foe-browser-row.vue b/src/module/vue/components/foe-browser/foe-browser-row.vue index e005c75d6..d5d68aa7f 100644 --- a/src/module/vue/components/foe-browser/foe-browser-row.vue +++ b/src/module/vue/components/foe-browser/foe-browser-row.vue @@ -53,7 +53,7 @@ diff --git a/src/module/vue/components/rules-text/rules-text-move.vue b/src/module/vue/components/rules-text/rules-text-move.vue index 28480c87e..2272cd8cb 100644 --- a/src/module/vue/components/rules-text/rules-text-move.vue +++ b/src/module/vue/components/rules-text/rules-text-move.vue @@ -1,7 +1,7 @@