A repository for a FoundryVTT plugin for Kingmaker homebrew.

Moving to TypeScript #1

closed opened by cass.cityboundforest.com targeting main from ts-vite-svelte
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:lsxnahuhdg6llq7lpo3wq6kf/sh.tangled.repo.pull/3m243omuuz422
+556 -1
Diff #0
+12
public/lang/en.json
··· 1 + 2 + 3 + 4 + 5 + 6 + "settlements": "Settlements", 7 + "relations": "Relations", 8 + "effects": "Effects" 9 + }, 10 + "kingdom-title": "Kingdom Sheet" 11 + } 12 + }
+52
public/module.json
··· 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + ] 47 + }, 48 + "esmodules": [ 49 + "main.iife.js" 50 + ], 51 + "languages": [ 52 + {
src/styles/kingdom-sheet.css public/styles/kingdom-sheet.css
src/templates/levels/level-1.hbs public/templates/levels/level-1.hbs
src/templates/levels/level-10.hbs public/templates/levels/level-10.hbs
src/templates/levels/level-11.hbs public/templates/levels/level-11.hbs
src/templates/levels/level-12.hbs public/templates/levels/level-12.hbs
src/templates/levels/level-13.hbs public/templates/levels/level-13.hbs
src/templates/levels/level-14.hbs public/templates/levels/level-14.hbs
src/templates/levels/level-15.hbs public/templates/levels/level-15.hbs
src/templates/levels/level-16.hbs public/templates/levels/level-16.hbs
src/templates/levels/level-17.hbs public/templates/levels/level-17.hbs
src/templates/levels/level-18.hbs public/templates/levels/level-18.hbs
src/templates/levels/level-19.hbs public/templates/levels/level-19.hbs
src/templates/levels/level-2.hbs public/templates/levels/level-2.hbs
src/templates/levels/level-20.hbs public/templates/levels/level-20.hbs
src/templates/levels/level-3.hbs public/templates/levels/level-3.hbs
src/templates/levels/level-4.hbs public/templates/levels/level-4.hbs
src/templates/levels/level-5.hbs public/templates/levels/level-5.hbs
src/templates/levels/level-6.hbs public/templates/levels/level-6.hbs
src/templates/levels/level-7.hbs public/templates/levels/level-7.hbs
src/templates/levels/level-8.hbs public/templates/levels/level-8.hbs
src/templates/levels/level-9.hbs public/templates/levels/level-9.hbs
src/templates/sheet.hbs public/templates/sheet.hbs
src/templates/tab-link.hbs public/templates/tab-link.hbs
src/templates/tab.hbs public/templates/tab.hbs
src/templates/tabs/tab-effects.hbs public/templates/tabs/tab-effects.hbs
src/templates/tabs/tab-kingdom.hbs public/templates/tabs/tab-kingdom.hbs
src/templates/tabs/tab-relations.hbs public/templates/tabs/tab-relations.hbs
src/templates/tabs/tab-settlements.hbs public/templates/tabs/tab-settlements.hbs
src/templates/tabs/tab-turn.hbs public/templates/tabs/tab-turn.hbs
+14
package-lock.json
··· 8 8 "@league-of-foundry-developers/foundry-vtt-types": "^13.346.0-beta.20250812191140", 9 9 "@sveltejs/vite-plugin-svelte": "^6.2.1", 10 10 "@tsconfig/svelte": "^5.0.5", 11 + "dotenv": "^17.2.3", 11 12 "terser": "^5.44.0", 12 13 "vite": "^7.1.7" 13 14 } ··· 2078 2079 "url": "https://github.com/fb55/domutils?sponsor=1" 2079 2080 } 2080 2081 }, 2082 + "node_modules/dotenv": { 2083 + "version": "17.2.3", 2084 + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", 2085 + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", 2086 + "dev": true, 2087 + "license": "BSD-2-Clause", 2088 + "engines": { 2089 + "node": ">=12" 2090 + }, 2091 + "funding": { 2092 + "url": "https://dotenvx.com" 2093 + } 2094 + }, 2081 2095 "node_modules/dunder-proto": { 2082 2096 "version": "1.0.1", 2083 2097 "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+1
package.json
··· 3 3 "@league-of-foundry-developers/foundry-vtt-types": "^13.346.0-beta.20250812191140", 4 4 "@sveltejs/vite-plugin-svelte": "^6.2.1", 5 5 "@tsconfig/svelte": "^5.0.5", 6 + "dotenv": "^17.2.3", 6 7 "terser": "^5.44.0", 7 8 "vite": "^7.1.7" 8 9 },
+38
config.ts
··· 1 + import dotenv from "dotenv"; 2 + import path from "path"; 3 + 4 + dotenv.config({ path: path.resolve(__dirname, ".env") }); 5 + 6 + interface ENV { 7 + MODULE_DIR: string | undefined; 8 + } 9 + 10 + interface Config { 11 + outdir: string; 12 + } 13 + 14 + const getConfig = (): ENV => { 15 + return { 16 + MODULE_DIR: process.env.MODULE_DIR 17 + }; 18 + } 19 + 20 + const getSanitizedConfig = (config: ENV): Config => { 21 + let outdir: string; 22 + 23 + if (config.MODULE_DIR === undefined) { 24 + outdir = path.join(process.cwd(), "dist"); 25 + } else { 26 + outdir = config.MODULE_DIR; 27 + } 28 + 29 + return { 30 + outdir 31 + } as Config; 32 + } 33 + 34 + const config = getConfig(); 35 + 36 + const sanitizedConfig = getSanitizedConfig(config); 37 + 38 + export default sanitizedConfig;
+36
src/module/data/charter.json
··· 1 + [ 2 + { 3 + "id": "conquest", 4 + "boosts": [ 5 + "loyalty", 6 + "free" 7 + ] 8 + }, 9 + { 10 + "id": "expansion", 11 + "boosts": [ 12 + "culture", 13 + "free" 14 + ] 15 + }, 16 + { 17 + "id": "exploration", 18 + "boosts": [ 19 + "stability", 20 + "free" 21 + ] 22 + }, 23 + { 24 + "id": "grant", 25 + "boosts": [ 26 + "economy", 27 + "free" 28 + ] 29 + }, 30 + { 31 + "id": "open", 32 + "boosts": [ 33 + "free" 34 + ] 35 + } 36 + ]
+56
src/module/data/governments.json
··· 1 + [ 2 + { 3 + "id": "despotism", 4 + "boosts": [ 5 + "stability", 6 + "economy", 7 + "free" 8 + ], 9 + "feat": "crush-dissent" 10 + }, 11 + { 12 + "id": "feudalism", 13 + "boosts": [ 14 + "stability", 15 + "culture", 16 + "free" 17 + ], 18 + "feat": "fortified-fiefs" 19 + }, 20 + { 21 + "id": "oligarchy", 22 + "boosts": [ 23 + "loyalty", 24 + "economy", 25 + "free" 26 + ], 27 + "feat": "insider-trading" 28 + }, 29 + { 30 + "id": "republic", 31 + "boosts": [ 32 + "stability", 33 + "loyalty", 34 + "free" 35 + ], 36 + "feat": "pull-together" 37 + }, 38 + { 39 + "id": "thaumocracy", 40 + "boosts": [ 41 + "economy", 42 + "culture", 43 + "free" 44 + ], 45 + "feat": "practical-magic" 46 + }, 47 + { 48 + "id": "yeomanry", 49 + "boosts": [ 50 + "loyalty", 51 + "culture", 52 + "free" 53 + ], 54 + "feat": "muddle-through" 55 + } 56 + ]
+18
src/module/data/heartland.json
··· 1 + [ 2 + { 3 + "id": "forest-swamp", 4 + "boost": "culture" 5 + }, 6 + { 7 + "id": "hill-plain", 8 + "boost": "loyalty" 9 + }, 10 + { 11 + "id": "lake-river", 12 + "boost": "economy" 13 + }, 14 + { 15 + "id": "mountain-ruins", 16 + "boost": "stability" 17 + } 18 + ]
src/module/data/charter.json src/data/charter.json
src/module/data/governments.json src/data/governments.json
src/module/data/heartland.json src/data/heartland.json
+30
src/kingdom-sheet.ts
··· 1 + import { Kingdom } from "./kingdom"; 2 + 3 + interface NPCPF2e { 4 + flags: { 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + foundry.documents.collections.Actors.registerSheet("pf2e", KingdomSheet, { 24 + types: [ 25 + "npc" 26 + ], 27 + label: (game as foundry.Game).i18n!.localize("kingdom-homebrew.kingdom-title") 28 + }); 29 + } 30 +
+216
src/kingdom.ts
··· 1 + import * as data from "./data"; 2 + 3 + /** 4 + * A Kingdom structure. 5 + * @typedef {Object} Kingdom 6 + * @property {string} name - The name of the Kingdom 7 + * @property {string} charter - The id of the charter 8 + * @property {string} government - The id of the government 9 + * @property {string} heartland - The id of the heartland 10 + * @property {string[]} boosts - An array of free boosts for the Kingdom 11 + * @property {LeaderInfo} leaders - Leaders of the kingdom. 12 + * @property {string[]} feats - An array of feats for the Kingdom 13 + * @property {number} size - The size of the Kingdom 14 + * @property {ResourceInfo} resourceDice - The resource dice for the Kingdom 15 + * @property {CommodityInfo} commodities - The commodities for the Kingdom 16 + * @property {ResourceInfo} resourcePoints - The resource points for the Kingdom 17 + * @property {ResourceLimitInfo} unrest - The unrest for the Kingdom 18 + * @property {RuinInfo} ruin - The ruin for the Kingdom 19 + * @property {Relation[]} groups - Other groups the Kingdom has relations with 20 + * @property {ResourceLimitInfo} krp - The Kingdom Reputation Points 21 + * @property {string[]} settlements - An array of Scene IDs for the Kingdom's settlements 22 + * @property {number} level - The level of the Kingdom 23 + */ 24 + export class Kingdom { 25 + name: string; 26 + charter: data.Charter; 27 + government: data.Government; 28 + heartland: data.Heartland; 29 + boosts: data.Boost[]; 30 + leaders: LeaderInfo; 31 + feats: string[]; 32 + size: number; 33 + resourceDice: ResourceInfo; 34 + commodities: CommodityInfo; 35 + resourcePoints: ResourceInfo; 36 + unrest: ResourceLimitInfo; 37 + ruin: RuinInfo; 38 + groups: Relation[]; 39 + krp: ResourceLimitInfo; 40 + settlements: string[]; 41 + level: number; 42 + 43 + constructor() { 44 + this.name = ""; 45 + this.level = 0; 46 + this.charter = { 47 + id: "", 48 + boosts: [] 49 + }; 50 + this.government = { 51 + id: "", 52 + boosts: [], 53 + feat: "" 54 + }; 55 + this.heartland = { 56 + id: "", 57 + boost: data.Boost.None 58 + }; 59 + this.boosts = []; 60 + this.leaders = new LeaderInfo(); 61 + this.feats = []; 62 + this.size = 0; 63 + this.resourceDice = new ResourceInfo(); 64 + this.commodities = new CommodityInfo(); 65 + this.resourcePoints = new ResourceInfo(); 66 + this.unrest = new ResourceLimitInfo(); 67 + this.ruin = new RuinInfo(); 68 + this.groups = []; 69 + this.krp = new ResourceLimitInfo(); 70 + this.settlements = []; 71 + } 72 + } 73 + 74 + /** 75 + * Information about a Kingdom's leaders. 76 + * @typedef {Object} LeaderInfo 77 + * @property {string} ruler - The actor ID of the ruler 78 + * @property {string} counselor - The actor ID of the counselor 79 + * @property {string} viceroy - The actor ID of the viceroy 80 + * @property {string} emissary - The actor ID of the emissary 81 + * @property {string} warden - The actor ID of the warden 82 + * @property {stirng} general - The actor ID of the general 83 + * @property {string} magister - The actor ID of the magister 84 + * @property {string} treasurer - The actor ID of the treasurer 85 + */ 86 + export class LeaderInfo { 87 + ruler: string; 88 + counselor: string; 89 + viceroy: string; 90 + emissary: string; 91 + warden: string; 92 + general: string; 93 + magister: string; 94 + treasurer: string; 95 + 96 + constructor() { 97 + this.ruler = ""; 98 + this.counselor = ""; 99 + this.viceroy = ""; 100 + this.emissary = ""; 101 + this.warden = ""; 102 + this.general = ""; 103 + this.magister = ""; 104 + this.treasurer = ""; 105 + } 106 + } 107 + 108 + /** 109 + * Information about a resource. This resource has a Next and Current value. 110 + * @typedef {Object} ResourceInfo 111 + * @property {number} next - The amount to add on the next turn. 112 + * @property {number} current - The current value of this resource. 113 + */ 114 + export class ResourceInfo { 115 + next: number; 116 + current: number; 117 + 118 + constructor() { 119 + this.next = 0; 120 + this.current = 0; 121 + } 122 + } 123 + 124 + /** 125 + * Information about the Kingdom's commodities 126 + * @typedef {Object} CommodityInfo 127 + * @property {ResourceInfo} ore - The amount of Ore the Kingdom has 128 + * @property {ResourceInfo} lumber - The amount of Lumber the Kingdom has 129 + * @property {ResourceInfo} stone - The amount of Stone the Kingdom has 130 + * @property {ResourceInfo} food - The amount of Food the Kingdom has 131 + * @property {ResourceInfo} luxuries - The amount of Luxuries the Kingdom has 132 + */ 133 + export class CommodityInfo { 134 + ore: ResourceInfo; 135 + lumber: ResourceInfo; 136 + stone: ResourceInfo; 137 + food: ResourceInfo; 138 + luxuries: ResourceInfo; 139 + 140 + constructor() { 141 + this.ore = new ResourceInfo(); 142 + this.lumber = new ResourceInfo(); 143 + this.stone = new ResourceInfo(); 144 + this.food = new ResourceInfo(); 145 + this.luxuries = new ResourceInfo(); 146 + } 147 + } 148 + 149 + /** 150 + * Information about a resource. This resource has Next, Current, and Threshold values. 151 + * @typedef {Object} ResourceLimitInfo 152 + * @property {number} next - The amount to add on the next turn. 153 + * @property {number} current - The current value of this resource. 154 + * @property {number} threshold - The maximum value of this resource. 155 + */ 156 + export class ResourceLimitInfo { 157 + next: number; 158 + current: number; 159 + threshold: number; 160 + 161 + constructor() { 162 + this.next = 0; 163 + this.current = 0; 164 + this.threshold = 0; 165 + } 166 + } 167 + 168 + /** 169 + * Information about the Kingdom's Ruin values. 170 + * @typedef {Object} RuinInfo 171 + * @property {ResourceLimitInfo} corruption - The amount of Corruption a Kingdom has 172 + * @property {ResourceLimitInfo} crime - The amount of Crime a Kingdom has 173 + * @property {ResourceLimitInfo} decay - The amount of Decay a Kingdom has 174 + * @property {ResourceLimitInfo} strife - The amount of Strife a Kingdom has 175 + */ 176 + export class RuinInfo { 177 + corruption: ResourceLimitInfo; 178 + crime: ResourceLimitInfo; 179 + decay: ResourceLimitInfo; 180 + strife: ResourceLimitInfo; 181 + 182 + constructor() { 183 + this.corruption = new ResourceLimitInfo(); 184 + this.crime = new ResourceLimitInfo(); 185 + this.decay = new ResourceLimitInfo(); 186 + this.strife = new ResourceLimitInfo(); 187 + } 188 + } 189 + 190 + /** 191 + * Information about a relation with another group the Kingdom has. 192 + * @typedef {Object} Relation 193 + * @property {string} name - The name of the group 194 + * @property {string} relation - The type of relation the Kingdom has with this group 195 + * @property {number} dc - The base Negotiation DC for this group 196 + * @property {boolean} atWar - Is the Kingdom at war with this group? 197 + */ 198 + export class Relation { 199 + name: string; 200 + relation: RelationType; 201 + dc: number; 202 + atWar: boolean; 203 + 204 + constructor() { 205 + this.name = ""; 206 + this.relation = RelationType.None; 207 + this.dc = 0; 208 + this.atWar = false; 209 + } 210 + } 211 + 212 + export enum RelationType { 213 + None = "none", 214 + TradeAgreement = "tradeAgreement", 215 + DiplomaticRelations = "diplomaticRelations" 216 + }
+17
src/main.ts
··· 1 + import KingdomSheet from "./kingdom-sheet"; 2 + import preloadTemplates from "./preloadTemplates"; 3 + import type { Socket, isocketlib } from "./utils"; 4 + 5 + declare var socketlib: isocketlib; 6 + 7 + let socket: Socket; 8 + 9 + Hooks.on("init", async (): Promise<void> => { 10 + KingdomSheet.register(); 11 + await preloadTemplates(); 12 + console.log("Kingdom Homebrew loaded"); 13 + }); 14 + 15 + Hooks.once("socketlib.ready", (): void => { 16 + socket = socketlib.registerModule("kingdom-homebrew"); 17 + });
+5
src/preloadTemplates.ts
··· 1 + import templateMap from "./templateMap.json"; 2 + 3 + export default function preloadTemplates() { 4 + return foundry.applications.handlebars.loadTemplates(templateMap as Record<string, string>); 5 + }
src/data/governments.json src/data/government.json
+42
src/data/index.ts
··· 1 + import charters from "./charter.json"; 2 + import governments from "./government.json"; 3 + import heartlands from "./heartland.json"; 4 + 5 + export interface Charter { 6 + id: string; 7 + boosts: Boost[]; 8 + } 9 + 10 + export interface Government { 11 + id: string; 12 + boosts: Boost[]; 13 + feat: string; 14 + } 15 + 16 + export interface Heartland { 17 + id: string; 18 + boost: Boost; 19 + } 20 + 21 + export enum Attribute { 22 + Loyalty = "loyalty", 23 + Culture = "culture", 24 + Stability = "stability", 25 + Economy = "economy", 26 + None = "" 27 + } 28 + 29 + export enum Boost { 30 + Loyalty = "loyalty", 31 + Culture = "culture", 32 + Stability = "stability", 33 + Economy = "economy", 34 + None = "", 35 + Free = "free" 36 + } 37 + 38 + export const data = { 39 + charters, 40 + governments, 41 + heartlands 42 + };
+2 -1
tsconfig.json
··· 16 16 "node" 17 17 ], 18 18 "allowUmdGlobalAccess": true, 19 - "strict": true 19 + "strict": true, 20 + "resolveJsonModule": true 20 21 }, 21 22 "include": [ 22 23 "src/**/*"
+14
src/utils.ts
··· 1 + export interface isocketlib { 2 + registerModule: (moduleName: string) => Socket 3 + } 4 + 5 + export interface Socket { 6 + register: (name: string, func: (...args: any[]) => any) => void, 7 + executeAsGM: (handler: string, ...args: any[]) => Promise<any>, 8 + executeAsUser: (handler: string, userId: string, ...parameters: any[]) => Promise<any>, 9 + executeForAllGMs: (handler: string, ...parameters: any[]) => Promise<any>, 10 + executeForOtherGMs: (handler: string, ...parameters: any[]) => Promise<any>, 11 + executeForEveryone: (handler: string, ...args: any[]) => Promise<any>, 12 + executeForOthers: (handler: string, ...args: any[]) => Promise<any>, 13 + executeForUsers: (handler: string, recipients: string[], ...parameters: any[]) => Promise<any> 14 + }
+3
src/templateMap.json
··· 1 + { 2 + "kmhb-sheet": "modules/kingdom-homebrew/templates/sheet.hbs" 3 + }

History

1 round 1 comment
sign up or login to add to the discussion
18 commits
expand
Moving static files to public folder to be automatically copied to out
Changing module filename to support new filename
Adding sourcemap generation
Adding dotenv build dependency
Adding config loading to change module directory to folder in Foundry folder
Adding in stock data
Moving files out of unnecessary module folder
Adding JSDoc info for the Kingdom class
Renaming governments data file to match naming convention of other files
Adding data into code
Enabling resolving json as modules
Adding in Kingdom data
Adding kingdom classes
Adding some utils to interface typescript with socketlib module
Adding types to socket
Working on registering templates
Fixing some issues with loading socketlib
Fixing label for Kingdom Sheet not showing
expand 1 comment

lol I don't know how to work pulls on here yet

closed without merging