From 8f206baf46e580d908949099d2519b77e2856054 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Thu, 9 Oct 2025 02:03:18 -0600 Subject: [PATCH 01/29] Add initial pack definitions --- .gitignore | 7 ++++ package.json | 2 + scripts/buildCompendia.mjs | 36 ++++++++++++++++++ scripts/extractCompendia.mjs | 31 ++++++++++++++++ system.json | 71 +++++++++++++++++++++++++++++++++++- 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 scripts/buildCompendia.mjs create mode 100644 scripts/extractCompendia.mjs diff --git a/.gitignore b/.gitignore index 6ef05ba..e058206 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,10 @@ jspm_packages/ .env.test.local .env.production.local .env.local + +# Ignore all of the binaries and stuff that gets built for Foundry from the raw +# JSON data because it's annoying seeing it in my git changes when it isn't actually +# needed. +/packs/**/* +!/packs/**/*/ +!/packs/**/*.json diff --git a/package.json b/package.json index 1c663e7..5fa77f1 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "eslint": "^9.16.0" }, "scripts": { + "data:build": "node scripts/buildCompendia.mjs", + "data:extract": "node scripts/extractCompendia.mjs", "link": "node scripts/linkFoundry.mjs", "lint": "eslint --fix", "lint:nofix": "eslint" diff --git a/scripts/buildCompendia.mjs b/scripts/buildCompendia.mjs new file mode 100644 index 0000000..88ab4e4 --- /dev/null +++ b/scripts/buildCompendia.mjs @@ -0,0 +1,36 @@ +import { existsSync } from "fs"; +import { readFile } from "fs/promises"; +import { join } from "path"; +import { compilePack } from "@foundryvtt/foundryvtt-cli"; +import { pathToFileURL } from "url"; + +export async function buildCompendia() { + const manifest = JSON.parse(await readFile(`./system.json`, `utf-8`)); + + if (!manifest.packs || manifest.packs.length === 0) { + console.log(`No compendium packs defined`); + process.exit(0); + }; + console.log(`Packing compendia`); + + for (const compendium of manifest.packs) { + console.debug(`Packing ${compendium.label} (${compendium.name})`); + let src = join(process.cwd(), compendium.path, `_source`); + if (!existsSync(src)) { + console.warn(`${compendium.path} doesn't exist, skipping.`) + continue; + }; + await compilePack( + src, + join(process.cwd(), compendium.path), + { recursive: true }, + ); + console.debug(`Finished packing compendium: ${compendium.name}`); + }; + + console.log(`Finished packing all compendia`) +}; + +if (import.meta.url === pathToFileURL(process.argv[1]).href) { + buildCompendia(); +}; diff --git a/scripts/extractCompendia.mjs b/scripts/extractCompendia.mjs new file mode 100644 index 0000000..0730b38 --- /dev/null +++ b/scripts/extractCompendia.mjs @@ -0,0 +1,31 @@ +import { readFile } from "fs/promises"; +import { join } from "path"; +import { extractPack } from "@foundryvtt/foundryvtt-cli"; +import { pathToFileURL } from "url"; + +export async function extractCompendia() { + const manifest = JSON.parse(await readFile(`./system.json`, `utf-8`)); + + if (!manifest.packs || manifest.packs.length === 0) { + console.log(`No compendium packs defined`); + process.exit(0); + }; + console.log(`Extracting compendia`); + + for (const compendium of manifest.packs) { + console.debug(`Unpacking ${compendium.label} (${compendium.name})`); + let src = join(process.cwd(), compendium.path, `_source`); + await extractPack( + join(process.cwd(), compendium.path), + src, + { recursive: true }, + ); + console.debug(`Finished unpacking compendium: ${compendium.name}`); + }; + + console.log(`Finished unpacking all compendia`); +}; + +if (import.meta.url === pathToFileURL(process.argv[1]).href) { + extractCompendia(); +}; diff --git a/system.json b/system.json index 5190f37..d4b61ed 100644 --- a/system.json +++ b/system.json @@ -53,5 +53,74 @@ "skill": {}, "weapon": {} } - } + }, + "packs": [ + { + "name": "protection", + "label": "Armour & Shields", + "system": "ripcrypt", + "path": "packs/protection", + "type": "Item", + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "weapons", + "label": "Weapons & Ammo", + "system": "ripcrypt", + "path": "packs/weapons", + "type": "Item", + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "skills", + "label": "Skills", + "system": "ripcrypt", + "path": "packs/skills", + "type": "Item", + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } + }, + { + "name": "geist", + "label": "Geist", + "system": "ripcrypt", + "path": "packs/geist", + "type": "Actor", + "ownership": { + "PLAYER": "NONE", + "ASSISTANT": "OWNER" + } + } + ], + "packFolders": [ + { + "name": "RipCrypt Sprint Start", + "color": "#04262a", + "sorting": "m", + "folders": [ + { + "name": "Character Options", + "color": "#06393f", + "sorting": "m", + "folders": [], + "packs": [ + "protection", + "weapons", + "skills" + ] + } + ], + "packs": [ + "geist" + ] + } + ] } From be04ab9a264a4d32ea37914eeb51505f7123d776 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Thu, 9 Oct 2025 02:04:38 -0600 Subject: [PATCH 02/29] Add data for the compendia from the SprintStart zine --- .../_source/Armour_pZxc6QLgVWfnZlf7.json | 23 +++++++++ .../_source/Breastplate_KQ6uyTPUOHuMTxDF.json | 41 +++++++++++++++ .../_source/Heavy_BsNUpCnwmlhOWBhZ.json | 21 ++++++++ .../Heavy_Shields_uUrCwjxV6Ihisb6V.json | 44 ++++++++++++++++ .../_source/Leather_Cap_JMkV8kMnCXhW5KDh.json | 41 +++++++++++++++ ...eather__Hide_Bracers_nz4DXXR4iU9CeMRA.json | 41 +++++++++++++++ ...Leather__Hide_Jacket_zMyxSJ6VpaH3ddOO.json | 41 +++++++++++++++ ...ather__Hide_Leggings_14Omu9q2sMxW8GWB.json | 41 +++++++++++++++ .../_source/Light_HRwiz1c1ZcQyPu4z.json | 21 ++++++++ .../Light_Shields_a6vPAa25z8L9t79K.json | 42 ++++++++++++++++ ...il__Link__Scale_Coat_Sr40RFsPr2M0bTKK.json | 42 ++++++++++++++++ ...il__Link__Scale_Coif_HfG5Doxf7576Jgbt.json | 41 +++++++++++++++ ...Link__Scale_Leggings_YBpElIVQ534pm3Mf.json | 41 +++++++++++++++ ...l__Link__Scale_Shirt_wab6Bo8ngar4mBCN.json | 41 +++++++++++++++ .../Modest_Shields_fyL8LZ8jpEQbjpM2.json | 43 ++++++++++++++++ .../_source/Modest_cKN149ZGLqfyt0oi.json | 21 ++++++++ .../Plate_Bracers_e8JRJn5Blw3UrvnW.json | 42 ++++++++++++++++ .../Plate_Leggings_v1y4RKGad2IXOu5e.json | 41 +++++++++++++++ .../Ring_Coif__Helm_Z4NTsrX63JNjjZ8Z.json | 41 +++++++++++++++ .../_source/Shields_RXPJBkzVxFnoT3Tm.json | 23 +++++++++ .../_source/Ammo_gvNPXXRBx2eGIzcU.json | 23 +++++++++ .../Arming_Sword_xXUItaoHTQ2QiaX4.json | 47 +++++++++++++++++ .../_source/Arrow_gN9JbmouUI7eOrSj.json | 35 +++++++++++++ .../Axe__Hammer__Pick_cr35WzuPGDojuOuJ.json | 49 ++++++++++++++++++ ...Battleaxe__Warhammer_otIFI9TIDPWnT3cq.json | 47 +++++++++++++++++ .../Black_Powder_c86ht86Z9vOEBtNH.json | 35 +++++++++++++ .../Blowgun_Darts_FvtiEaQhJumPsCwb.json | 35 +++++++++++++ .../Blowgun__Sling_VrG2xer1quhjwUag.json | 49 ++++++++++++++++++ .../_source/Broadsword_I9QaJTU6O2E9WzUS.json | 47 +++++++++++++++++ .../_source/Club_NlDJVbXeXRfoCZWp.json | 47 +++++++++++++++++ .../_source/Crossbow_BNoYUrlpDk6oBeJt.json | 49 ++++++++++++++++++ .../Crossbow_Bolts_7cmLLV6o2pPAyyAg.json | 35 +++++++++++++ ...ass__Saber__Scimitar_kSWrbdKdYIRxkWka.json | 49 ++++++++++++++++++ .../_source/Dagger_q8z2HptFaPmeHU9n.json | 50 +++++++++++++++++++ .../_source/Darts_rDxS6EJzg2zvSpxR.json | 49 ++++++++++++++++++ .../Flintlock_Pistol_1vxM6KoEPrQ7pjcg.json | 50 +++++++++++++++++++ .../Flintlock_Rifle_xUGUgnjJsKUPgPpX.json | 50 +++++++++++++++++++ .../Great_Arrows_FQ5VBjR0LdXf8Nh2.json | 35 +++++++++++++ ...reataxe__Maul__Sword_Pfm448hGPVSuyyrd.json | 49 ++++++++++++++++++ .../_source/Greatbow_N80F8sq9SaHrXBvS.json | 49 ++++++++++++++++++ .../Greatclub__Staff_Ct9iNF9KPMGStSQo.json | 49 ++++++++++++++++++ .../Hand_Crossbow_5sUeNom6dn6MaoAE.json | 49 ++++++++++++++++++ .../Hand_Weapons_3mr6aZe43z7YBysA.json | 23 +++++++++ .../_source/Heavy_3tp9cwpArQNOpkAY.json | 21 ++++++++ .../Heavy_Crossbow_xJzHTrYsJVL2WsSF.json | 49 ++++++++++++++++++ .../_source/Heavy_IkSGLBUzPI9Jbcj7.json | 21 ++++++++ .../_source/Knife_fv5D0xOJVpOwnyTn.json | 49 ++++++++++++++++++ .../_source/Light_mmd8siMKSLyOeILo.json | 23 +++++++++ .../_source/Light_vPyj2cK1j66Zyrul.json | 21 ++++++++ .../_source/Long_Rifle_dn1eja68NNuxB8K1.json | 50 +++++++++++++++++++ .../_source/Longbow_oyVNU8XgMiZI0Uxr.json | 49 ++++++++++++++++++ .../_source/Longsword_7ezV0MrGA0duoGbl.json | 49 ++++++++++++++++++ .../_source/Modest_8NNF9jBjpmPpmw1B.json | 21 ++++++++ .../_source/Modest_dBAI76CApXH8qqjx.json | 21 ++++++++ ...axe__Glaive__Halberd_j6C9IyebpKsk7M6R.json | 49 ++++++++++++++++++ .../Quarterstaff_0ebCxTylmQa5UJvF.json | 49 ++++++++++++++++++ .../Ranged_Weapons_sjc6X9bKf7BY04Ar.json | 23 +++++++++ .../Rapier__Foil_cgEQKXKnSShCRQaq.json | 50 +++++++++++++++++++ .../_source/Scythe_PnBWkLNzmQjXbB94.json | 49 ++++++++++++++++++ .../_source/Shortbow_qmnDO3TrKoeW7DZB.json | 49 ++++++++++++++++++ .../_source/Shortsword_UulalWrMRtSX5KxZ.json | 47 +++++++++++++++++ .../_source/Shot_Q5i7hMOPgb9oXmh5.json | 35 +++++++++++++ .../_source/Sickle_o9saXoHahbxTxt4h.json | 47 +++++++++++++++++ ...Spear__Javelin__Pike_bTOoWxHeLSY9JWNY.json | 50 +++++++++++++++++++ .../Throwing_Axe_n2j1gxnn3WnUPag6.json | 49 ++++++++++++++++++ ...Warclub__Flail__Mace_WMiQdSVgM8z84MEv.json | 47 +++++++++++++++++ .../_source/Whip_vVF6LZSFi0pNB95E.json | 50 +++++++++++++++++++ 67 files changed, 2700 insertions(+) create mode 100644 packs/protection/_source/Armour_pZxc6QLgVWfnZlf7.json create mode 100644 packs/protection/_source/Breastplate_KQ6uyTPUOHuMTxDF.json create mode 100644 packs/protection/_source/Heavy_BsNUpCnwmlhOWBhZ.json create mode 100644 packs/protection/_source/Heavy_Shields_uUrCwjxV6Ihisb6V.json create mode 100644 packs/protection/_source/Leather_Cap_JMkV8kMnCXhW5KDh.json create mode 100644 packs/protection/_source/Leather__Hide_Bracers_nz4DXXR4iU9CeMRA.json create mode 100644 packs/protection/_source/Leather__Hide_Jacket_zMyxSJ6VpaH3ddOO.json create mode 100644 packs/protection/_source/Leather__Hide_Leggings_14Omu9q2sMxW8GWB.json create mode 100644 packs/protection/_source/Light_HRwiz1c1ZcQyPu4z.json create mode 100644 packs/protection/_source/Light_Shields_a6vPAa25z8L9t79K.json create mode 100644 packs/protection/_source/Mail__Link__Scale_Coat_Sr40RFsPr2M0bTKK.json create mode 100644 packs/protection/_source/Mail__Link__Scale_Coif_HfG5Doxf7576Jgbt.json create mode 100644 packs/protection/_source/Mail__Link__Scale_Leggings_YBpElIVQ534pm3Mf.json create mode 100644 packs/protection/_source/Mail__Link__Scale_Shirt_wab6Bo8ngar4mBCN.json create mode 100644 packs/protection/_source/Modest_Shields_fyL8LZ8jpEQbjpM2.json create mode 100644 packs/protection/_source/Modest_cKN149ZGLqfyt0oi.json create mode 100644 packs/protection/_source/Plate_Bracers_e8JRJn5Blw3UrvnW.json create mode 100644 packs/protection/_source/Plate_Leggings_v1y4RKGad2IXOu5e.json create mode 100644 packs/protection/_source/Ring_Coif__Helm_Z4NTsrX63JNjjZ8Z.json create mode 100644 packs/protection/_source/Shields_RXPJBkzVxFnoT3Tm.json create mode 100644 packs/weapons/_source/Ammo_gvNPXXRBx2eGIzcU.json create mode 100644 packs/weapons/_source/Arming_Sword_xXUItaoHTQ2QiaX4.json create mode 100644 packs/weapons/_source/Arrow_gN9JbmouUI7eOrSj.json create mode 100644 packs/weapons/_source/Axe__Hammer__Pick_cr35WzuPGDojuOuJ.json create mode 100644 packs/weapons/_source/Battleaxe__Warhammer_otIFI9TIDPWnT3cq.json create mode 100644 packs/weapons/_source/Black_Powder_c86ht86Z9vOEBtNH.json create mode 100644 packs/weapons/_source/Blowgun_Darts_FvtiEaQhJumPsCwb.json create mode 100644 packs/weapons/_source/Blowgun__Sling_VrG2xer1quhjwUag.json create mode 100644 packs/weapons/_source/Broadsword_I9QaJTU6O2E9WzUS.json create mode 100644 packs/weapons/_source/Club_NlDJVbXeXRfoCZWp.json create mode 100644 packs/weapons/_source/Crossbow_BNoYUrlpDk6oBeJt.json create mode 100644 packs/weapons/_source/Crossbow_Bolts_7cmLLV6o2pPAyyAg.json create mode 100644 packs/weapons/_source/Cutlass__Saber__Scimitar_kSWrbdKdYIRxkWka.json create mode 100644 packs/weapons/_source/Dagger_q8z2HptFaPmeHU9n.json create mode 100644 packs/weapons/_source/Darts_rDxS6EJzg2zvSpxR.json create mode 100644 packs/weapons/_source/Flintlock_Pistol_1vxM6KoEPrQ7pjcg.json create mode 100644 packs/weapons/_source/Flintlock_Rifle_xUGUgnjJsKUPgPpX.json create mode 100644 packs/weapons/_source/Great_Arrows_FQ5VBjR0LdXf8Nh2.json create mode 100644 packs/weapons/_source/Greataxe__Maul__Sword_Pfm448hGPVSuyyrd.json create mode 100644 packs/weapons/_source/Greatbow_N80F8sq9SaHrXBvS.json create mode 100644 packs/weapons/_source/Greatclub__Staff_Ct9iNF9KPMGStSQo.json create mode 100644 packs/weapons/_source/Hand_Crossbow_5sUeNom6dn6MaoAE.json create mode 100644 packs/weapons/_source/Hand_Weapons_3mr6aZe43z7YBysA.json create mode 100644 packs/weapons/_source/Heavy_3tp9cwpArQNOpkAY.json create mode 100644 packs/weapons/_source/Heavy_Crossbow_xJzHTrYsJVL2WsSF.json create mode 100644 packs/weapons/_source/Heavy_IkSGLBUzPI9Jbcj7.json create mode 100644 packs/weapons/_source/Knife_fv5D0xOJVpOwnyTn.json create mode 100644 packs/weapons/_source/Light_mmd8siMKSLyOeILo.json create mode 100644 packs/weapons/_source/Light_vPyj2cK1j66Zyrul.json create mode 100644 packs/weapons/_source/Long_Rifle_dn1eja68NNuxB8K1.json create mode 100644 packs/weapons/_source/Longbow_oyVNU8XgMiZI0Uxr.json create mode 100644 packs/weapons/_source/Longsword_7ezV0MrGA0duoGbl.json create mode 100644 packs/weapons/_source/Modest_8NNF9jBjpmPpmw1B.json create mode 100644 packs/weapons/_source/Modest_dBAI76CApXH8qqjx.json create mode 100644 packs/weapons/_source/Poleaxe__Glaive__Halberd_j6C9IyebpKsk7M6R.json create mode 100644 packs/weapons/_source/Quarterstaff_0ebCxTylmQa5UJvF.json create mode 100644 packs/weapons/_source/Ranged_Weapons_sjc6X9bKf7BY04Ar.json create mode 100644 packs/weapons/_source/Rapier__Foil_cgEQKXKnSShCRQaq.json create mode 100644 packs/weapons/_source/Scythe_PnBWkLNzmQjXbB94.json create mode 100644 packs/weapons/_source/Shortbow_qmnDO3TrKoeW7DZB.json create mode 100644 packs/weapons/_source/Shortsword_UulalWrMRtSX5KxZ.json create mode 100644 packs/weapons/_source/Shot_Q5i7hMOPgb9oXmh5.json create mode 100644 packs/weapons/_source/Sickle_o9saXoHahbxTxt4h.json create mode 100644 packs/weapons/_source/Spear__Javelin__Pike_bTOoWxHeLSY9JWNY.json create mode 100644 packs/weapons/_source/Throwing_Axe_n2j1gxnn3WnUPag6.json create mode 100644 packs/weapons/_source/Warclub__Flail__Mace_WMiQdSVgM8z84MEv.json create mode 100644 packs/weapons/_source/Whip_vVF6LZSFi0pNB95E.json diff --git a/packs/protection/_source/Armour_pZxc6QLgVWfnZlf7.json b/packs/protection/_source/Armour_pZxc6QLgVWfnZlf7.json new file mode 100644 index 0000000..6f80750 --- /dev/null +++ b/packs/protection/_source/Armour_pZxc6QLgVWfnZlf7.json @@ -0,0 +1,23 @@ +{ + "type": "Item", + "folder": null, + "name": "Armour", + "color": "#04262a", + "sorting": "m", + "_id": "pZxc6QLgVWfnZlf7", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994081362, + "modifiedTime": 1759994081362, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!folders!pZxc6QLgVWfnZlf7" +} diff --git a/packs/protection/_source/Breastplate_KQ6uyTPUOHuMTxDF.json b/packs/protection/_source/Breastplate_KQ6uyTPUOHuMTxDF.json new file mode 100644 index 0000000..75dd4a1 --- /dev/null +++ b/packs/protection/_source/Breastplate_KQ6uyTPUOHuMTxDF.json @@ -0,0 +1,41 @@ +{ + "folder": "BsNUpCnwmlhOWBhZ", + "name": "Breastplate", + "type": "armour", + "_id": "KQ6uyTPUOHuMTxDF", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 90, + "copper": null + }, + "protection": 3, + "location": [ + "body" + ], + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994459142, + "modifiedTime": 1759994468351, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!KQ6uyTPUOHuMTxDF" +} diff --git a/packs/protection/_source/Heavy_BsNUpCnwmlhOWBhZ.json b/packs/protection/_source/Heavy_BsNUpCnwmlhOWBhZ.json new file mode 100644 index 0000000..225a22c --- /dev/null +++ b/packs/protection/_source/Heavy_BsNUpCnwmlhOWBhZ.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "pZxc6QLgVWfnZlf7", + "name": "Heavy", + "color": "#06393f", + "sorting": "a", + "_id": "BsNUpCnwmlhOWBhZ", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!BsNUpCnwmlhOWBhZ" +} diff --git a/packs/protection/_source/Heavy_Shields_uUrCwjxV6Ihisb6V.json b/packs/protection/_source/Heavy_Shields_uUrCwjxV6Ihisb6V.json new file mode 100644 index 0000000..69d4a46 --- /dev/null +++ b/packs/protection/_source/Heavy_Shields_uUrCwjxV6Ihisb6V.json @@ -0,0 +1,44 @@ +{ + "folder": "RXPJBkzVxFnoT3Tm", + "name": "Heavy Shields", + "type": "shield", + "_id": "uUrCwjxV6Ihisb6V", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 50, + "copper": null + }, + "protection": 1, + "location": [ + "head", + "body", + "arms", + "legs" + ], + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994801184, + "modifiedTime": 1759994810086, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!uUrCwjxV6Ihisb6V" +} diff --git a/packs/protection/_source/Leather_Cap_JMkV8kMnCXhW5KDh.json b/packs/protection/_source/Leather_Cap_JMkV8kMnCXhW5KDh.json new file mode 100644 index 0000000..c7db6f2 --- /dev/null +++ b/packs/protection/_source/Leather_Cap_JMkV8kMnCXhW5KDh.json @@ -0,0 +1,41 @@ +{ + "folder": "HRwiz1c1ZcQyPu4z", + "name": "Leather Cap", + "type": "armour", + "_id": "JMkV8kMnCXhW5KDh", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 10, + "copper": null + }, + "protection": 1, + "location": [ + "head" + ], + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994118194, + "modifiedTime": 1759994130845, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!JMkV8kMnCXhW5KDh" +} diff --git a/packs/protection/_source/Leather__Hide_Bracers_nz4DXXR4iU9CeMRA.json b/packs/protection/_source/Leather__Hide_Bracers_nz4DXXR4iU9CeMRA.json new file mode 100644 index 0000000..509e0e7 --- /dev/null +++ b/packs/protection/_source/Leather__Hide_Bracers_nz4DXXR4iU9CeMRA.json @@ -0,0 +1,41 @@ +{ + "folder": "HRwiz1c1ZcQyPu4z", + "name": "Leather, Hide Bracers", + "type": "armour", + "_id": "nz4DXXR4iU9CeMRA", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 10, + "copper": null + }, + "protection": 1, + "location": [ + "arms" + ], + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994170968, + "modifiedTime": 1759994180395, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!nz4DXXR4iU9CeMRA" +} diff --git a/packs/protection/_source/Leather__Hide_Jacket_zMyxSJ6VpaH3ddOO.json b/packs/protection/_source/Leather__Hide_Jacket_zMyxSJ6VpaH3ddOO.json new file mode 100644 index 0000000..f382b54 --- /dev/null +++ b/packs/protection/_source/Leather__Hide_Jacket_zMyxSJ6VpaH3ddOO.json @@ -0,0 +1,41 @@ +{ + "folder": "HRwiz1c1ZcQyPu4z", + "name": "Leather, Hide Jacket", + "type": "armour", + "_id": "zMyxSJ6VpaH3ddOO", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 20, + "copper": null + }, + "protection": 1, + "location": [ + "body" + ], + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994151324, + "modifiedTime": 1759994160761, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!zMyxSJ6VpaH3ddOO" +} diff --git a/packs/protection/_source/Leather__Hide_Leggings_14Omu9q2sMxW8GWB.json b/packs/protection/_source/Leather__Hide_Leggings_14Omu9q2sMxW8GWB.json new file mode 100644 index 0000000..8c9a9c3 --- /dev/null +++ b/packs/protection/_source/Leather__Hide_Leggings_14Omu9q2sMxW8GWB.json @@ -0,0 +1,41 @@ +{ + "folder": "HRwiz1c1ZcQyPu4z", + "name": "Leather, Hide Leggings", + "type": "armour", + "_id": "14Omu9q2sMxW8GWB", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 20, + "copper": null + }, + "protection": 1, + "location": [ + "legs" + ], + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994190989, + "modifiedTime": 1759994198011, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!14Omu9q2sMxW8GWB" +} diff --git a/packs/protection/_source/Light_HRwiz1c1ZcQyPu4z.json b/packs/protection/_source/Light_HRwiz1c1ZcQyPu4z.json new file mode 100644 index 0000000..bb9b437 --- /dev/null +++ b/packs/protection/_source/Light_HRwiz1c1ZcQyPu4z.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "pZxc6QLgVWfnZlf7", + "name": "Light", + "color": "#06393f", + "sorting": "a", + "_id": "HRwiz1c1ZcQyPu4z", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!HRwiz1c1ZcQyPu4z" +} diff --git a/packs/protection/_source/Light_Shields_a6vPAa25z8L9t79K.json b/packs/protection/_source/Light_Shields_a6vPAa25z8L9t79K.json new file mode 100644 index 0000000..e04bc0c --- /dev/null +++ b/packs/protection/_source/Light_Shields_a6vPAa25z8L9t79K.json @@ -0,0 +1,42 @@ +{ + "folder": "RXPJBkzVxFnoT3Tm", + "name": "Light Shields", + "type": "shield", + "_id": "a6vPAa25z8L9t79K", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 20, + "copper": null + }, + "protection": 1, + "location": [ + "head", + "arms" + ], + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994549164, + "modifiedTime": 1759994761998, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!a6vPAa25z8L9t79K" +} diff --git a/packs/protection/_source/Mail__Link__Scale_Coat_Sr40RFsPr2M0bTKK.json b/packs/protection/_source/Mail__Link__Scale_Coat_Sr40RFsPr2M0bTKK.json new file mode 100644 index 0000000..1c008b2 --- /dev/null +++ b/packs/protection/_source/Mail__Link__Scale_Coat_Sr40RFsPr2M0bTKK.json @@ -0,0 +1,42 @@ +{ + "folder": "cKN149ZGLqfyt0oi", + "name": "Mail, Link, Scale Coat", + "type": "armour", + "_id": "Sr40RFsPr2M0bTKK", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 180, + "copper": null + }, + "protection": 2, + "location": [ + "body", + "arms" + ], + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994257751, + "modifiedTime": 1759994294312, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!Sr40RFsPr2M0bTKK" +} diff --git a/packs/protection/_source/Mail__Link__Scale_Coif_HfG5Doxf7576Jgbt.json b/packs/protection/_source/Mail__Link__Scale_Coif_HfG5Doxf7576Jgbt.json new file mode 100644 index 0000000..708afd3 --- /dev/null +++ b/packs/protection/_source/Mail__Link__Scale_Coif_HfG5Doxf7576Jgbt.json @@ -0,0 +1,41 @@ +{ + "folder": "cKN149ZGLqfyt0oi", + "name": "Mail, Link, Scale Coif", + "type": "armour", + "_id": "HfG5Doxf7576Jgbt", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 180, + "copper": null + }, + "protection": 2, + "location": [ + "head" + ], + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994210701, + "modifiedTime": 1759994221462, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!HfG5Doxf7576Jgbt" +} diff --git a/packs/protection/_source/Mail__Link__Scale_Leggings_YBpElIVQ534pm3Mf.json b/packs/protection/_source/Mail__Link__Scale_Leggings_YBpElIVQ534pm3Mf.json new file mode 100644 index 0000000..e1d45ce --- /dev/null +++ b/packs/protection/_source/Mail__Link__Scale_Leggings_YBpElIVQ534pm3Mf.json @@ -0,0 +1,41 @@ +{ + "folder": "cKN149ZGLqfyt0oi", + "name": "Mail, Link, Scale Leggings", + "type": "armour", + "_id": "YBpElIVQ534pm3Mf", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 200, + "copper": null + }, + "protection": 2, + "location": [ + "legs" + ], + "equipped": false, + "weight": null, + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994280754, + "modifiedTime": 1759994424980, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!YBpElIVQ534pm3Mf" +} diff --git a/packs/protection/_source/Mail__Link__Scale_Shirt_wab6Bo8ngar4mBCN.json b/packs/protection/_source/Mail__Link__Scale_Shirt_wab6Bo8ngar4mBCN.json new file mode 100644 index 0000000..766f79f --- /dev/null +++ b/packs/protection/_source/Mail__Link__Scale_Shirt_wab6Bo8ngar4mBCN.json @@ -0,0 +1,41 @@ +{ + "folder": "cKN149ZGLqfyt0oi", + "name": "Mail, Link, Scale Shirt", + "type": "armour", + "_id": "wab6Bo8ngar4mBCN", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 90, + "copper": null + }, + "protection": 2, + "location": [ + "body" + ], + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994235204, + "modifiedTime": 1759994246578, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!wab6Bo8ngar4mBCN" +} diff --git a/packs/protection/_source/Modest_Shields_fyL8LZ8jpEQbjpM2.json b/packs/protection/_source/Modest_Shields_fyL8LZ8jpEQbjpM2.json new file mode 100644 index 0000000..5f40713 --- /dev/null +++ b/packs/protection/_source/Modest_Shields_fyL8LZ8jpEQbjpM2.json @@ -0,0 +1,43 @@ +{ + "folder": "RXPJBkzVxFnoT3Tm", + "name": "Modest Shields", + "type": "shield", + "_id": "fyL8LZ8jpEQbjpM2", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 30, + "copper": null + }, + "protection": 1, + "location": [ + "head", + "body", + "arms" + ], + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994777609, + "modifiedTime": 1759994784898, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!fyL8LZ8jpEQbjpM2" +} diff --git a/packs/protection/_source/Modest_cKN149ZGLqfyt0oi.json b/packs/protection/_source/Modest_cKN149ZGLqfyt0oi.json new file mode 100644 index 0000000..0df0b4f --- /dev/null +++ b/packs/protection/_source/Modest_cKN149ZGLqfyt0oi.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "pZxc6QLgVWfnZlf7", + "name": "Modest", + "color": "#06393f", + "sorting": "a", + "_id": "cKN149ZGLqfyt0oi", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!cKN149ZGLqfyt0oi" +} diff --git a/packs/protection/_source/Plate_Bracers_e8JRJn5Blw3UrvnW.json b/packs/protection/_source/Plate_Bracers_e8JRJn5Blw3UrvnW.json new file mode 100644 index 0000000..b14cd65 --- /dev/null +++ b/packs/protection/_source/Plate_Bracers_e8JRJn5Blw3UrvnW.json @@ -0,0 +1,42 @@ +{ + "folder": "BsNUpCnwmlhOWBhZ", + "name": "Plate Bracers", + "type": "armour", + "_id": "e8JRJn5Blw3UrvnW", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 180, + "copper": null + }, + "protection": 1, + "location": [ + "body", + "arms" + ], + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994478040, + "modifiedTime": 1759994486947, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!e8JRJn5Blw3UrvnW" +} diff --git a/packs/protection/_source/Plate_Leggings_v1y4RKGad2IXOu5e.json b/packs/protection/_source/Plate_Leggings_v1y4RKGad2IXOu5e.json new file mode 100644 index 0000000..ea89641 --- /dev/null +++ b/packs/protection/_source/Plate_Leggings_v1y4RKGad2IXOu5e.json @@ -0,0 +1,41 @@ +{ + "folder": "BsNUpCnwmlhOWBhZ", + "name": "Plate Leggings", + "type": "armour", + "_id": "v1y4RKGad2IXOu5e", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 200, + "copper": null + }, + "protection": 3, + "location": [ + "legs" + ], + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994497119, + "modifiedTime": 1759994506514, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!v1y4RKGad2IXOu5e" +} diff --git a/packs/protection/_source/Ring_Coif__Helm_Z4NTsrX63JNjjZ8Z.json b/packs/protection/_source/Ring_Coif__Helm_Z4NTsrX63JNjjZ8Z.json new file mode 100644 index 0000000..072f340 --- /dev/null +++ b/packs/protection/_source/Ring_Coif__Helm_Z4NTsrX63JNjjZ8Z.json @@ -0,0 +1,41 @@ +{ + "folder": "BsNUpCnwmlhOWBhZ", + "name": "Ring Coif, Helm", + "type": "armour", + "_id": "Z4NTsrX63JNjjZ8Z", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 440, + "copper": null + }, + "protection": 3, + "location": [ + "head" + ], + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994438779, + "modifiedTime": 1759994448846, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!Z4NTsrX63JNjjZ8Z" +} diff --git a/packs/protection/_source/Shields_RXPJBkzVxFnoT3Tm.json b/packs/protection/_source/Shields_RXPJBkzVxFnoT3Tm.json new file mode 100644 index 0000000..f561577 --- /dev/null +++ b/packs/protection/_source/Shields_RXPJBkzVxFnoT3Tm.json @@ -0,0 +1,23 @@ +{ + "type": "Item", + "folder": null, + "name": "Shields", + "color": "#04262a", + "sorting": "m", + "_id": "RXPJBkzVxFnoT3Tm", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994538745, + "modifiedTime": 1759994538745, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!folders!RXPJBkzVxFnoT3Tm" +} diff --git a/packs/weapons/_source/Ammo_gvNPXXRBx2eGIzcU.json b/packs/weapons/_source/Ammo_gvNPXXRBx2eGIzcU.json new file mode 100644 index 0000000..f25006d --- /dev/null +++ b/packs/weapons/_source/Ammo_gvNPXXRBx2eGIzcU.json @@ -0,0 +1,23 @@ +{ + "type": "Item", + "folder": null, + "name": "Ammo", + "color": "#04262a", + "sorting": "a", + "_id": "gvNPXXRBx2eGIzcU", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993925940, + "modifiedTime": 1759993925940, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!folders!gvNPXXRBx2eGIzcU" +} diff --git a/packs/weapons/_source/Arming_Sword_xXUItaoHTQ2QiaX4.json b/packs/weapons/_source/Arming_Sword_xXUItaoHTQ2QiaX4.json new file mode 100644 index 0000000..07dc4b5 --- /dev/null +++ b/packs/weapons/_source/Arming_Sword_xXUItaoHTQ2QiaX4.json @@ -0,0 +1,47 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Arming Sword", + "type": "weapon", + "_id": "xXUItaoHTQ2QiaX4", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 80, + "copper": null + }, + "traits": [], + "range": { + "short": null, + "long": null + }, + "damage": 2, + "wear": { + "value": 4, + "max": 4 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992689272, + "modifiedTime": 1759992708712, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!xXUItaoHTQ2QiaX4" +} diff --git a/packs/weapons/_source/Arrow_gN9JbmouUI7eOrSj.json b/packs/weapons/_source/Arrow_gN9JbmouUI7eOrSj.json new file mode 100644 index 0000000..5538980 --- /dev/null +++ b/packs/weapons/_source/Arrow_gN9JbmouUI7eOrSj.json @@ -0,0 +1,35 @@ +{ + "folder": "gvNPXXRBx2eGIzcU", + "name": "Arrow", + "type": "ammo", + "_id": "gN9JbmouUI7eOrSj", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 12, + "cost": { + "gold": null, + "silver": 3, + "copper": null + }, + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993937035, + "modifiedTime": 1759993944077, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!gN9JbmouUI7eOrSj" +} diff --git a/packs/weapons/_source/Axe__Hammer__Pick_cr35WzuPGDojuOuJ.json b/packs/weapons/_source/Axe__Hammer__Pick_cr35WzuPGDojuOuJ.json new file mode 100644 index 0000000..b36ef0b --- /dev/null +++ b/packs/weapons/_source/Axe__Hammer__Pick_cr35WzuPGDojuOuJ.json @@ -0,0 +1,49 @@ +{ + "folder": "mmd8siMKSLyOeILo", + "name": "Axe, Hammer, Pick", + "type": "weapon", + "_id": "cr35WzuPGDojuOuJ", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 10, + "copper": null + }, + "traits": [ + "Thrown" + ], + "range": { + "short": null, + "long": null + }, + "damage": 0, + "wear": { + "value": 2, + "max": 2 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759991980652, + "modifiedTime": 1759992328546, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!cr35WzuPGDojuOuJ" +} diff --git a/packs/weapons/_source/Battleaxe__Warhammer_otIFI9TIDPWnT3cq.json b/packs/weapons/_source/Battleaxe__Warhammer_otIFI9TIDPWnT3cq.json new file mode 100644 index 0000000..d4249cb --- /dev/null +++ b/packs/weapons/_source/Battleaxe__Warhammer_otIFI9TIDPWnT3cq.json @@ -0,0 +1,47 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Battleaxe, Warhammer", + "type": "weapon", + "_id": "otIFI9TIDPWnT3cq", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 40, + "copper": null + }, + "traits": [], + "range": { + "short": null, + "long": null + }, + "damage": 3, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992730036, + "modifiedTime": 1759992748112, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!otIFI9TIDPWnT3cq" +} diff --git a/packs/weapons/_source/Black_Powder_c86ht86Z9vOEBtNH.json b/packs/weapons/_source/Black_Powder_c86ht86Z9vOEBtNH.json new file mode 100644 index 0000000..ef90dd2 --- /dev/null +++ b/packs/weapons/_source/Black_Powder_c86ht86Z9vOEBtNH.json @@ -0,0 +1,35 @@ +{ + "folder": "gvNPXXRBx2eGIzcU", + "name": "Black Powder", + "type": "ammo", + "_id": "c86ht86Z9vOEBtNH", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 12, + "cost": { + "gold": null, + "silver": 40, + "copper": null + }, + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994005587, + "modifiedTime": 1759994010244, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!c86ht86Z9vOEBtNH" +} diff --git a/packs/weapons/_source/Blowgun_Darts_FvtiEaQhJumPsCwb.json b/packs/weapons/_source/Blowgun_Darts_FvtiEaQhJumPsCwb.json new file mode 100644 index 0000000..9c307f4 --- /dev/null +++ b/packs/weapons/_source/Blowgun_Darts_FvtiEaQhJumPsCwb.json @@ -0,0 +1,35 @@ +{ + "folder": "gvNPXXRBx2eGIzcU", + "name": "Blowgun Darts", + "type": "ammo", + "_id": "FvtiEaQhJumPsCwb", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 12, + "cost": { + "gold": null, + "silver": 2, + "copper": null + }, + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993963869, + "modifiedTime": 1759993969644, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!FvtiEaQhJumPsCwb" +} diff --git a/packs/weapons/_source/Blowgun__Sling_VrG2xer1quhjwUag.json b/packs/weapons/_source/Blowgun__Sling_VrG2xer1quhjwUag.json new file mode 100644 index 0000000..2394a78 --- /dev/null +++ b/packs/weapons/_source/Blowgun__Sling_VrG2xer1quhjwUag.json @@ -0,0 +1,49 @@ +{ + "folder": "vPyj2cK1j66Zyrul", + "name": "Blowgun, Sling", + "type": "weapon", + "_id": "VrG2xer1quhjwUag", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 10, + "copper": null + }, + "traits": [ + "Ammo" + ], + "range": { + "short": 5, + "long": 10 + }, + "damage": 1, + "wear": { + "value": 1, + "max": 1 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993449825, + "modifiedTime": 1759993468278, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!VrG2xer1quhjwUag" +} diff --git a/packs/weapons/_source/Broadsword_I9QaJTU6O2E9WzUS.json b/packs/weapons/_source/Broadsword_I9QaJTU6O2E9WzUS.json new file mode 100644 index 0000000..7802c4f --- /dev/null +++ b/packs/weapons/_source/Broadsword_I9QaJTU6O2E9WzUS.json @@ -0,0 +1,47 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Broadsword", + "type": "weapon", + "_id": "I9QaJTU6O2E9WzUS", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 100, + "copper": null + }, + "traits": [], + "range": { + "short": null, + "long": null + }, + "damage": 3, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992797603, + "modifiedTime": 1759992815028, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!I9QaJTU6O2E9WzUS" +} diff --git a/packs/weapons/_source/Club_NlDJVbXeXRfoCZWp.json b/packs/weapons/_source/Club_NlDJVbXeXRfoCZWp.json new file mode 100644 index 0000000..b174c2b --- /dev/null +++ b/packs/weapons/_source/Club_NlDJVbXeXRfoCZWp.json @@ -0,0 +1,47 @@ +{ + "folder": "mmd8siMKSLyOeILo", + "name": "Club", + "type": "weapon", + "_id": "NlDJVbXeXRfoCZWp", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 2, + "copper": null + }, + "traits": [], + "range": { + "short": null, + "long": null + }, + "damage": 1, + "wear": { + "value": 2, + "max": 2 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992392474, + "modifiedTime": 1759992619109, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!NlDJVbXeXRfoCZWp" +} diff --git a/packs/weapons/_source/Crossbow_BNoYUrlpDk6oBeJt.json b/packs/weapons/_source/Crossbow_BNoYUrlpDk6oBeJt.json new file mode 100644 index 0000000..d03ae6d --- /dev/null +++ b/packs/weapons/_source/Crossbow_BNoYUrlpDk6oBeJt.json @@ -0,0 +1,49 @@ +{ + "folder": "8NNF9jBjpmPpmw1B", + "name": "Crossbow", + "type": "weapon", + "_id": "BNoYUrlpDk6oBeJt", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 90, + "copper": null + }, + "traits": [ + "Reload" + ], + "range": { + "short": 10, + "long": 25 + }, + "damage": 3, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993621847, + "modifiedTime": 1759993694978, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!BNoYUrlpDk6oBeJt" +} diff --git a/packs/weapons/_source/Crossbow_Bolts_7cmLLV6o2pPAyyAg.json b/packs/weapons/_source/Crossbow_Bolts_7cmLLV6o2pPAyyAg.json new file mode 100644 index 0000000..1dea670 --- /dev/null +++ b/packs/weapons/_source/Crossbow_Bolts_7cmLLV6o2pPAyyAg.json @@ -0,0 +1,35 @@ +{ + "folder": "gvNPXXRBx2eGIzcU", + "name": "Crossbow Bolts", + "type": "ammo", + "_id": "7cmLLV6o2pPAyyAg", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 12, + "cost": { + "gold": null, + "silver": 3, + "copper": null + }, + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993977460, + "modifiedTime": 1759993982911, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!7cmLLV6o2pPAyyAg" +} diff --git a/packs/weapons/_source/Cutlass__Saber__Scimitar_kSWrbdKdYIRxkWka.json b/packs/weapons/_source/Cutlass__Saber__Scimitar_kSWrbdKdYIRxkWka.json new file mode 100644 index 0000000..d391acc --- /dev/null +++ b/packs/weapons/_source/Cutlass__Saber__Scimitar_kSWrbdKdYIRxkWka.json @@ -0,0 +1,49 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Cutlass, Saber, Scimitar", + "type": "weapon", + "_id": "kSWrbdKdYIRxkWka", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 120, + "copper": null + }, + "traits": [ + "Agile" + ], + "range": { + "short": null, + "long": null + }, + "damage": 2, + "wear": { + "value": 2, + "max": 2 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992861725, + "modifiedTime": 1759992882913, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!kSWrbdKdYIRxkWka" +} diff --git a/packs/weapons/_source/Dagger_q8z2HptFaPmeHU9n.json b/packs/weapons/_source/Dagger_q8z2HptFaPmeHU9n.json new file mode 100644 index 0000000..8ded77a --- /dev/null +++ b/packs/weapons/_source/Dagger_q8z2HptFaPmeHU9n.json @@ -0,0 +1,50 @@ +{ + "folder": "mmd8siMKSLyOeILo", + "name": "Dagger", + "type": "weapon", + "_id": "q8z2HptFaPmeHU9n", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 20, + "copper": null + }, + "traits": [ + "Agile", + "Thrown" + ], + "range": { + "short": null, + "long": null + }, + "damage": 1, + "wear": { + "value": 1, + "max": 1 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992606052, + "modifiedTime": 1759992639628, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!q8z2HptFaPmeHU9n" +} diff --git a/packs/weapons/_source/Darts_rDxS6EJzg2zvSpxR.json b/packs/weapons/_source/Darts_rDxS6EJzg2zvSpxR.json new file mode 100644 index 0000000..6caf1c7 --- /dev/null +++ b/packs/weapons/_source/Darts_rDxS6EJzg2zvSpxR.json @@ -0,0 +1,49 @@ +{ + "folder": "vPyj2cK1j66Zyrul", + "name": "Darts", + "type": "weapon", + "_id": "rDxS6EJzg2zvSpxR", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 6, + "cost": { + "gold": null, + "silver": 30, + "copper": null + }, + "traits": [ + "Thrown" + ], + "range": { + "short": 3, + "long": 6 + }, + "damage": 1, + "wear": { + "value": 1, + "max": 1 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993477954, + "modifiedTime": 1759993498878, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!rDxS6EJzg2zvSpxR" +} diff --git a/packs/weapons/_source/Flintlock_Pistol_1vxM6KoEPrQ7pjcg.json b/packs/weapons/_source/Flintlock_Pistol_1vxM6KoEPrQ7pjcg.json new file mode 100644 index 0000000..868057d --- /dev/null +++ b/packs/weapons/_source/Flintlock_Pistol_1vxM6KoEPrQ7pjcg.json @@ -0,0 +1,50 @@ +{ + "folder": "vPyj2cK1j66Zyrul", + "name": "Flintlock Pistol", + "type": "weapon", + "_id": "1vxM6KoEPrQ7pjcg", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 260, + "copper": null + }, + "traits": [ + "Reload", + "Loud" + ], + "range": { + "short": 5, + "long": 10 + }, + "damage": 2, + "wear": { + "value": 2, + "max": 2 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993514814, + "modifiedTime": 1759993538727, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!1vxM6KoEPrQ7pjcg" +} diff --git a/packs/weapons/_source/Flintlock_Rifle_xUGUgnjJsKUPgPpX.json b/packs/weapons/_source/Flintlock_Rifle_xUGUgnjJsKUPgPpX.json new file mode 100644 index 0000000..13105fc --- /dev/null +++ b/packs/weapons/_source/Flintlock_Rifle_xUGUgnjJsKUPgPpX.json @@ -0,0 +1,50 @@ +{ + "folder": "IkSGLBUzPI9Jbcj7", + "name": "Flintlock Rifle", + "type": "weapon", + "_id": "xUGUgnjJsKUPgPpX", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 640, + "copper": null + }, + "traits": [ + "Reload", + "Loud" + ], + "range": { + "short": 15, + "long": 30 + }, + "damage": 4, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993769479, + "modifiedTime": 1759993794528, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!xUGUgnjJsKUPgPpX" +} diff --git a/packs/weapons/_source/Great_Arrows_FQ5VBjR0LdXf8Nh2.json b/packs/weapons/_source/Great_Arrows_FQ5VBjR0LdXf8Nh2.json new file mode 100644 index 0000000..6f80b11 --- /dev/null +++ b/packs/weapons/_source/Great_Arrows_FQ5VBjR0LdXf8Nh2.json @@ -0,0 +1,35 @@ +{ + "folder": "gvNPXXRBx2eGIzcU", + "name": "Great Arrows", + "type": "ammo", + "_id": "FQ5VBjR0LdXf8Nh2", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 12, + "cost": { + "gold": null, + "silver": 12, + "copper": null + }, + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993988701, + "modifiedTime": 1759993993428, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!FQ5VBjR0LdXf8Nh2" +} diff --git a/packs/weapons/_source/Greataxe__Maul__Sword_Pfm448hGPVSuyyrd.json b/packs/weapons/_source/Greataxe__Maul__Sword_Pfm448hGPVSuyyrd.json new file mode 100644 index 0000000..ccba1ec --- /dev/null +++ b/packs/weapons/_source/Greataxe__Maul__Sword_Pfm448hGPVSuyyrd.json @@ -0,0 +1,49 @@ +{ + "folder": "3tp9cwpArQNOpkAY", + "name": "Greataxe, Maul, Sword", + "type": "weapon", + "_id": "Pfm448hGPVSuyyrd", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 120, + "copper": null + }, + "traits": [ + "Long" + ], + "range": { + "short": null, + "long": null + }, + "damage": 4, + "wear": { + "value": 4, + "max": 4 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993233713, + "modifiedTime": 1759993258414, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!Pfm448hGPVSuyyrd" +} diff --git a/packs/weapons/_source/Greatbow_N80F8sq9SaHrXBvS.json b/packs/weapons/_source/Greatbow_N80F8sq9SaHrXBvS.json new file mode 100644 index 0000000..a823775 --- /dev/null +++ b/packs/weapons/_source/Greatbow_N80F8sq9SaHrXBvS.json @@ -0,0 +1,49 @@ +{ + "folder": "IkSGLBUzPI9Jbcj7", + "name": "Greatbow", + "type": "weapon", + "_id": "N80F8sq9SaHrXBvS", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 320, + "copper": null + }, + "traits": [ + "Ammo" + ], + "range": { + "short": 20, + "long": 40 + }, + "damage": 4, + "wear": { + "value": 4, + "max": 4 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993806102, + "modifiedTime": 1759993839512, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!N80F8sq9SaHrXBvS" +} diff --git a/packs/weapons/_source/Greatclub__Staff_Ct9iNF9KPMGStSQo.json b/packs/weapons/_source/Greatclub__Staff_Ct9iNF9KPMGStSQo.json new file mode 100644 index 0000000..181532c --- /dev/null +++ b/packs/weapons/_source/Greatclub__Staff_Ct9iNF9KPMGStSQo.json @@ -0,0 +1,49 @@ +{ + "folder": "3tp9cwpArQNOpkAY", + "name": "Greatclub, Staff", + "type": "weapon", + "_id": "Ct9iNF9KPMGStSQo", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 30, + "copper": null + }, + "traits": [ + "Long" + ], + "range": { + "short": null, + "long": null + }, + "damage": 4, + "wear": { + "value": 4, + "max": 4 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993276032, + "modifiedTime": 1759993292511, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!Ct9iNF9KPMGStSQo" +} diff --git a/packs/weapons/_source/Hand_Crossbow_5sUeNom6dn6MaoAE.json b/packs/weapons/_source/Hand_Crossbow_5sUeNom6dn6MaoAE.json new file mode 100644 index 0000000..0dc3807 --- /dev/null +++ b/packs/weapons/_source/Hand_Crossbow_5sUeNom6dn6MaoAE.json @@ -0,0 +1,49 @@ +{ + "folder": "vPyj2cK1j66Zyrul", + "name": "Hand Crossbow", + "type": "weapon", + "_id": "5sUeNom6dn6MaoAE", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 120, + "copper": null + }, + "traits": [ + "Reload" + ], + "range": { + "short": 5, + "long": 10 + }, + "damage": 2, + "wear": { + "value": 1, + "max": 1 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993551322, + "modifiedTime": 1759993570977, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!5sUeNom6dn6MaoAE" +} diff --git a/packs/weapons/_source/Hand_Weapons_3mr6aZe43z7YBysA.json b/packs/weapons/_source/Hand_Weapons_3mr6aZe43z7YBysA.json new file mode 100644 index 0000000..cc22c9f --- /dev/null +++ b/packs/weapons/_source/Hand_Weapons_3mr6aZe43z7YBysA.json @@ -0,0 +1,23 @@ +{ + "type": "Item", + "folder": null, + "name": "Hand Weapons", + "color": "#04262a", + "sorting": "m", + "_id": "3mr6aZe43z7YBysA", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992349332, + "modifiedTime": 1759993205214, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!folders!3mr6aZe43z7YBysA" +} diff --git a/packs/weapons/_source/Heavy_3tp9cwpArQNOpkAY.json b/packs/weapons/_source/Heavy_3tp9cwpArQNOpkAY.json new file mode 100644 index 0000000..729d6f9 --- /dev/null +++ b/packs/weapons/_source/Heavy_3tp9cwpArQNOpkAY.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "3mr6aZe43z7YBysA", + "name": "Heavy", + "color": "#06393f", + "sorting": "a", + "_id": "3tp9cwpArQNOpkAY", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!3tp9cwpArQNOpkAY" +} diff --git a/packs/weapons/_source/Heavy_Crossbow_xJzHTrYsJVL2WsSF.json b/packs/weapons/_source/Heavy_Crossbow_xJzHTrYsJVL2WsSF.json new file mode 100644 index 0000000..bd06196 --- /dev/null +++ b/packs/weapons/_source/Heavy_Crossbow_xJzHTrYsJVL2WsSF.json @@ -0,0 +1,49 @@ +{ + "folder": "IkSGLBUzPI9Jbcj7", + "name": "Heavy Crossbow", + "type": "weapon", + "_id": "xJzHTrYsJVL2WsSF", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 200, + "copper": null + }, + "traits": [ + "Ammo" + ], + "range": { + "short": 20, + "long": 40 + }, + "damage": 4, + "wear": { + "value": 4, + "max": 4 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993848517, + "modifiedTime": 1759993869078, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!xJzHTrYsJVL2WsSF" +} diff --git a/packs/weapons/_source/Heavy_IkSGLBUzPI9Jbcj7.json b/packs/weapons/_source/Heavy_IkSGLBUzPI9Jbcj7.json new file mode 100644 index 0000000..b7585e5 --- /dev/null +++ b/packs/weapons/_source/Heavy_IkSGLBUzPI9Jbcj7.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "sjc6X9bKf7BY04Ar", + "name": "Heavy", + "color": "#06393f", + "sorting": "a", + "_id": "IkSGLBUzPI9Jbcj7", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!IkSGLBUzPI9Jbcj7" +} diff --git a/packs/weapons/_source/Knife_fv5D0xOJVpOwnyTn.json b/packs/weapons/_source/Knife_fv5D0xOJVpOwnyTn.json new file mode 100644 index 0000000..04d325c --- /dev/null +++ b/packs/weapons/_source/Knife_fv5D0xOJVpOwnyTn.json @@ -0,0 +1,49 @@ +{ + "folder": "mmd8siMKSLyOeILo", + "name": "Knife", + "type": "weapon", + "_id": "fv5D0xOJVpOwnyTn", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 6, + "copper": null + }, + "traits": [ + "Thrown" + ], + "range": { + "short": null, + "long": null + }, + "damage": 1, + "wear": { + "value": 1, + "max": 1 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992653763, + "modifiedTime": 1759992669428, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!fv5D0xOJVpOwnyTn" +} diff --git a/packs/weapons/_source/Light_mmd8siMKSLyOeILo.json b/packs/weapons/_source/Light_mmd8siMKSLyOeILo.json new file mode 100644 index 0000000..f243f42 --- /dev/null +++ b/packs/weapons/_source/Light_mmd8siMKSLyOeILo.json @@ -0,0 +1,23 @@ +{ + "type": "Item", + "folder": "3mr6aZe43z7YBysA", + "name": "Light", + "color": "#06393f", + "sorting": "a", + "_id": "mmd8siMKSLyOeILo", + "description": "", + "sort": -100000, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759991969340, + "modifiedTime": 1759993210807, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!folders!mmd8siMKSLyOeILo" +} diff --git a/packs/weapons/_source/Light_vPyj2cK1j66Zyrul.json b/packs/weapons/_source/Light_vPyj2cK1j66Zyrul.json new file mode 100644 index 0000000..fb4cbf3 --- /dev/null +++ b/packs/weapons/_source/Light_vPyj2cK1j66Zyrul.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "sjc6X9bKf7BY04Ar", + "name": "Light", + "color": "#06393f", + "sorting": "a", + "_id": "vPyj2cK1j66Zyrul", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!vPyj2cK1j66Zyrul" +} diff --git a/packs/weapons/_source/Long_Rifle_dn1eja68NNuxB8K1.json b/packs/weapons/_source/Long_Rifle_dn1eja68NNuxB8K1.json new file mode 100644 index 0000000..d20d8c3 --- /dev/null +++ b/packs/weapons/_source/Long_Rifle_dn1eja68NNuxB8K1.json @@ -0,0 +1,50 @@ +{ + "folder": "IkSGLBUzPI9Jbcj7", + "name": "Long Rifle", + "type": "weapon", + "_id": "dn1eja68NNuxB8K1", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 840, + "copper": null + }, + "traits": [ + "Reload", + "Loud" + ], + "range": { + "short": 20, + "long": 40 + }, + "damage": 4, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993878663, + "modifiedTime": 1759993902478, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!dn1eja68NNuxB8K1" +} diff --git a/packs/weapons/_source/Longbow_oyVNU8XgMiZI0Uxr.json b/packs/weapons/_source/Longbow_oyVNU8XgMiZI0Uxr.json new file mode 100644 index 0000000..57ee032 --- /dev/null +++ b/packs/weapons/_source/Longbow_oyVNU8XgMiZI0Uxr.json @@ -0,0 +1,49 @@ +{ + "folder": "8NNF9jBjpmPpmw1B", + "name": "Longbow", + "type": "weapon", + "_id": "oyVNU8XgMiZI0Uxr", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 80, + "copper": null + }, + "traits": [ + "Ammo" + ], + "range": { + "short": 9, + "long": 30 + }, + "damage": 3, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993703627, + "modifiedTime": 1759993727378, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!oyVNU8XgMiZI0Uxr" +} diff --git a/packs/weapons/_source/Longsword_7ezV0MrGA0duoGbl.json b/packs/weapons/_source/Longsword_7ezV0MrGA0duoGbl.json new file mode 100644 index 0000000..7ca740d --- /dev/null +++ b/packs/weapons/_source/Longsword_7ezV0MrGA0duoGbl.json @@ -0,0 +1,49 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Longsword", + "type": "weapon", + "_id": "7ezV0MrGA0duoGbl", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 220, + "copper": null + }, + "traits": [ + "Able" + ], + "range": { + "short": null, + "long": null + }, + "damage": 3, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992894140, + "modifiedTime": 1759992913378, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!7ezV0MrGA0duoGbl" +} diff --git a/packs/weapons/_source/Modest_8NNF9jBjpmPpmw1B.json b/packs/weapons/_source/Modest_8NNF9jBjpmPpmw1B.json new file mode 100644 index 0000000..ca9314d --- /dev/null +++ b/packs/weapons/_source/Modest_8NNF9jBjpmPpmw1B.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "sjc6X9bKf7BY04Ar", + "name": "Modest", + "color": "#06393f", + "sorting": "a", + "_id": "8NNF9jBjpmPpmw1B", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!8NNF9jBjpmPpmw1B" +} diff --git a/packs/weapons/_source/Modest_dBAI76CApXH8qqjx.json b/packs/weapons/_source/Modest_dBAI76CApXH8qqjx.json new file mode 100644 index 0000000..0828e40 --- /dev/null +++ b/packs/weapons/_source/Modest_dBAI76CApXH8qqjx.json @@ -0,0 +1,21 @@ +{ + "type": "Item", + "folder": "3mr6aZe43z7YBysA", + "name": "Modest", + "color": "#06393f", + "sorting": "a", + "_id": "dBAI76CApXH8qqjx", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "lastModifiedBy": null + }, + "_key": "!folders!dBAI76CApXH8qqjx" +} diff --git a/packs/weapons/_source/Poleaxe__Glaive__Halberd_j6C9IyebpKsk7M6R.json b/packs/weapons/_source/Poleaxe__Glaive__Halberd_j6C9IyebpKsk7M6R.json new file mode 100644 index 0000000..28cf30c --- /dev/null +++ b/packs/weapons/_source/Poleaxe__Glaive__Halberd_j6C9IyebpKsk7M6R.json @@ -0,0 +1,49 @@ +{ + "folder": "3tp9cwpArQNOpkAY", + "name": "Poleaxe, Glaive, Halberd", + "type": "weapon", + "_id": "j6C9IyebpKsk7M6R", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 60, + "copper": null + }, + "traits": [ + "Long" + ], + "range": { + "short": null, + "long": null + }, + "damage": 4, + "wear": { + "value": 4, + "max": 4 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993308439, + "modifiedTime": 1759993324411, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!j6C9IyebpKsk7M6R" +} diff --git a/packs/weapons/_source/Quarterstaff_0ebCxTylmQa5UJvF.json b/packs/weapons/_source/Quarterstaff_0ebCxTylmQa5UJvF.json new file mode 100644 index 0000000..63aaffe --- /dev/null +++ b/packs/weapons/_source/Quarterstaff_0ebCxTylmQa5UJvF.json @@ -0,0 +1,49 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Quarterstaff", + "type": "weapon", + "_id": "0ebCxTylmQa5UJvF", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 20, + "copper": null + }, + "traits": [ + "Able" + ], + "range": { + "short": null, + "long": null + }, + "damage": 2, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992932299, + "modifiedTime": 1759992950112, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!0ebCxTylmQa5UJvF" +} diff --git a/packs/weapons/_source/Ranged_Weapons_sjc6X9bKf7BY04Ar.json b/packs/weapons/_source/Ranged_Weapons_sjc6X9bKf7BY04Ar.json new file mode 100644 index 0000000..ff8a606 --- /dev/null +++ b/packs/weapons/_source/Ranged_Weapons_sjc6X9bKf7BY04Ar.json @@ -0,0 +1,23 @@ +{ + "type": "Item", + "folder": null, + "name": "Ranged Weapons", + "color": "#04262a", + "sorting": "m", + "_id": "sjc6X9bKf7BY04Ar", + "description": "", + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993402367, + "modifiedTime": 1759993402367, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!folders!sjc6X9bKf7BY04Ar" +} diff --git a/packs/weapons/_source/Rapier__Foil_cgEQKXKnSShCRQaq.json b/packs/weapons/_source/Rapier__Foil_cgEQKXKnSShCRQaq.json new file mode 100644 index 0000000..b2a5f0c --- /dev/null +++ b/packs/weapons/_source/Rapier__Foil_cgEQKXKnSShCRQaq.json @@ -0,0 +1,50 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Rapier, Foil", + "type": "weapon", + "_id": "cgEQKXKnSShCRQaq", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 120, + "copper": null + }, + "traits": [ + "Agile", + "Long" + ], + "range": { + "short": null, + "long": null + }, + "damage": 2, + "wear": { + "value": 2, + "max": 2 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759992972763, + "modifiedTime": 1759992992895, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!cgEQKXKnSShCRQaq" +} diff --git a/packs/weapons/_source/Scythe_PnBWkLNzmQjXbB94.json b/packs/weapons/_source/Scythe_PnBWkLNzmQjXbB94.json new file mode 100644 index 0000000..e999370 --- /dev/null +++ b/packs/weapons/_source/Scythe_PnBWkLNzmQjXbB94.json @@ -0,0 +1,49 @@ +{ + "folder": "3tp9cwpArQNOpkAY", + "name": "Scythe", + "type": "weapon", + "_id": "PnBWkLNzmQjXbB94", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 80, + "copper": null + }, + "traits": [ + "Long" + ], + "range": { + "short": null, + "long": null + }, + "damage": 4, + "wear": { + "value": 4, + "max": 4 + }, + "equipped": false, + "weight": "heavy", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993335901, + "modifiedTime": 1759993351161, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!PnBWkLNzmQjXbB94" +} diff --git a/packs/weapons/_source/Shortbow_qmnDO3TrKoeW7DZB.json b/packs/weapons/_source/Shortbow_qmnDO3TrKoeW7DZB.json new file mode 100644 index 0000000..484b4ab --- /dev/null +++ b/packs/weapons/_source/Shortbow_qmnDO3TrKoeW7DZB.json @@ -0,0 +1,49 @@ +{ + "folder": "8NNF9jBjpmPpmw1B", + "name": "Shortbow", + "type": "weapon", + "_id": "qmnDO3TrKoeW7DZB", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 50, + "copper": null + }, + "traits": [ + "Ammo" + ], + "range": { + "short": 6, + "long": 20 + }, + "damage": 2, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993734661, + "modifiedTime": 1759993756094, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!qmnDO3TrKoeW7DZB" +} diff --git a/packs/weapons/_source/Shortsword_UulalWrMRtSX5KxZ.json b/packs/weapons/_source/Shortsword_UulalWrMRtSX5KxZ.json new file mode 100644 index 0000000..06322d5 --- /dev/null +++ b/packs/weapons/_source/Shortsword_UulalWrMRtSX5KxZ.json @@ -0,0 +1,47 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Shortsword", + "type": "weapon", + "_id": "UulalWrMRtSX5KxZ", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 60, + "copper": null + }, + "traits": [], + "range": { + "short": null, + "long": null + }, + "damage": 2, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993008835, + "modifiedTime": 1759993028879, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!UulalWrMRtSX5KxZ" +} diff --git a/packs/weapons/_source/Shot_Q5i7hMOPgb9oXmh5.json b/packs/weapons/_source/Shot_Q5i7hMOPgb9oXmh5.json new file mode 100644 index 0000000..5338692 --- /dev/null +++ b/packs/weapons/_source/Shot_Q5i7hMOPgb9oXmh5.json @@ -0,0 +1,35 @@ +{ + "folder": "gvNPXXRBx2eGIzcU", + "name": "Shot", + "type": "ammo", + "_id": "Q5i7hMOPgb9oXmh5", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 12, + "cost": { + "gold": null, + "silver": 10, + "copper": null + }, + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759994014714, + "modifiedTime": 1759994020511, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!Q5i7hMOPgb9oXmh5" +} diff --git a/packs/weapons/_source/Sickle_o9saXoHahbxTxt4h.json b/packs/weapons/_source/Sickle_o9saXoHahbxTxt4h.json new file mode 100644 index 0000000..f0c8fe8 --- /dev/null +++ b/packs/weapons/_source/Sickle_o9saXoHahbxTxt4h.json @@ -0,0 +1,47 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Sickle", + "type": "weapon", + "_id": "o9saXoHahbxTxt4h", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 80, + "copper": null + }, + "traits": [], + "range": { + "short": null, + "long": null + }, + "damage": 3, + "wear": { + "value": 2, + "max": 2 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993051839, + "modifiedTime": 1759993069744, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!o9saXoHahbxTxt4h" +} diff --git a/packs/weapons/_source/Spear__Javelin__Pike_bTOoWxHeLSY9JWNY.json b/packs/weapons/_source/Spear__Javelin__Pike_bTOoWxHeLSY9JWNY.json new file mode 100644 index 0000000..477bc8b --- /dev/null +++ b/packs/weapons/_source/Spear__Javelin__Pike_bTOoWxHeLSY9JWNY.json @@ -0,0 +1,50 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Spear, Javelin, Pike", + "type": "weapon", + "_id": "bTOoWxHeLSY9JWNY", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 30, + "copper": null + }, + "traits": [ + "Agile", + "Thrown" + ], + "range": { + "short": 5, + "long": 10 + }, + "damage": 2, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993081111, + "modifiedTime": 1759993110561, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!bTOoWxHeLSY9JWNY" +} diff --git a/packs/weapons/_source/Throwing_Axe_n2j1gxnn3WnUPag6.json b/packs/weapons/_source/Throwing_Axe_n2j1gxnn3WnUPag6.json new file mode 100644 index 0000000..b193d2a --- /dev/null +++ b/packs/weapons/_source/Throwing_Axe_n2j1gxnn3WnUPag6.json @@ -0,0 +1,49 @@ +{ + "folder": "vPyj2cK1j66Zyrul", + "name": "Throwing Axe", + "type": "weapon", + "_id": "n2j1gxnn3WnUPag6", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 30, + "copper": null + }, + "traits": [ + "Thrown" + ], + "range": { + "short": 2, + "long": 4 + }, + "damage": 1, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "light", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993592390, + "modifiedTime": 1759993609878, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!n2j1gxnn3WnUPag6" +} diff --git a/packs/weapons/_source/Warclub__Flail__Mace_WMiQdSVgM8z84MEv.json b/packs/weapons/_source/Warclub__Flail__Mace_WMiQdSVgM8z84MEv.json new file mode 100644 index 0000000..0f102f8 --- /dev/null +++ b/packs/weapons/_source/Warclub__Flail__Mace_WMiQdSVgM8z84MEv.json @@ -0,0 +1,47 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Warclub, Flail, Mace", + "type": "weapon", + "_id": "WMiQdSVgM8z84MEv", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 80, + "copper": null + }, + "traits": [], + "range": { + "short": null, + "long": null + }, + "damage": 2, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993125576, + "modifiedTime": 1759993138211, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!WMiQdSVgM8z84MEv" +} diff --git a/packs/weapons/_source/Whip_vVF6LZSFi0pNB95E.json b/packs/weapons/_source/Whip_vVF6LZSFi0pNB95E.json new file mode 100644 index 0000000..7380fb8 --- /dev/null +++ b/packs/weapons/_source/Whip_vVF6LZSFi0pNB95E.json @@ -0,0 +1,50 @@ +{ + "folder": "dBAI76CApXH8qqjx", + "name": "Whip", + "type": "weapon", + "_id": "vVF6LZSFi0pNB95E", + "img": "icons/svg/item-bag.svg", + "system": { + "quantity": 1, + "cost": { + "gold": null, + "silver": 20, + "copper": null + }, + "traits": [ + "Agile", + "Long" + ], + "range": { + "short": null, + "long": null + }, + "damage": 1, + "wear": { + "value": 3, + "max": 3 + }, + "equipped": false, + "weight": "modest", + "access": "" + }, + "effects": [], + "sort": 0, + "ownership": { + "default": 0, + "9x9FgB0YTeCJJUDK": 3 + }, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.350", + "systemId": "ripcrypt", + "systemVersion": "0.2.0", + "createdTime": 1759993155738, + "modifiedTime": 1759993176128, + "lastModifiedBy": "9x9FgB0YTeCJJUDK" + }, + "_key": "!items!vVF6LZSFi0pNB95E" +} From de0030a8755ca42be4eb37fbf965d6d1481b9543 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Thu, 9 Oct 2025 18:36:16 -0600 Subject: [PATCH 03/29] Update the workflow to build the compendia and include it in releases --- .github/workflows/draft-release.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 7d4a73f..eecafc4 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -29,6 +29,12 @@ jobs: if: ${{ steps.check-tag.outputs.exists == 'true' }} run: exit 1 + - name: "Building compendia" + run: "npm run data:build" + + - name: "Removing compendium source" + run: "rm -rf packs/**/_source" + - name: Update the manifest with the relevant properties id: manifest-update uses: microsoft/variable-substitution@v1 @@ -38,7 +44,7 @@ jobs: download: "https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/release.zip" - name: Create the zip - run: zip -r release.zip system.json module langs assets templates README.md + run: zip -r release.zip system.json packs module langs assets templates README.md - name: Create the draft release uses: ncipollo/release-action@v1 From 507c9b034173c2d4000462e375a704c61ae0ed4f Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Fri, 10 Oct 2025 18:05:56 -0600 Subject: [PATCH 04/29] Remove parts of the item schemas that aren't necessary --- module/data/Item/Ammo.mjs | 13 ------------- module/data/Item/Common.mjs | 13 ++----------- module/data/Item/Craft.mjs | 13 ------------- module/data/Item/Good.mjs | 13 ------------- module/data/Item/Skill.mjs | 13 ------------- 5 files changed, 2 insertions(+), 63 deletions(-) diff --git a/module/data/Item/Ammo.mjs b/module/data/Item/Ammo.mjs index 0493eb1..135acf8 100644 --- a/module/data/Item/Ammo.mjs +++ b/module/data/Item/Ammo.mjs @@ -2,19 +2,6 @@ import { CommonItemData } from "./Common.mjs"; import { gameTerms } from "../../gameTerms.mjs"; export class AmmoData extends CommonItemData { - // MARK: Base Data - prepareBaseData() { - super.prepareBaseData(); - }; - - // MARK: Derived Data - prepareDerivedData() { - super.prepareDerivedData(); - }; - - // #region Getters - // #endregion - // #region Sheet Data getFormFields(_ctx) { const fields = [ diff --git a/module/data/Item/Common.mjs b/module/data/Item/Common.mjs index bf37c0e..f98dd5a 100644 --- a/module/data/Item/Common.mjs +++ b/module/data/Item/Common.mjs @@ -4,7 +4,7 @@ import { gameTerms } from "../../gameTerms.mjs"; const { fields } = foundry.data; export class CommonItemData extends foundry.abstract.TypeDataModel { - // MARK: Schema + // #region Schema static defineSchema() { return { quantity: requiredInteger({ min: 0, initial: 1 }), @@ -21,14 +21,5 @@ export class CommonItemData extends foundry.abstract.TypeDataModel { }), }; }; - - // MARK: Base Data - prepareBaseData() { - super.prepareBaseData(); - }; - - // MARK: Derived Data - prepareDerivedData() { - super.prepareDerivedData(); - }; + // #endregion Schema }; diff --git a/module/data/Item/Craft.mjs b/module/data/Item/Craft.mjs index 23aa9ba..b9a7d3e 100644 --- a/module/data/Item/Craft.mjs +++ b/module/data/Item/Craft.mjs @@ -21,19 +21,6 @@ export class CraftData extends SkillData { return schema; }; - // MARK: Base Data - prepareBaseData() { - super.prepareBaseData(); - }; - - // MARK: Derived Data - prepareDerivedData() { - super.prepareDerivedData(); - }; - - // #region Getters - // #endregion - // #region Sheet Data async getFormFields(_ctx) { const fields = [ diff --git a/module/data/Item/Good.mjs b/module/data/Item/Good.mjs index 9af246b..34c09b6 100644 --- a/module/data/Item/Good.mjs +++ b/module/data/Item/Good.mjs @@ -17,19 +17,6 @@ export class GoodData extends CommonItemData { return schema; }; - // MARK: Base Data - prepareBaseData() { - super.prepareBaseData(); - }; - - // MARK: Derived Data - prepareDerivedData() { - super.prepareDerivedData(); - }; - - // #region Getters - // #endregion - // #region Sheet Data async getFormFields(_ctx) { const fields = [ diff --git a/module/data/Item/Skill.mjs b/module/data/Item/Skill.mjs index 520a344..da03381 100644 --- a/module/data/Item/Skill.mjs +++ b/module/data/Item/Skill.mjs @@ -34,19 +34,6 @@ export class SkillData extends foundry.abstract.TypeDataModel { return schema; }; - // MARK: Base Data - prepareBaseData() { - super.prepareBaseData(); - }; - - // MARK: Derived Data - prepareDerivedData() { - super.prepareDerivedData(); - }; - - // #region Getters - // #endregion - // #region Sheet Data async getFormFields(_ctx) { const fields = [ From 8de63e91c74cf27e35b18a040739c3ff471add11 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Fri, 10 Oct 2025 18:07:02 -0600 Subject: [PATCH 05/29] Get the foundation Trait type defined --- langs/en-ca.json | 1 + module/data/Item/Trait.mjs | 11 +++++++++++ module/hooks/init.mjs | 2 ++ system.json | 17 +++++++++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 module/data/Item/Trait.mjs diff --git a/langs/en-ca.json b/langs/en-ca.json index a5d28cc..4ba733a 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -11,6 +11,7 @@ "good": "Good", "shield": "Shield", "skill": "Skill", + "trait": "Trait", "weapon": "Weapon" } }, diff --git a/module/data/Item/Trait.mjs b/module/data/Item/Trait.mjs new file mode 100644 index 0000000..1a90c5a --- /dev/null +++ b/module/data/Item/Trait.mjs @@ -0,0 +1,11 @@ +const { fields } = foundry.data; + +export class TraitData extends foundry.abstract.TypeDataModel { + // #region Schema + static defineSchema() { + return { + description: fields.HTMLField({ blank: true, nullable: false, trim: true }), + }; + }; + // #endregion Schema +}; diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index 28c4fd9..e9384d5 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -17,6 +17,7 @@ import { GoodData } from "../data/Item/Good.mjs"; import { HeroData } from "../data/Actor/Hero.mjs"; import { ShieldData } from "../data/Item/Shield.mjs"; import { SkillData } from "../data/Item/Skill.mjs"; +import { TraitData } from "../data/Item/Trait.mjs"; import { WeaponData } from "../data/Item/Weapon.mjs"; // Class Overrides @@ -62,6 +63,7 @@ Hooks.once(`init`, () => { CONFIG.Item.dataModels.good = GoodData; CONFIG.Item.dataModels.shield = ShieldData; CONFIG.Item.dataModels.skill = SkillData; + CONFIG.Item.dataModels.trait = TraitData; CONFIG.Item.dataModels.weapon = WeaponData; // #endregion diff --git a/system.json b/system.json index 5190f37..55a2be4 100644 --- a/system.json +++ b/system.json @@ -48,9 +48,22 @@ "ammo": {}, "armour": {}, "craft": {}, - "good": {}, + "good": { + "htmlFields": [ + "description" + ] + }, "shield": {}, - "skill": {}, + "skill": { + "htmlFields": [ + "description" + ] + }, + "trait": { + "htmlFields": [ + "description" + ] + }, "weapon": {} } } From 803c1673e262e2737c5f4235b5d1fe8a216c3f41 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Fri, 10 Oct 2025 18:45:13 -0600 Subject: [PATCH 06/29] Move dev-only hooks into their own folder that isn't included in the build --- dev/hooks/getHeaderControlsActorSheetV2.mjs | 15 +++++++++++++++ {module => dev}/hooks/hotReload.mjs | 2 +- dev/main.mjs | 3 +++ jsconfig.json | 1 + module/main.mjs | 1 - scripts/prepareManifest.mjs | 14 ++++++++++++++ system.json | 5 +++-- 7 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 dev/hooks/getHeaderControlsActorSheetV2.mjs rename {module => dev}/hooks/hotReload.mjs (87%) create mode 100644 dev/main.mjs create mode 100644 scripts/prepareManifest.mjs diff --git a/dev/hooks/getHeaderControlsActorSheetV2.mjs b/dev/hooks/getHeaderControlsActorSheetV2.mjs new file mode 100644 index 0000000..51725e8 --- /dev/null +++ b/dev/hooks/getHeaderControlsActorSheetV2.mjs @@ -0,0 +1,15 @@ +/* +This hook exists to be able to change all of the actor-sheets to allow +them to have dev-mode controls in their header that are useful for +testing purposes. (This is particularly useful for testing embedded +items that are only allowed to exist on specific actor types) +*/ +Hooks.on(`getHeaderControlsActorSheetV2`, (_app, controls) => { + if (!game.settings.get(`ripcrypt`, `devMode`)) { return } + + controls.push({ + icon: `fa-solid fa-terminal`, + label: `Embed New Item (DEV)`, + action: `createItem`, + }); +}); diff --git a/module/hooks/hotReload.mjs b/dev/hooks/hotReload.mjs similarity index 87% rename from module/hooks/hotReload.mjs rename to dev/hooks/hotReload.mjs index 7ef784f..99f6a55 100644 --- a/module/hooks/hotReload.mjs +++ b/dev/hooks/hotReload.mjs @@ -1,4 +1,4 @@ -import { Logger } from "../utils/Logger.mjs"; +import { Logger } from "../../module/utils/Logger.mjs"; const loaders = { svg(data) { diff --git a/dev/main.mjs b/dev/main.mjs new file mode 100644 index 0000000..35dfa4c --- /dev/null +++ b/dev/main.mjs @@ -0,0 +1,3 @@ +// Hooks +import "./hooks/hotReload.mjs"; +import "./hooks/getHeaderControlsActorSheetV2.mjs"; diff --git a/jsconfig.json b/jsconfig.json index 47b5b55..9841790 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -12,6 +12,7 @@ }, "include": [ "module/**/*", + "dev/**/*", "foundry/client/client.mjs", "foundry/client/global.d.mts", "foundry/common/primitives/global.d.mts" diff --git a/module/main.mjs b/module/main.mjs index 064d9f8..8c32f94 100644 --- a/module/main.mjs +++ b/module/main.mjs @@ -1,7 +1,6 @@ // Hooks import "./hooks/init.mjs"; import "./hooks/ready.mjs"; -import "./hooks/hotReload.mjs"; // Global API import "./api.mjs"; diff --git a/scripts/prepareManifest.mjs b/scripts/prepareManifest.mjs new file mode 100644 index 0000000..ec0ed06 --- /dev/null +++ b/scripts/prepareManifest.mjs @@ -0,0 +1,14 @@ +/* +The intent of this script is to do all of the modifications of the +manifest file that we need to do in order to release the system. This +can include removing dev-only fields/attributes that end users will +never, and should never, care about nor need. +*/ + +// TODO: load the manifest + +// TODO: remove all files that start with dev/ from the esmodules list + +// TODO: remove flags.hotReload + +// TODO: write the new manifest to disk diff --git a/system.json b/system.json index 55a2be4..6cf405f 100644 --- a/system.json +++ b/system.json @@ -12,7 +12,8 @@ { "name": "Oliver" } ], "esmodules": [ - "module/main.mjs" + "module/main.mjs", + "dev/main.mjs" ], "styles": [ { @@ -36,7 +37,7 @@ "flags": { "hotReload": { "extensions": ["css", "hbs", "json", "mjs", "svg"], - "paths": ["assets", "templates", "langs", "module"] + "paths": ["assets", "templates", "langs", "module", "dev"] } }, "documentTypes": { From 0e0f9d383123c64ecb8610d28e2423766e417f4d Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Fri, 10 Oct 2025 21:09:44 -0600 Subject: [PATCH 07/29] Clean up some non-functional CSS --- templates/css/elements/prose-mirror.css | 3 --- templates/css/main.css | 1 - 2 files changed, 4 deletions(-) delete mode 100644 templates/css/elements/prose-mirror.css diff --git a/templates/css/elements/prose-mirror.css b/templates/css/elements/prose-mirror.css deleted file mode 100644 index 7aaa978..0000000 --- a/templates/css/elements/prose-mirror.css +++ /dev/null @@ -1,3 +0,0 @@ -.ripcrypt prose-mirror * { - all: revert-layer; -} diff --git a/templates/css/main.css b/templates/css/main.css index a8c65a3..8fc8421 100644 --- a/templates/css/main.css +++ b/templates/css/main.css @@ -26,4 +26,3 @@ @import url("../Apps/apps.css") layer(apps); /* Exceptions */ -@import url("./elements/prose-mirror.css") layer(exceptions); From 4d0f29d7f0319893f5bd077f2e26f2816f85dd87 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Fri, 10 Oct 2025 21:49:32 -0600 Subject: [PATCH 08/29] Prevent creating a Trait when it's on a non-geist Actor --- langs/en-ca.json | 3 ++- module/data/Item/Trait.mjs | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/langs/en-ca.json b/langs/en-ca.json index 4ba733a..93d8f79 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -202,7 +202,8 @@ "invalid-socket": "Invalid socket data received, this means a module or system bug is present.", "unknown-socket-event": "An unknown socket event was received: {event}", "no-active-gm": "No active @USER.GM is logged in, you must wait for a @USER.GM to be active before you can do that.", - "malformed-socket-payload": "Socket event \"{event}\" received with malformed payload. Details: {details}" + "malformed-socket-payload": "Socket event \"{event}\" received with malformed payload. Details: {details}", + "invalid-parent-document": "Cannot create an item with type \"{itemType}\" on a parent document of type \"{parentType}\"" }, "warn": { "cannot-go-negative": "\"{name}\" is unable to be a negative number." diff --git a/module/data/Item/Trait.mjs b/module/data/Item/Trait.mjs index 1a90c5a..775d5aa 100644 --- a/module/data/Item/Trait.mjs +++ b/module/data/Item/Trait.mjs @@ -1,11 +1,29 @@ +import { localizer } from "../../utils/Localizer.mjs"; + const { fields } = foundry.data; export class TraitData extends foundry.abstract.TypeDataModel { // #region Schema static defineSchema() { return { - description: fields.HTMLField({ blank: true, nullable: false, trim: true }), + description: new fields.HTMLField({ blank: true, nullable: false, trim: true }), }; }; // #endregion Schema + + // #region Lifecycle + async _preCreate() { + if (this.parent.isEmbedded && this.parent.parent.type !== `geist`) { + ui.notifications.error(localizer( + `RipCrypt.notifs.error.invalid-parent-document`, + { itemType: `trait`, parentType: this.parent.parent.type }, + )); + return false; + }; + }; + // #endregion + + async getFormFields() { + return []; + }; }; From 7de3f1ca87a8aae1ba5ba198697372cd19937fed Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Fri, 10 Oct 2025 21:50:01 -0600 Subject: [PATCH 09/29] Add an item sheet for editing Traits --- module/Apps/ItemSheets/TraitSheet.mjs | 53 +++++++++++++++++++++++++ module/hooks/init.mjs | 10 ++++- templates/Apps/TraitSheet/content.hbs | 21 ++++++++++ templates/Apps/TraitSheet/style.css | 35 ++++++++++++++++ templates/Apps/apps.css | 1 + templates/Apps/partials/item-header.hbs | 1 - 6 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 module/Apps/ItemSheets/TraitSheet.mjs create mode 100644 templates/Apps/TraitSheet/content.hbs create mode 100644 templates/Apps/TraitSheet/style.css diff --git a/module/Apps/ItemSheets/TraitSheet.mjs b/module/Apps/ItemSheets/TraitSheet.mjs new file mode 100644 index 0000000..1d8c78d --- /dev/null +++ b/module/Apps/ItemSheets/TraitSheet.mjs @@ -0,0 +1,53 @@ +import { filePath } from "../../consts.mjs"; +import { GenericAppMixin } from "../GenericApp.mjs"; + +const { HandlebarsApplicationMixin } = foundry.applications.api; +const { ItemSheetV2 } = foundry.applications.sheets; + +export class TraitSheet extends GenericAppMixin(HandlebarsApplicationMixin(ItemSheetV2)) { + // #region Options + static DEFAULT_OPTIONS = { + classes: [ + `ripcrypt--item`, + `TraitSheet`, + ], + position: { + width: `auto`, + height: `auto`, + }, + window: { + resizable: true, + }, + form: { + submitOnChange: true, + closeOnSubmit: false, + }, + }; + + static PARTS = { + content: { + template: filePath(`templates/Apps/TraitSheet/content.hbs`), + root: true, + }, + }; + // #endregion Options + + // #region Data Prep + async _prepareContext() { + const TextEditor = foundry.applications.ux.TextEditor.implementation; + const ctx = { + meta: { + idp: this.id, + }, + item: this.document, + enriched: { + system: { + description: await TextEditor.enrichHTML(this.document.system.description), + }, + }, + }; + + return ctx; + }; + // #endregion Data Prep +}; diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index e9384d5..f74514d 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -38,6 +38,7 @@ import { registerMetaSettings } from "../settings/metaSettings.mjs"; import { registerSockets } from "../sockets/_index.mjs"; import { registerUserSettings } from "../settings/userSettings.mjs"; import { registerWorldSettings } from "../settings/worldSettings.mjs"; +import { TraitSheet } from "../Apps/ItemSheets/TraitSheet.mjs"; const { Items, Actors } = foundry.documents.collections; @@ -120,8 +121,15 @@ Hooks.once(`init`, () => { label: `RipCrypt.sheet-names.ArmourSheet`, themes: ArmourSheet.themes, }); + Items.registerSheet(game.system.id, TraitSheet, { + makeDefault: true, + types: [`trait`], + label: `RipCrypt.sheet-names.TraitSheet`, + themes: TraitSheet.themes, + }); + Items.unregisterSheet(game.system.id, AllItemSheetV1, { - types: [`armour`, `shield`], + types: [`armour`, `shield`, `trait`], }); // #endregion // #endregion diff --git a/templates/Apps/TraitSheet/content.hbs b/templates/Apps/TraitSheet/content.hbs new file mode 100644 index 0000000..5e60416 --- /dev/null +++ b/templates/Apps/TraitSheet/content.hbs @@ -0,0 +1,21 @@ +
+ + +
{{{ enriched.system.description }}}
+
diff --git a/templates/Apps/TraitSheet/style.css b/templates/Apps/TraitSheet/style.css new file mode 100644 index 0000000..adbf30c --- /dev/null +++ b/templates/Apps/TraitSheet/style.css @@ -0,0 +1,35 @@ +.ripcrypt.TraitSheet { + --input-underline: none; + max-width: 300px; + + > .window-content { + display: flex; + flex-direction: column; + gap: 8px; + padding: 4px; + color: var(--base-text); + background: var(--base-background); + } + + input { + border-radius: 4px; + padding: 2px 4px; + } + + .value { + background: var(--input-background); + color: var(--input-text); + padding: 4px; + + > :first-child { + margin-top: 0; + } + > :last-child { + margin-bottom: 0; + } + + &:empty { + display: none; + } + } +} diff --git a/templates/Apps/apps.css b/templates/Apps/apps.css index db88f7e..e170ca0 100644 --- a/templates/Apps/apps.css +++ b/templates/Apps/apps.css @@ -7,6 +7,7 @@ @import url("./SkillsCardV1/style.css"); @import url("./RichEditor/style.css"); @import url("./ArmourSheet/style.css"); +@import url("./TraitSheet/style.css"); @import url("./popover.css"); @import url("./popovers/AmmoTracker/style.css"); diff --git a/templates/Apps/partials/item-header.hbs b/templates/Apps/partials/item-header.hbs index 300c166..358779d 100644 --- a/templates/Apps/partials/item-header.hbs +++ b/templates/Apps/partials/item-header.hbs @@ -2,7 +2,6 @@ Required parameters: "name" : the name of the item "system.quantity" : the quantity of the item - "meta.idp" : the ID Prefix for the application --}}
From d6beb4ba6373e24ed030e3fcbed6a7cd2814a815 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sat, 11 Oct 2025 17:02:01 -0600 Subject: [PATCH 10/29] Localize the button label --- langs/en-ca.json | 1 + templates/Apps/TraitSheet/content.hbs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/langs/en-ca.json b/langs/en-ca.json index 93d8f79..355793c 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -174,6 +174,7 @@ "guts-value-readonly": "The current amount of guts the character has", "guts-max-readonly": "The maximum amount of guts the character can have" }, + "edit-description": "Edit Description", "traits-placeholder": "New Trait...", "short-range": "Short @RipCrypt.common.range", "long-range": "Long @RipCrypt.common.range", diff --git a/templates/Apps/TraitSheet/content.hbs b/templates/Apps/TraitSheet/content.hbs index 5e60416..7ede18c 100644 --- a/templates/Apps/TraitSheet/content.hbs +++ b/templates/Apps/TraitSheet/content.hbs @@ -15,7 +15,7 @@ data-uuid="{{item.uuid}}" data-collaborative="true" > - Edit Description + {{ rc-i18n "RipCrypt.Apps.edit-description" }}
{{{ enriched.system.description }}}
From 165c24f32cce171b012220093d34879253b33b0e Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sat, 11 Oct 2025 17:02:58 -0600 Subject: [PATCH 11/29] Remove unneeded helper method --- module/data/Item/Trait.mjs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/module/data/Item/Trait.mjs b/module/data/Item/Trait.mjs index 775d5aa..067cb1c 100644 --- a/module/data/Item/Trait.mjs +++ b/module/data/Item/Trait.mjs @@ -22,8 +22,4 @@ export class TraitData extends foundry.abstract.TypeDataModel { }; }; // #endregion - - async getFormFields() { - return []; - }; }; From e8baec0bc4d98ca8689b2265581e50cfcae799e7 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sat, 11 Oct 2025 17:19:03 -0600 Subject: [PATCH 12/29] Implement the script that handles preparing the manifest for release --- scripts/prepareManifest.mjs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/scripts/prepareManifest.mjs b/scripts/prepareManifest.mjs index ec0ed06..bfdbfba 100644 --- a/scripts/prepareManifest.mjs +++ b/scripts/prepareManifest.mjs @@ -4,11 +4,31 @@ manifest file that we need to do in order to release the system. This can include removing dev-only fields/attributes that end users will never, and should never, care about nor need. */ +import { readFile, writeFile } from "fs/promises"; -// TODO: load the manifest +const MANIFEST_PATH = `system.json`; -// TODO: remove all files that start with dev/ from the esmodules list +let manifest; +try { + manifest = JSON.parse(await readFile(MANIFEST_PATH, `utf-8`)); +} catch { + console.error(`Failed to parse manifest file.`); + process.exit(1); +}; -// TODO: remove flags.hotReload -// TODO: write the new manifest to disk +// Filter out dev-only resources +if (manifest.esmodules) { + manifest.esmodules = manifest.esmodules.filter( + filepath => !filepath.startsWith(`dev/`) + ); +}; + +// Remove dev flags +delete manifest.flags?.hotReload; + +if (Object.keys(manifest.flags).length === 0) { + delete manifest.flags; +}; + +await writeFile(MANIFEST_PATH, JSON.stringify(manifest, undefined, `\t`)); From ca185ba42aeb3589ba3e4b64de5e1820cd555fd8 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sat, 11 Oct 2025 22:52:12 -0600 Subject: [PATCH 13/29] Add a custom mixin that allows doing complex structural position while maintaining partial rerenders --- module/Apps/mixins/LaidOutAppMixin.mjs | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 module/Apps/mixins/LaidOutAppMixin.mjs diff --git a/module/Apps/mixins/LaidOutAppMixin.mjs b/module/Apps/mixins/LaidOutAppMixin.mjs new file mode 100644 index 0000000..956630b --- /dev/null +++ b/module/Apps/mixins/LaidOutAppMixin.mjs @@ -0,0 +1,56 @@ +/** + * This mixin makes it so that we can provide a specific layout template without + * needing to reference each of the inner areas via a partial embedded in the root, + * enabling partial re-renders for parts of the sheet without losing advanced + * layout capabilities. + * + * @param {ReturnType} HandlebarsApp The mixin'd class from HAM to further mix + */ +export function LaidOutAppMixin(HandlebarsApp) { + class LaidOutApp extends HandlebarsApp { + #partDescriptors; + + /** + * This caches the part descriptors into this class of the heirarchy, because + * Foundry doesn't expose the partDescriptors from the HAM directly, so we + * inject a heirarchy call so that we can nab the pointer that Foundry has + * in the HAM so that we can also read/write it from this class. + */ + _configureRenderParts(options) { + const parts = super._configureRenderParts(options); + this.#partDescriptors = parts; + return parts; + }; + + /** + * @override + * This is essentially Foundry's HandlebarsApplicationMixin implementation, + * however if an existing part for non-root elements don't get concatenated + * into the DOM. + */ + _replaceHTML(result, content, options) { + const partInfo = this.#partDescriptors; + for ( const [partId, htmlElement] of Object.entries(result) ) { + const part = partInfo[partId]; + const priorElement = part.root ? content : content.querySelector(`[data-application-part="${partId}"]`); + const state = {}; + if ( priorElement ) { + this._preSyncPartState(partId, htmlElement, priorElement, state); + if ( part.root ) { + priorElement.replaceChildren(...htmlElement.children); + } + else { + priorElement.replaceWith(htmlElement); + } + this._syncPartState(partId, htmlElement, priorElement, state); + } + else { + continue; + }; + this._attachPartListeners(partId, htmlElement, options); + this.parts[partId] = htmlElement; + } + }; + }; + return LaidOutApp; +}; From 0626279fbeba5fa0a3158dc31b52b7b28f5d4881 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sat, 11 Oct 2025 22:52:51 -0600 Subject: [PATCH 14/29] Move the GenericApp mixin into the mixins folder --- module/Apps/ActorSheets/CombinedHeroSheet.mjs | 2 +- module/Apps/ActorSheets/CraftCardV1.mjs | 2 +- module/Apps/ActorSheets/SkillsCardV1.mjs | 2 +- module/Apps/ActorSheets/StatsCardV1.mjs | 2 +- module/Apps/DicePool.mjs | 2 +- module/Apps/ItemSheets/AllItemSheetV1.mjs | 2 +- module/Apps/ItemSheets/ArmourSheet.mjs | 2 +- module/Apps/ItemSheets/TraitSheet.mjs | 2 +- module/Apps/{ => mixins}/GenericApp.mjs | 8 ++++---- 9 files changed, 12 insertions(+), 12 deletions(-) rename module/Apps/{ => mixins}/GenericApp.mjs (95%) diff --git a/module/Apps/ActorSheets/CombinedHeroSheet.mjs b/module/Apps/ActorSheets/CombinedHeroSheet.mjs index b81923a..25f01e4 100644 --- a/module/Apps/ActorSheets/CombinedHeroSheet.mjs +++ b/module/Apps/ActorSheets/CombinedHeroSheet.mjs @@ -1,6 +1,6 @@ import { CraftCardV1 } from "./CraftCardV1.mjs"; import { filePath } from "../../consts.mjs"; -import { GenericAppMixin } from "../GenericApp.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { SkillsCardV1 } from "./SkillsCardV1.mjs"; import { StatsCardV1 } from "./StatsCardV1.mjs"; diff --git a/module/Apps/ActorSheets/CraftCardV1.mjs b/module/Apps/ActorSheets/CraftCardV1.mjs index 4a650df..560a08e 100644 --- a/module/Apps/ActorSheets/CraftCardV1.mjs +++ b/module/Apps/ActorSheets/CraftCardV1.mjs @@ -1,7 +1,7 @@ import { deleteItemFromElement, editItemFromElement } from "../utils.mjs"; import { documentSorter, filePath } from "../../consts.mjs"; import { gameTerms } from "../../gameTerms.mjs"; -import { GenericAppMixin } from "../GenericApp.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { localizer } from "../../utils/Localizer.mjs"; import { Logger } from "../../utils/Logger.mjs"; diff --git a/module/Apps/ActorSheets/SkillsCardV1.mjs b/module/Apps/ActorSheets/SkillsCardV1.mjs index b0231f3..048536c 100644 --- a/module/Apps/ActorSheets/SkillsCardV1.mjs +++ b/module/Apps/ActorSheets/SkillsCardV1.mjs @@ -2,7 +2,7 @@ import { deleteItemFromElement, editItemFromElement } from "../utils.mjs"; import { documentSorter, filePath } from "../../consts.mjs"; import { AmmoTracker } from "../popovers/AmmoTracker.mjs"; import { gameTerms } from "../../gameTerms.mjs"; -import { GenericAppMixin } from "../GenericApp.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { ItemFlags } from "../../flags/item.mjs"; import { localizer } from "../../utils/Localizer.mjs"; import { Logger } from "../../utils/Logger.mjs"; diff --git a/module/Apps/ActorSheets/StatsCardV1.mjs b/module/Apps/ActorSheets/StatsCardV1.mjs index cd44ead..8f05344 100644 --- a/module/Apps/ActorSheets/StatsCardV1.mjs +++ b/module/Apps/ActorSheets/StatsCardV1.mjs @@ -2,7 +2,7 @@ import { deleteItemFromElement, editItemFromElement } from "../utils.mjs"; import { DelveDiceHUD } from "../DelveDiceHUD.mjs"; import { filePath } from "../../consts.mjs"; import { gameTerms } from "../../gameTerms.mjs"; -import { GenericAppMixin } from "../GenericApp.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { localizer } from "../../utils/Localizer.mjs"; import { Logger } from "../../utils/Logger.mjs"; diff --git a/module/Apps/DicePool.mjs b/module/Apps/DicePool.mjs index 7418a3c..99eb70f 100644 --- a/module/Apps/DicePool.mjs +++ b/module/Apps/DicePool.mjs @@ -1,5 +1,5 @@ import { filePath } from "../consts.mjs"; -import { GenericAppMixin } from "./GenericApp.mjs"; +import { GenericAppMixin } from "./mixins/GenericApp.mjs"; import { localizer } from "../utils/Localizer.mjs"; import { Logger } from "../utils/Logger.mjs"; diff --git a/module/Apps/ItemSheets/AllItemSheetV1.mjs b/module/Apps/ItemSheets/AllItemSheetV1.mjs index 0608fde..6ec5fe5 100644 --- a/module/Apps/ItemSheets/AllItemSheetV1.mjs +++ b/module/Apps/ItemSheets/AllItemSheetV1.mjs @@ -1,5 +1,5 @@ import { filePath } from "../../consts.mjs"; -import { GenericAppMixin } from "../GenericApp.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { Logger } from "../../utils/Logger.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; diff --git a/module/Apps/ItemSheets/ArmourSheet.mjs b/module/Apps/ItemSheets/ArmourSheet.mjs index 7570413..bec8a14 100644 --- a/module/Apps/ItemSheets/ArmourSheet.mjs +++ b/module/Apps/ItemSheets/ArmourSheet.mjs @@ -1,6 +1,6 @@ import { filePath } from "../../consts.mjs"; import { gameTerms } from "../../gameTerms.mjs"; -import { GenericAppMixin } from "../GenericApp.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ItemSheetV2 } = foundry.applications.sheets; diff --git a/module/Apps/ItemSheets/TraitSheet.mjs b/module/Apps/ItemSheets/TraitSheet.mjs index 1d8c78d..c835d01 100644 --- a/module/Apps/ItemSheets/TraitSheet.mjs +++ b/module/Apps/ItemSheets/TraitSheet.mjs @@ -1,5 +1,5 @@ import { filePath } from "../../consts.mjs"; -import { GenericAppMixin } from "../GenericApp.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ItemSheetV2 } = foundry.applications.sheets; diff --git a/module/Apps/GenericApp.mjs b/module/Apps/mixins/GenericApp.mjs similarity index 95% rename from module/Apps/GenericApp.mjs rename to module/Apps/mixins/GenericApp.mjs index 0be30e4..b0c2553 100644 --- a/module/Apps/GenericApp.mjs +++ b/module/Apps/mixins/GenericApp.mjs @@ -1,7 +1,7 @@ -import { createItemFromElement, deleteItemFromElement, editItemFromElement, updateForeignDocumentFromEvent } from "./utils.mjs"; -import { DicePool } from "./DicePool.mjs"; -import { RichEditor } from "./RichEditor.mjs"; -import { toBoolean } from "../consts.mjs"; +import { createItemFromElement, deleteItemFromElement, editItemFromElement, updateForeignDocumentFromEvent } from "../utils.mjs"; +import { DicePool } from "../DicePool.mjs"; +import { RichEditor } from "../RichEditor.mjs"; +import { toBoolean } from "../../consts.mjs"; /** * A mixin that takes the class from HandlebarsApplicationMixin and combines it From 163423ea5b063555fb03c56c3d656cb24514f518 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 00:56:07 -0600 Subject: [PATCH 15/29] Add dev button for getting an easy actor reference in the console --- dev/hooks/getHeaderControlsActorSheetV2.mjs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/dev/hooks/getHeaderControlsActorSheetV2.mjs b/dev/hooks/getHeaderControlsActorSheetV2.mjs index 51725e8..07c78eb 100644 --- a/dev/hooks/getHeaderControlsActorSheetV2.mjs +++ b/dev/hooks/getHeaderControlsActorSheetV2.mjs @@ -4,12 +4,20 @@ them to have dev-mode controls in their header that are useful for testing purposes. (This is particularly useful for testing embedded items that are only allowed to exist on specific actor types) */ -Hooks.on(`getHeaderControlsActorSheetV2`, (_app, controls) => { +Hooks.on(`getHeaderControlsActorSheetV2`, (app, controls) => { if (!game.settings.get(`ripcrypt`, `devMode`)) { return } - controls.push({ - icon: `fa-solid fa-terminal`, - label: `Embed New Item (DEV)`, - action: `createItem`, - }); + controls.push( + { + icon: `fa-solid fa-terminal`, + label: `Embed New Item (DEV)`, + action: `createItem`, + }, + { + label: `Make Global Reference`, + onClick: () => { + globalThis._doc = app.actor; + }, + }, + ); }); From 7935a85188d36153db03e0ae9cc8ee173ac41be3 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 01:42:05 -0600 Subject: [PATCH 16/29] Initialize the BookGeistSheet --- module/Apps/ActorSheets/BookGeistSheet.mjs | 99 ++++++++++++++++++++++ module/hooks/init.mjs | 16 ++-- templates/Apps/BookGeistSheet/header.hbs | 7 ++ templates/Apps/BookGeistSheet/image.hbs | 3 + templates/Apps/BookGeistSheet/items.hbs | 1 + templates/Apps/BookGeistSheet/layout.hbs | 10 +++ templates/Apps/BookGeistSheet/stats.hbs | 11 +++ templates/Apps/BookGeistSheet/style.css | 13 +++ templates/Apps/apps.css | 1 + 9 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 module/Apps/ActorSheets/BookGeistSheet.mjs create mode 100644 templates/Apps/BookGeistSheet/header.hbs create mode 100644 templates/Apps/BookGeistSheet/image.hbs create mode 100644 templates/Apps/BookGeistSheet/items.hbs create mode 100644 templates/Apps/BookGeistSheet/layout.hbs create mode 100644 templates/Apps/BookGeistSheet/stats.hbs create mode 100644 templates/Apps/BookGeistSheet/style.css diff --git a/module/Apps/ActorSheets/BookGeistSheet.mjs b/module/Apps/ActorSheets/BookGeistSheet.mjs new file mode 100644 index 0000000..1a789e1 --- /dev/null +++ b/module/Apps/ActorSheets/BookGeistSheet.mjs @@ -0,0 +1,99 @@ +import { filePath } from "../../consts.mjs"; +import { GenericAppMixin } from "../mixins/GenericApp.mjs"; +import { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs"; + +const { HandlebarsApplicationMixin } = foundry.applications.api; +const { ActorSheetV2 } = foundry.applications.sheets; + +export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsApplicationMixin(ActorSheetV2))) { + // #region Options + static DEFAULT_OPTIONS = { + classes: [ + `ripcrypt--actor`, + `BookGeistSheet`, + ], + // position: { + // width: ``, + // height: ``, + // }, + window: { + resizable: true, + }, + form: { + submitOnChange: true, + closeOnSubmite: false, + }, + }; + + static PARTS = { + layout: { + root: true, + template: filePath(`templates/Apps/BookGeistSheet/layout.hbs`), + }, + image: { + template: filePath(`templates/Apps/BookGeistSheet/image.hbs`), + }, + header: { + template: filePath(`templates/Apps/BookGeistSheet/header.hbs`), + }, + stats: { + template: filePath(`templates/Apps/BookGeistSheet/stats.hbs`), + }, + items: { + template: filePath(`templates/Apps/BookGeistSheet/items.hbs`), + }, + }; + // #endregion Options + + // #region Lifecycle + // #endregion Lifecycle + + // #region Data Prep + _preparePartContext(partID, ctx) { + + switch (partID) { + case `layout`: this._prepareLayoutContext(ctx); break; + case `image`: this._prepareImageContext(ctx); break; + case `header`: this._prepareHeaderContext(ctx); break; + case `stats`: this._prepareStatsContext(ctx); break; + case `items`: this._prepareItemsContext(ctx); break; + }; + + return ctx; + }; + + _prepareLayoutContext(ctx) { + ctx.imageVisible = true; + }; + + _prepareImageContext(ctx) { + ctx.url = this.actor.img; + }; + + _prepareHeaderContext(ctx) { + ctx.name = this.actor.name; + ctx.description = null; // this.actor.system.description; + }; + + _prepareStatsContext(ctx) { + const system = this.actor.system; + ctx.path = system.fate; + Object.assign(ctx, system.ability); + ctx.guts = system.guts; + ctx.speed = system.speed; + }; + + _prepareItemsContext(ctx) { + ctx.attacks = []; + ctx.defense = { + locations: `None`, + protection: 0, + shield: false, + }; + ctx.traits = []; + }; + // #endregion Data Prep + + // #region Actions + // #endregion Actions +}; diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index f74514d..4b46bc0 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -1,6 +1,7 @@ // Applications import { AllItemSheetV1 } from "../Apps/ItemSheets/AllItemSheetV1.mjs"; import { ArmourSheet } from "../Apps/ItemSheets/ArmourSheet.mjs"; +import { BookGeistSheet } from "../Apps/ActorSheets/BookGeistSheet.mjs"; import { CombinedHeroSheet } from "../Apps/ActorSheets/CombinedHeroSheet.mjs"; import { CraftCardV1 } from "../Apps/ActorSheets/CraftCardV1.mjs"; import { DelveDiceHUD } from "../Apps/DelveDiceHUD.mjs"; @@ -90,22 +91,21 @@ Hooks.once(`init`, () => { label: `RipCrypt.sheet-names.StatsCardV1`, themes: StatsCardV1.themes, }); - Actors.registerSheet(game.system.id, StatsCardV1, { - makeDefault: true, - types: [`geist`], - label: `RipCrypt.sheet-names.StatsCardV1`, - themes: StatsCardV1.themes, - }); Actors.registerSheet(game.system.id, SkillsCardV1, { - types: [`hero`, `geist`], + types: [`hero`], label: `RipCrypt.sheet-names.SkillsCardV1`, themes: SkillsCardV1.themes, }); Actors.registerSheet(game.system.id, CraftCardV1, { - types: [`hero`, `geist`], + types: [`hero`], label: `RipCrypt.sheet-names.CraftCardV1`, themes: CraftCardV1.themes, }); + Actors.registerSheet(game.system.id, BookGeistSheet, { + types: [`geist`], + label: `RipCrypt.sheet-names.BookGeistSheet`, + themes: BookGeistSheet.themes, + }); // #endregion // #region Items diff --git a/templates/Apps/BookGeistSheet/header.hbs b/templates/Apps/BookGeistSheet/header.hbs new file mode 100644 index 0000000..02b4b14 --- /dev/null +++ b/templates/Apps/BookGeistSheet/header.hbs @@ -0,0 +1,7 @@ +
+ +
diff --git a/templates/Apps/BookGeistSheet/image.hbs b/templates/Apps/BookGeistSheet/image.hbs new file mode 100644 index 0000000..8df65cc --- /dev/null +++ b/templates/Apps/BookGeistSheet/image.hbs @@ -0,0 +1,3 @@ +
+ IMAGE +
diff --git a/templates/Apps/BookGeistSheet/items.hbs b/templates/Apps/BookGeistSheet/items.hbs new file mode 100644 index 0000000..156fe1b --- /dev/null +++ b/templates/Apps/BookGeistSheet/items.hbs @@ -0,0 +1 @@ +
ITEMS
diff --git a/templates/Apps/BookGeistSheet/layout.hbs b/templates/Apps/BookGeistSheet/layout.hbs new file mode 100644 index 0000000..13e8fea --- /dev/null +++ b/templates/Apps/BookGeistSheet/layout.hbs @@ -0,0 +1,10 @@ +
+ {{#if imageVisible}} +
+ {{/if}} +
+
+
+
+
+
diff --git a/templates/Apps/BookGeistSheet/stats.hbs b/templates/Apps/BookGeistSheet/stats.hbs new file mode 100644 index 0000000..716671a --- /dev/null +++ b/templates/Apps/BookGeistSheet/stats.hbs @@ -0,0 +1,11 @@ +
+
    +
  • Path: {{path}}
  • +
  • Grit: {{grit}}
  • +
  • Gait: {{gait}}
  • +
  • Grip: {{grip}}
  • +
  • Glim: {{glim}}
  • +
  • Guts: {{guts.value}} / {{guts.max}}
  • +
  • Move: {{speed.move}} / {{speed.run}}
  • +
+
diff --git a/templates/Apps/BookGeistSheet/style.css b/templates/Apps/BookGeistSheet/style.css new file mode 100644 index 0000000..0d47ece --- /dev/null +++ b/templates/Apps/BookGeistSheet/style.css @@ -0,0 +1,13 @@ +.BookGeistSheet { + > .window-content { + display: flex; + flex-direction: row; + gap: 4px; + } + + .info { + display: flex; + flex-direction: column; + gap: 4px; + } +} diff --git a/templates/Apps/apps.css b/templates/Apps/apps.css index e170ca0..82b7eb5 100644 --- a/templates/Apps/apps.css +++ b/templates/Apps/apps.css @@ -8,6 +8,7 @@ @import url("./RichEditor/style.css"); @import url("./ArmourSheet/style.css"); @import url("./TraitSheet/style.css"); +@import url("./BookGeistSheet/style.css"); @import url("./popover.css"); @import url("./popovers/AmmoTracker/style.css"); From f237bce4d99f8f0762ec34e4e2ca406c440d9b24 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 01:42:23 -0600 Subject: [PATCH 17/29] Update the GenericApp to be using _prepareContext instead of _preparePartContext --- module/Apps/mixins/GenericApp.mjs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/module/Apps/mixins/GenericApp.mjs b/module/Apps/mixins/GenericApp.mjs index b0c2553..ae2eb94 100644 --- a/module/Apps/mixins/GenericApp.mjs +++ b/module/Apps/mixins/GenericApp.mjs @@ -83,10 +83,8 @@ export function GenericAppMixin(HandlebarsApp) { }); }; - async _preparePartContext(partId, ctx, opts) { - ctx = await super._preparePartContext(partId, ctx, opts); - delete ctx.document; - delete ctx.fields; + async _prepareContext() { + const ctx = {}; ctx.meta ??= {}; ctx.meta.idp = this.document?.uuid ?? this.id; @@ -95,7 +93,6 @@ export function GenericAppMixin(HandlebarsApp) { ctx.meta.editable = this.isEditable || game.user.isGM; ctx.meta.embedded = this.document.isEmbedded; }; - delete ctx.editable; return ctx; }; From 28989c2d3590f56cedbc2d5cf173c58a87ab0387 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 14:07:39 -0600 Subject: [PATCH 18/29] Update fate path preparation to use localized labels --- module/Apps/ActorSheets/BookGeistSheet.mjs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/module/Apps/ActorSheets/BookGeistSheet.mjs b/module/Apps/ActorSheets/BookGeistSheet.mjs index 1a789e1..a744669 100644 --- a/module/Apps/ActorSheets/BookGeistSheet.mjs +++ b/module/Apps/ActorSheets/BookGeistSheet.mjs @@ -1,6 +1,7 @@ import { filePath } from "../../consts.mjs"; import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs"; +import { localizer } from "../../utils/Localizer.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ActorSheetV2 } = foundry.applications.sheets; @@ -77,7 +78,21 @@ export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsAp _prepareStatsContext(ctx) { const system = this.actor.system; - ctx.path = system.fate; + + const fate = system.fate; + if (fate) { + ctx.path = { + full: localizer(`RipCrypt.common.ordinals.${fate}.full`), + abbv: localizer(`RipCrypt.common.ordinals.${fate}.abbv`), + }; + } + else { + ctx.path = { + full: null, + abbv: localizer(`RipCrypt.common.empty`), + }; + }; + Object.assign(ctx, system.ability); ctx.guts = system.guts; ctx.speed = system.speed; From 4a8ce9b0994c1a8bea2445e1b64cd139b0146711 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 18:01:47 -0600 Subject: [PATCH 19/29] Update the GenericAppMixin so that it persists focus better --- module/Apps/mixins/GenericApp.mjs | 40 +++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/module/Apps/mixins/GenericApp.mjs b/module/Apps/mixins/GenericApp.mjs index ae2eb94..ffb3666 100644 --- a/module/Apps/mixins/GenericApp.mjs +++ b/module/Apps/mixins/GenericApp.mjs @@ -37,6 +37,8 @@ export function GenericAppMixin(HandlebarsApp) { _popoverManagers = new Map(); /** @type {Map} */ _hookIDs = new Map(); + /** @type {string | null} */ + #focus = null; // #endregion // #region Lifecycle @@ -53,6 +55,26 @@ export function GenericAppMixin(HandlebarsApp) { }; }; + /** + * @override + * This method overrides Foundry's default behaviour for caching the focused + * element so that it actually works when the application has a root partial + */ + async _preRender(...args) { + if (this.rendered) { + const target = this.element.querySelector(`:focus`); + if (target) { + if (target.id) { + this.#focus = `#${CSS.escape(target.id)}`; + } + else if (target.name) { + this.#focus = `${target.tagName}[name="${target.name}"]`; + }; + }; + }; + return super._preRender(...args); + }; + /** @override */ async _onRender(...args) { await super._onRender(...args); @@ -83,11 +105,25 @@ export function GenericAppMixin(HandlebarsApp) { }); }; - async _prepareContext() { + /** + * @override + * This method overrides Foundry's default behaviour for caching the focused + * element so that it actually works when the application has a root partial + */ + async _postRender(...args) { + if (this.rendered) { + const target = this.element.querySelector(this.#focus); + target?.focus(); + }; + this.#focus = null; + return super._postRender(...args); + }; + + async _prepareContext(_options) { const ctx = {}; ctx.meta ??= {}; - ctx.meta.idp = this.document?.uuid ?? this.id; + ctx.meta.idp = this.id; if (this.document) { ctx.meta.limited = this.document.limited; ctx.meta.editable = this.isEditable || game.user.isGM; From e7ac049ae382dbdd087a84f28f50b0ab5af93271 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 20:18:18 -0600 Subject: [PATCH 20/29] Update the eslint indentation rule to be better when using a buncha mixins --- eslint.config.mjs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 4ef4c09..1d3bc7a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -74,7 +74,16 @@ export default [ "@stylistic/space-infix-ops": `warn`, "@stylistic/eol-last": `warn`, "@stylistic/operator-linebreak": [`warn`, `before`], - "@stylistic/indent": [`warn`, `tab`], + "@stylistic/indent": [ + `warn`, + `tab`, + { + SwitchCase: 1, + ignoredNodes: [ + `> .superClass`, + ], + }, + ], "@stylistic/brace-style": [`warn`, `stroustrup`, { "allowSingleLine": true }], "@stylistic/quotes": [`warn`, `backtick`, { "avoidEscape": true }], "@stylistic/comma-dangle": [`warn`, { arrays: `always-multiline`, objects: `always-multiline`, imports: `always-multiline`, exports: `always-multiline`, functions: `always-multiline` }], From d81d86ef474bace3039ce066806ac26c3059c562 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 20:37:16 -0600 Subject: [PATCH 21/29] Auto-equip weapons when embedded into Geist --- module/data/Item/Weapon.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/module/data/Item/Weapon.mjs b/module/data/Item/Weapon.mjs index ec35f29..c4db30f 100644 --- a/module/data/Item/Weapon.mjs +++ b/module/data/Item/Weapon.mjs @@ -49,10 +49,13 @@ export class WeaponData extends CommonItemData { async _preCreate(item, options) { const showEquipPrompt = options.showEquipPrompt ?? true; if (showEquipPrompt && this.parent.isEmbedded && this._canEquip()) { - const shouldEquip = await DialogV2.confirm({ + let shouldEquip = this.parent.parent.type === `geist`; + + shouldEquip ||= await DialogV2.confirm({ window: { title: `Equip Item?` }, content: `Do you want to equip ${item.name}?`, }); + if (shouldEquip) { this.updateSource({ "equipped": true }); }; From 798e7441b4036b0c154b8b544ace9f158ede1321 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 21:28:52 -0600 Subject: [PATCH 22/29] Add a helper to output a value if it's truthy or nothing otherwise --- module/handlebarHelpers/_index.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/module/handlebarHelpers/_index.mjs b/module/handlebarHelpers/_index.mjs index 9c8587d..2d1e881 100644 --- a/module/handlebarHelpers/_index.mjs +++ b/module/handlebarHelpers/_index.mjs @@ -9,5 +9,6 @@ export default { "rc-options": options, // #region Simple + "rc-ifOut": (v) => (v || ``), "rc-empty-state": (v) => v ?? localizer(`RipCrypt.common.empty`), }; From 28345bdef0a054af8b3ef950cd656f363da45074 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Sun, 12 Oct 2025 21:29:59 -0600 Subject: [PATCH 23/29] Begin making the BookGeistSheet have the final design --- module/Apps/ActorSheets/BookGeistSheet.mjs | 114 +++++++++++++++------ templates/Apps/BookGeistSheet/header.hbs | 25 ++++- templates/Apps/BookGeistSheet/image.hbs | 9 +- templates/Apps/BookGeistSheet/items.hbs | 48 ++++++++- templates/Apps/BookGeistSheet/stats.hbs | 105 +++++++++++++++++-- templates/Apps/BookGeistSheet/style.css | 87 ++++++++++++++++ templates/Apps/apps.css | 19 +--- templates/Apps/common.css | 17 +++ 8 files changed, 360 insertions(+), 64 deletions(-) create mode 100644 templates/Apps/common.css diff --git a/module/Apps/ActorSheets/BookGeistSheet.mjs b/module/Apps/ActorSheets/BookGeistSheet.mjs index a744669..5c39a1d 100644 --- a/module/Apps/ActorSheets/BookGeistSheet.mjs +++ b/module/Apps/ActorSheets/BookGeistSheet.mjs @@ -2,21 +2,27 @@ import { filePath } from "../../consts.mjs"; import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs"; import { localizer } from "../../utils/Localizer.mjs"; +import { editItemFromElement, deleteItemFromElement } from "../utils.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ActorSheetV2 } = foundry.applications.sheets; -export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsApplicationMixin(ActorSheetV2))) { +export class BookGeistSheet extends + LaidOutAppMixin( + GenericAppMixin( + HandlebarsApplicationMixin( + ActorSheetV2, +))) { // #region Options static DEFAULT_OPTIONS = { classes: [ `ripcrypt--actor`, `BookGeistSheet`, ], - // position: { - // width: ``, - // height: ``, - // }, + position: { + width: `auto`, + height: `auto`, + }, window: { resizable: true, }, @@ -31,52 +37,71 @@ export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsAp root: true, template: filePath(`templates/Apps/BookGeistSheet/layout.hbs`), }, - image: { - template: filePath(`templates/Apps/BookGeistSheet/image.hbs`), - }, - header: { - template: filePath(`templates/Apps/BookGeistSheet/header.hbs`), - }, - stats: { - template: filePath(`templates/Apps/BookGeistSheet/stats.hbs`), - }, - items: { - template: filePath(`templates/Apps/BookGeistSheet/items.hbs`), - }, + image: { template: filePath(`templates/Apps/BookGeistSheet/image.hbs`) }, + header: { template: filePath(`templates/Apps/BookGeistSheet/header.hbs`) }, + stats: { template: filePath(`templates/Apps/BookGeistSheet/stats.hbs`) }, + items: { template: filePath(`templates/Apps/BookGeistSheet/items.hbs`) }, }; // #endregion Options // #region Lifecycle + async _onRender() { + await super._onRender(); + + new ContextMenu( + this.element, + `[data-ctx-menu="item"]`, + [ + { + name: localizer(`RipCrypt.common.edit`), + condition: (el) => { + const itemId = el.dataset.itemId; + return itemId !== ``; + }, + callback: editItemFromElement, + }, + { + name: localizer(`RipCrypt.common.delete`), + condition: (el) => { + const itemId = el.dataset.itemId; + return itemId !== ``; + }, + callback: deleteItemFromElement, + }, + ], + { jQuery: false, fixed: true }, + ); + }; // #endregion Lifecycle // #region Data Prep - _preparePartContext(partID, ctx) { + async _preparePartContext(partID, ctx) { switch (partID) { - case `layout`: this._prepareLayoutContext(ctx); break; - case `image`: this._prepareImageContext(ctx); break; - case `header`: this._prepareHeaderContext(ctx); break; - case `stats`: this._prepareStatsContext(ctx); break; - case `items`: this._prepareItemsContext(ctx); break; + case `layout`: await this._prepareLayoutContext(ctx); break; + case `image`: await this._prepareImageContext(ctx); break; + case `header`: await this._prepareHeaderContext(ctx); break; + case `stats`: await this._prepareStatsContext(ctx); break; + case `items`: await this._prepareItemsContext(ctx); break; }; return ctx; }; - _prepareLayoutContext(ctx) { + async _prepareLayoutContext(ctx) { ctx.imageVisible = true; }; - _prepareImageContext(ctx) { + async _prepareImageContext(ctx) { ctx.url = this.actor.img; }; - _prepareHeaderContext(ctx) { + async _prepareHeaderContext(ctx) { ctx.name = this.actor.name; ctx.description = null; // this.actor.system.description; }; - _prepareStatsContext(ctx) { + async _prepareStatsContext(ctx) { const system = this.actor.system; const fate = system.fate; @@ -98,14 +123,45 @@ export class BookGeistSheet extends LaidOutAppMixin(GenericAppMixin(HandlebarsAp ctx.speed = system.speed; }; - _prepareItemsContext(ctx) { + async _prepareItemsContext(ctx) { ctx.attacks = []; ctx.defense = { locations: `None`, protection: 0, shield: false, }; - ctx.traits = []; + ctx.traits = []; // Array<{name: string}> + + for (const item of this.actor.items) { + switch (item.type) { + case `weapon`: { + if (!item.system.equipped) { continue }; + ctx.attacks.push(this._prepareWeapon(item)); + break; + }; + case `trait`: { + ctx.traits.push(this._prepareTrait(item)); + break; + }; + }; + }; + }; + + _prepareWeapon(weapon) { + return { + uuid: weapon.uuid, + name: weapon.name, + damage: weapon.system.damage, + range: weapon.system.range, + }; + }; + + _prepareTrait(trait) { + return { + uuid: trait.uuid, + name: trait.name, + description: trait.system.description, + }; }; // #endregion Data Prep diff --git a/templates/Apps/BookGeistSheet/header.hbs b/templates/Apps/BookGeistSheet/header.hbs index 02b4b14..eb830eb 100644 --- a/templates/Apps/BookGeistSheet/header.hbs +++ b/templates/Apps/BookGeistSheet/header.hbs @@ -1,7 +1,22 @@
- +
+ +
+ Rank + +
+ {{#if description}} +
+ {{{description}}} +
+ {{/if}}
diff --git a/templates/Apps/BookGeistSheet/image.hbs b/templates/Apps/BookGeistSheet/image.hbs index 8df65cc..3edfe8e 100644 --- a/templates/Apps/BookGeistSheet/image.hbs +++ b/templates/Apps/BookGeistSheet/image.hbs @@ -1,3 +1,8 @@ -
- IMAGE +
+
diff --git a/templates/Apps/BookGeistSheet/items.hbs b/templates/Apps/BookGeistSheet/items.hbs index 156fe1b..937f546 100644 --- a/templates/Apps/BookGeistSheet/items.hbs +++ b/templates/Apps/BookGeistSheet/items.hbs @@ -1 +1,47 @@ -
ITEMS
+
+
Attacks
+
+ {{#each attacks as |attack|}} +
+ {{attack.name}} +
+ {{else}} + Unarmed! + {{/each}} +
+
Defense
+
+ Armour + {{rc-ifOut defense.protection}} + / + {{defense.locations}} + {{#if defense.shield}} + , Shield + {{/if}} +
+
Traits
+
    + {{#each traits as |trait|}} +
  • + {{trait.name}} + {{#if trait.description}} + + {{/if}} +
  • + {{else}} + None + {{/each}} +
+
diff --git a/templates/Apps/BookGeistSheet/stats.hbs b/templates/Apps/BookGeistSheet/stats.hbs index 716671a..68417b4 100644 --- a/templates/Apps/BookGeistSheet/stats.hbs +++ b/templates/Apps/BookGeistSheet/stats.hbs @@ -1,11 +1,98 @@
-
    -
  • Path: {{path}}
  • -
  • Grit: {{grit}}
  • -
  • Gait: {{gait}}
  • -
  • Grip: {{grip}}
  • -
  • Glim: {{glim}}
  • -
  • Guts: {{guts.value}} / {{guts.max}}
  • -
  • Move: {{speed.move}} / {{speed.run}}
  • -
+ {{log this}} + + + + + + + + + + + + + + + + + + + + + + + +
PathGritGaitGripGlimGutsMove
+ {{path.abbv}} + + {{#if meta.editable}} + + {{else if meta.limited}} + ??? + {{else}} + {{grit}} + {{/if}} + + {{#if meta.editable}} + + {{else if meta.limited}} + ??? + {{else}} + {{gait}} + {{/if}} + + {{#if meta.editable}} + + {{else if meta.limited}} + ??? + {{else}} + {{grip}} + {{/if}} + + {{#if meta.editable}} + + {{else if meta.limited}} + ??? + {{else}} + {{glim}} + {{/if}} + + {{#if meta.editable}} + + / {{guts.max}} + {{else if meta.limited}} + ??/?? + {{else}} + {{guts.value}}/{{guts.max}} + {{/if}} + {{speed.move}} / {{speed.run}}
diff --git a/templates/Apps/BookGeistSheet/style.css b/templates/Apps/BookGeistSheet/style.css index 0d47ece..e698743 100644 --- a/templates/Apps/BookGeistSheet/style.css +++ b/templates/Apps/BookGeistSheet/style.css @@ -3,11 +3,98 @@ display: flex; flex-direction: row; gap: 4px; + padding: 8px; + color: var(--base-text); + background: var(--base-background); } .info { display: flex; flex-direction: column; + justify-content: space-between; gap: 4px; } + + .img-wrapper { + display: flex; + justify-content: center; + align-items: center; + + img { + width: 150px; + height: 150px; + } + } + + .overview { + display: flex; + flex-direction: row; + gap: 4px; + + input { + width: 50%; + } + } + + table { + td { + border: 1px solid var(--accent-1); + text-align: center; + + input { + width: 30px; + background: unset; + text-align: center; + } + } + + thead td { + font-weight: bold; + border-top-width: 0; + + &:first-of-type, &:last-of-type { + border-left-width: 0; + border-right-width: 0; + } + } + + tbody tr { + td:first-of-type, td:last-of-type { + border-left-width: 0; + border-right-width: 0; + } + + &:last-of-type td { + border-bottom-width: 0; + } + } + + .alt { + background-color: var(--alt-row-background); + } + } + + .items { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 4fr); + grid-template-rows: repeat(3, auto); + gap: 2px; + + .traits { + display: flex; + flex-direction: row; + gap: 8px; + list-style-type: none; + } + + .trait { + display: flex; + flex-direction: row; + align-items: center; + gap: 4px; + background-color: var(--accent-2); + border-radius: 4px; + padding: 2px 4px; + } + } } diff --git a/templates/Apps/apps.css b/templates/Apps/apps.css index 82b7eb5..e620e85 100644 --- a/templates/Apps/apps.css +++ b/templates/Apps/apps.css @@ -1,3 +1,4 @@ +@import url("./common.css"); @import url("./AllItemSheetV1/style.css"); @import url("./CombinedHeroSheet/style.css"); @import url("./DelveDiceHUD/style.css"); @@ -12,21 +13,3 @@ @import url("./popover.css"); @import url("./popovers/AmmoTracker/style.css"); - -.ripcrypt { - .window-content { - flex: initial; - padding: 0; - margin: 0; - } - - .StatsCardV1, - .SkillsCardV1, - .CraftCardV1 { - padding: 8px; - /* height: 270px; */ - width: 680px; - --col-gap: 2px; - --row-gap: 4px; - } -} diff --git a/templates/Apps/common.css b/templates/Apps/common.css new file mode 100644 index 0000000..379307a --- /dev/null +++ b/templates/Apps/common.css @@ -0,0 +1,17 @@ +.ripcrypt { + .window-content { + flex: initial; + padding: 0; + margin: 0; + } + + .StatsCardV1, + .SkillsCardV1, + .CraftCardV1 { + padding: 8px; + /* height: 270px; */ + width: 680px; + --col-gap: 2px; + --row-gap: 4px; + } +} From cd69228e680b3f2d680ad058df4d8db02e95bf81 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Mon, 13 Oct 2025 21:29:56 -0600 Subject: [PATCH 24/29] Add Craft as it's own section item. Display the attack range --- module/Apps/ActorSheets/BookGeistSheet.mjs | 18 +++++++- templates/Apps/BookGeistSheet/items.hbs | 48 +++++++++++++++------- templates/Apps/BookGeistSheet/style.css | 1 + 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/module/Apps/ActorSheets/BookGeistSheet.mjs b/module/Apps/ActorSheets/BookGeistSheet.mjs index 5c39a1d..7a6aa06 100644 --- a/module/Apps/ActorSheets/BookGeistSheet.mjs +++ b/module/Apps/ActorSheets/BookGeistSheet.mjs @@ -124,7 +124,6 @@ export class BookGeistSheet extends }; async _prepareItemsContext(ctx) { - ctx.attacks = []; ctx.defense = { locations: `None`, protection: 0, @@ -136,9 +135,15 @@ export class BookGeistSheet extends switch (item.type) { case `weapon`: { if (!item.system.equipped) { continue }; + ctx.attacks ??= []; ctx.attacks.push(this._prepareWeapon(item)); break; }; + case `craft`: { + ctx.crafts ??= []; + ctx.crafts.push(this._prepareCraft(item)); + break; + }; case `trait`: { ctx.traits.push(this._prepareTrait(item)); break; @@ -148,14 +153,25 @@ export class BookGeistSheet extends }; _prepareWeapon(weapon) { + const hasShortRange = weapon.system.range.short != null; + const hasLongRange = weapon.system.range.long != null; + const isRanged = hasShortRange || hasLongRange; return { uuid: weapon.uuid, name: weapon.name, damage: weapon.system.damage, + isRanged, range: weapon.system.range, }; }; + _prepareCraft(craft) { + return { + uuid: craft.uuid, + name: craft.name, + }; + }; + _prepareTrait(trait) { return { uuid: trait.uuid, diff --git a/templates/Apps/BookGeistSheet/items.hbs b/templates/Apps/BookGeistSheet/items.hbs index 937f546..c60ba24 100644 --- a/templates/Apps/BookGeistSheet/items.hbs +++ b/templates/Apps/BookGeistSheet/items.hbs @@ -1,18 +1,38 @@
-
Attacks
-
- {{#each attacks as |attack|}} -
- {{attack.name}} -
- {{else}} - Unarmed! - {{/each}} -
+ {{#if attacks}} +
Attacks
+
+ {{#each attacks as |attack|}} +
+ {{attack.name}} + {{attack.damage}} + {{#if attack.isRanged}} + + ({{attack.range.short}} / {{attack.range.long}}) + + {{/if}} +
+ {{/each}} +
+ {{/if}} + {{#if crafts}} +
Craft
+
+ {{#each crafts as |craft|}} +
+ {{craft.name}} +
+ {{/each}} +
+ {{/if}}
Defense
Armour diff --git a/templates/Apps/BookGeistSheet/style.css b/templates/Apps/BookGeistSheet/style.css index e698743..60cd1bc 100644 --- a/templates/Apps/BookGeistSheet/style.css +++ b/templates/Apps/BookGeistSheet/style.css @@ -19,6 +19,7 @@ display: flex; justify-content: center; align-items: center; + flex-shrink: 0; img { width: 150px; From 0d1c2ddbb35240ca1ba1c1a0737f884f2bda5307 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Wed, 15 Oct 2025 21:27:40 -0600 Subject: [PATCH 25/29] Fix deprecation warning --- module/Apps/ActorSheets/BookGeistSheet.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/Apps/ActorSheets/BookGeistSheet.mjs b/module/Apps/ActorSheets/BookGeistSheet.mjs index 7a6aa06..cafb51d 100644 --- a/module/Apps/ActorSheets/BookGeistSheet.mjs +++ b/module/Apps/ActorSheets/BookGeistSheet.mjs @@ -6,6 +6,7 @@ import { editItemFromElement, deleteItemFromElement } from "../utils.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ActorSheetV2 } = foundry.applications.sheets; +const { ContextMenu } = foundry.applications.ux; export class BookGeistSheet extends LaidOutAppMixin( @@ -48,7 +49,7 @@ export class BookGeistSheet extends async _onRender() { await super._onRender(); - new ContextMenu( + new ContextMenu.implementation( this.element, `[data-ctx-menu="item"]`, [ From d70c5113b133621986f8e589f7288497d8b04caf Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Wed, 15 Oct 2025 22:33:39 -0600 Subject: [PATCH 26/29] Remove log that's a bit spammy --- module/Apps/DelveDiceHUD.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/module/Apps/DelveDiceHUD.mjs b/module/Apps/DelveDiceHUD.mjs index 9599fa1..0998668 100644 --- a/module/Apps/DelveDiceHUD.mjs +++ b/module/Apps/DelveDiceHUD.mjs @@ -143,7 +143,6 @@ export class DelveDiceHUD extends HandlebarsApplicationMixin(ApplicationV2) { }; }; - Logger.log(`${partId} Context`, ctx); return ctx; }; From 8ed6f49c8d9f6fe5742672362a2651548c4fddfc Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Wed, 15 Oct 2025 22:34:46 -0600 Subject: [PATCH 27/29] Finish the initial requirements for the header partial --- module/Apps/ActorSheets/BookGeistSheet.mjs | 10 ++++++++-- module/data/Actor/Geist.mjs | 17 ++++++++++++++++- templates/Apps/BookGeistSheet/header.hbs | 14 ++++++++------ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/module/Apps/ActorSheets/BookGeistSheet.mjs b/module/Apps/ActorSheets/BookGeistSheet.mjs index cafb51d..a1427d1 100644 --- a/module/Apps/ActorSheets/BookGeistSheet.mjs +++ b/module/Apps/ActorSheets/BookGeistSheet.mjs @@ -6,7 +6,7 @@ import { editItemFromElement, deleteItemFromElement } from "../utils.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ActorSheetV2 } = foundry.applications.sheets; -const { ContextMenu } = foundry.applications.ux; +const { ContextMenu, TextEditor } = foundry.applications.ux; export class BookGeistSheet extends LaidOutAppMixin( @@ -99,7 +99,13 @@ export class BookGeistSheet extends async _prepareHeaderContext(ctx) { ctx.name = this.actor.name; - ctx.description = null; // this.actor.system.description; + ctx.rank = this.actor.system.level.rank; + ctx.ranks = Object.values(gameTerms.Rank) + .map((value, index) => ({ + value, + label: index + })); + ctx.description = await TextEditor.implementation.enrichHTML(this.actor.system.description); }; async _prepareStatsContext(ctx) { diff --git a/module/data/Actor/Geist.mjs b/module/data/Actor/Geist.mjs index 440392a..b78572c 100644 --- a/module/data/Actor/Geist.mjs +++ b/module/data/Actor/Geist.mjs @@ -1,3 +1,18 @@ import { EntityData } from "./Entity.mjs"; -export class GeistData extends EntityData {}; +const { fields } = foundry.data; + +export class GeistData extends EntityData { + static defineSchema() { + const schema = super.defineSchema(); + + schema.description = new fields.HTMLField({ + blank: true, + nullable: true, + trim: true, + initial: null, + }); + + return schema; + }; +}; diff --git a/templates/Apps/BookGeistSheet/header.hbs b/templates/Apps/BookGeistSheet/header.hbs index eb830eb..fe198ef 100644 --- a/templates/Apps/BookGeistSheet/header.hbs +++ b/templates/Apps/BookGeistSheet/header.hbs @@ -6,12 +6,14 @@ value="{{name}}" >
- Rank - + {{rc-options rank ranks}}
{{#if description}} From 1d13f38f817db8d8fc64722652a1545fc9e74386 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Wed, 15 Oct 2025 22:35:44 -0600 Subject: [PATCH 28/29] Tweak the way armour shows up on the sheet so that it's a bit easier to deal with --- module/Apps/ActorSheets/BookGeistSheet.mjs | 32 +++++++++++++++++++--- templates/Apps/BookGeistSheet/items.hbs | 29 ++++++++++++++------ templates/Apps/BookGeistSheet/style.css | 6 ++-- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/module/Apps/ActorSheets/BookGeistSheet.mjs b/module/Apps/ActorSheets/BookGeistSheet.mjs index a1427d1..eeeffdd 100644 --- a/module/Apps/ActorSheets/BookGeistSheet.mjs +++ b/module/Apps/ActorSheets/BookGeistSheet.mjs @@ -3,6 +3,7 @@ import { GenericAppMixin } from "../mixins/GenericApp.mjs"; import { LaidOutAppMixin } from "../mixins/LaidOutAppMixin.mjs"; import { localizer } from "../../utils/Localizer.mjs"; import { editItemFromElement, deleteItemFromElement } from "../utils.mjs"; +import { gameTerms } from "../../gameTerms.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ActorSheetV2 } = foundry.applications.sheets; @@ -131,11 +132,34 @@ export class BookGeistSheet extends }; async _prepareItemsContext(ctx) { - ctx.defense = { - locations: `None`, - protection: 0, - shield: false, + const armours = this.actor.system.equippedArmour; + const shield = this.actor.system.equippedShield; + + let defenses = []; + for (const [location, armour] of Object.entries(armours)) { + if (!armour) { continue } + const defense = { + name: localizer(`RipCrypt.common.anatomy.${location}`), + tooltip: null, + protection: 0, + shielded: false, + }; + if (armour) { + defense.armourUUID = armour.uuid; + defense.tooltip = armour.name, + defense.protection = armour.system.protection; + } + if (shield?.system.location.has(location)) { + defense.shieldUUID = shield.uuid; + defense.shielded = true; + defense.protection += shield.system.protection; + }; + if (defense.protection > 0) { + defenses.push(defense); + }; }; + + ctx.defenses = defenses ctx.traits = []; // Array<{name: string}> for (const item of this.actor.items) { diff --git a/templates/Apps/BookGeistSheet/items.hbs b/templates/Apps/BookGeistSheet/items.hbs index c60ba24..dbe53b5 100644 --- a/templates/Apps/BookGeistSheet/items.hbs +++ b/templates/Apps/BookGeistSheet/items.hbs @@ -34,15 +34,26 @@
{{/if}}
Defense
-
- Armour - {{rc-ifOut defense.protection}} - / - {{defense.locations}} - {{#if defense.shield}} - , Shield - {{/if}} -
+
    + {{#each defenses as |defense|}} +
  • + {{defense.name}} ({{defense.protection}}{{#if defense.shielded}}, + + {{/if}}) +
  • + {{/each}} +
Traits
    {{#each traits as |trait|}} diff --git a/templates/Apps/BookGeistSheet/style.css b/templates/Apps/BookGeistSheet/style.css index 60cd1bc..4c8b2cf 100644 --- a/templates/Apps/BookGeistSheet/style.css +++ b/templates/Apps/BookGeistSheet/style.css @@ -81,14 +81,14 @@ grid-template-rows: repeat(3, auto); gap: 2px; - .traits { + ul { display: flex; flex-direction: row; - gap: 8px; + gap: 4px; list-style-type: none; } - .trait { + li { display: flex; flex-direction: row; align-items: center; From f3aecc1ce8c5915dfce0ec03f51b98f37c3728c5 Mon Sep 17 00:00:00 2001 From: Eldritch-Oliver Date: Wed, 15 Oct 2025 22:35:52 -0600 Subject: [PATCH 29/29] Remove handlebars log --- templates/Apps/BookGeistSheet/stats.hbs | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/Apps/BookGeistSheet/stats.hbs b/templates/Apps/BookGeistSheet/stats.hbs index 68417b4..453ab1b 100644 --- a/templates/Apps/BookGeistSheet/stats.hbs +++ b/templates/Apps/BookGeistSheet/stats.hbs @@ -1,5 +1,4 @@
    - {{log this}}