diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..730309d3 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +FOUNDRY_MAIN_PATH=/path/to/foundry/resources/app/main.js +FOUNDRY_DATA_PATH=/path/to/foundry/data \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 938abe7c..71d48111 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,10 +1,10 @@ --- name: Bug report -about: Create a report to help us improve -title: "[BUG] - " +about: Create a bug report to help us identify issues and resolve them +title: "[Bug] " labels: bug +type: bug assignees: '' - --- **Describe the bug** @@ -24,11 +24,11 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Setup Information:** - - OS: [e.g. iOS] + - OS: [e.g. iOS, Windows] - Browser [e.g. chrome, safari] - Foundry Version [e.g. v13 b342] -- System Version [e.g. main-3593f44] +- System Version [e.g. v.1.0, v.1.0.1] **Additional context** -Add any other context about the problem here. +Add any other context about the problem here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_report.md b/.github/ISSUE_TEMPLATE/feature_report.md new file mode 100644 index 00000000..df00ba37 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_report.md @@ -0,0 +1,14 @@ +--- +name: Feature report +about: Create a feature report for suggestions on improving the system +title: "[Feature] " +labels: enhancement, discussion, maybe +type: feature +assignees: '' +--- + +**Description** +A clear and concise description of what feature needs to be implemented. + +**Screenshots** +If applicable, add screenshots to help explain the feature that needs to be implemented. \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE/community_pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/community_pull_request_template.md new file mode 100644 index 00000000..25812870 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/community_pull_request_template.md @@ -0,0 +1,55 @@ +--- +name: Pull Request +about: Create a new pull request +title: "[Community PR] " +labels: community pr +assignees: '' +--- +## Description + +Please include a summary of the change and which issue is fixed (if applicable). Also include relevant context or motivation for the change. + +- Fixes #(issue) +- Closes #(issue) + +## Type of Change + +Please check the relevant options: + +- [ ] Bug fix +- [ ] New feature +- [ ] Code cleanup/refactor +- [ ] Documentation update +- [ ] Test coverage +- [ ] Dependency update +- [ ] Configuration change +- [ ] Other (please describe): + +## How Has This Been Tested? + +Please describe the tests you ran to verify your changes: + +- [ ] Manual testing +- [ ] Other: + +## Screenshots (if applicable) + +Include screenshots or GIFs to help explain your changes visually. + +## Checklist + +- [ ] My code follows the project style guidelines +- [ ] I have performed a self-review of my code +- [ ] I have commented my code where necessary +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings or errors +- [ ] I have added tests that prove my fix or feature works +- [ ] New and existing tests pass locally with my changes + +## Additional Comments + +Add any other context or questions here. + +--- + +> Thank you for your contribution! 🎉 diff --git a/.gitignore b/.gitignore index 264581a4..9a22c0ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode +.env node_modules /packs Build diff --git a/README.md b/README.md index fda78b4b..0c2dabc3 100644 --- a/README.md +++ b/README.md @@ -24,24 +24,41 @@ You can find the documentation here: https://github.com/Foundryborne/daggerheart ## Development Setup -- Open a terminal in the directory with the repo `cd //` -- NOTE: The repo should be placed in the system files are or somewhere else and a link (if on linux) is placed in the system directory -- NOTE: Linux link can be made using `ln -snf daggerheart` inside the system folder -- Install npm `npm install` -- Update package.json to match your profile +1. **Navigate to the repo directory:** -``` -"start": "concurrently \"rollup -c --watch\" \"node C:/FoundryDev/resources/app/main.js --dataPath=C:/FoundryDevFiles --noupnp\" \"gulp\"", -"start-test": "node C:/FoundryDev/resources/app/main.js --dataPath=C:/FoundryDevFiles && rollup -c --watch && gulp", + ```bash + cd // + ``` -``` +2. **Install dependencies:** -- Replace `C:/FoundryDev/resources/app/main.js` with `////` -- The main is likely in `/resouces/app/main.js` -- Replace `--dataPath=C:/FoundryDevFiles` with `////` + ```bash + npm install + ``` -Now you should be able to build the app using `npm start` -[Foundry VTT Website][1] +3. **Configure your Foundry paths:** + + ```bash + npm run setup:dev -- --foundry-path="/path/to/foundry/main.js" --data-path="/path/to/data" + ``` + +4. **Start developing:** + ```bash + npm start + ``` + +### Available Scripts + +- `npm start` - Start development with file watching and Foundry launching +- `npm run build` - One-time build +- `npm run setup:dev -- --foundry-path="" --data-path=""` - Configure development environment + +### Notes + +- The repo should be placed in your Foundry `Data/systems/` directory or symlinked there +- Linux symlink can be made using `ln -snf daggerheart` inside the systems folder +- Your `.env` file is ignored by git, so each developer can have their own configuration + [Foundry VTT Website][1] [1]: https://foundryvtt.com/ diff --git a/daggerheart.mjs b/daggerheart.mjs index a2f41735..795764cc 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -8,7 +8,7 @@ import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs'; import { enricherConfig, enricherRenderSetup } from './module/enrichers/_module.mjs'; import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs'; import { NarrativeCountdowns } from './module/applications/ui/countdowns.mjs'; -import { DHRoll, DualityRoll, D20Roll, DamageRoll } from './module/dice/_module.mjs'; +import { BaseRoll, DHRoll, DualityRoll, D20Roll, DamageRoll } from './module/dice/_module.mjs'; import { enrichedDualityRoll } from './module/enrichers/DualityRollEnricher.mjs'; import { registerCountdownHooks } from './module/data/countdowns.mjs'; import { @@ -49,9 +49,7 @@ Hooks.once('init', () => { DamageRoll: DamageRoll }; - CONFIG.Dice.rolls = [...CONFIG.Dice.rolls, DHRoll, DualityRoll, D20Roll, DamageRoll]; - Roll.CHAT_TEMPLATE = 'systems/daggerheart/templates/ui/chat/foundryRoll.hbs'; - Roll.TOOLTIP_TEMPLATE = 'systems/daggerheart/templates/ui/chat/foundryRollTooltip.hbs'; + CONFIG.Dice.rolls = [BaseRoll, DHRoll, DualityRoll, D20Roll, DamageRoll]; CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate; const { DocumentSheetConfig } = foundry.applications.apps; diff --git a/lang/en.json b/lang/en.json index 17605f40..7daf6b14 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1985,7 +1985,7 @@ "true": "True", "type": "Type", "unarmed": "Unarmed", - "unarmedStrike": "Unarmed Strike", + "unarmedAttack": "Unarmed Attack", "unarmored": "Unarmored", "use": "Use", "used": "Used", diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index c128b648..b0fc5fb4 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -60,6 +60,7 @@ export default class AdversarySheet extends DHBaseActorSheet { htmlElement.querySelectorAll('.inventory-item-resource').forEach(element => { element.addEventListener('change', this.updateItemResource.bind(this)); + element.addEventListener('click', e => e.stopPropagation()); }); } diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 481c745e..4f7d947b 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -114,6 +114,7 @@ export default class CharacterSheet extends DHBaseActorSheet { htmlElement.querySelectorAll('.inventory-item-resource').forEach(element => { element.addEventListener('change', this.updateItemResource.bind(this)); + element.addEventListener('click', e => e.stopPropagation()); }); htmlElement.querySelectorAll('.inventory-item-quantity').forEach(element => { element.addEventListener('change', this.updateItemQuantity.bind(this)); @@ -638,7 +639,7 @@ export default class CharacterSheet extends DHBaseActorSheet { ability: abilityLabel }) }); - + this.consumeResource(result?.costs); } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 83dc1581..ab1c9ab2 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -121,7 +121,7 @@ export default function DHApplicationMixin(Base) { } } ], - dragDrop: [], + dragDrop: [{ dragSelector: '.inventory-item[data-type="effect"]', dropSelector: null }], tagifyConfigs: [] }; @@ -249,14 +249,37 @@ export default function DHApplicationMixin(Base) { * @param {DragEvent} event * @protected */ - _onDragStart(event) {} + async _onDragStart(event) { + const inventoryItem = event.currentTarget.closest('.inventory-item'); + if (inventoryItem) { + const { type, itemUuid } = inventoryItem.dataset; + if (type === 'effect') { + const effect = await foundry.utils.fromUuid(itemUuid); + const effectData = { + type: 'ActiveEffect', + data: { ...effect.toObject(), _id: null }, + fromInternal: this.document.uuid + }; + event.dataTransfer.setData('text/plain', JSON.stringify(effectData)); + event.dataTransfer.setDragImage(inventoryItem.querySelector('img'), 60, 0); + } + } + } /** * Handle drop event. * @param {DragEvent} event * @protected */ - _onDrop(event) {} + _onDrop(event) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.fromInternal === this.document.uuid) return; + + if (data.type === 'ActiveEffect') { + this.document.createEmbeddedDocuments('ActiveEffect', [data.data]); + } + } /* -------------------------------------------- */ /* Context Menu */ diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index 67cec44f..2535142f 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -195,6 +195,8 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { }; event.dataTransfer.setData('text/plain', JSON.stringify(attackData)); event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0); + } else if (this.document.type !== 'environment') { + super._onDragStart(event); } } } diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index a9d3237d..9d7df6ee 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -252,6 +252,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { }; event.dataTransfer.setData('text/plain', JSON.stringify(actionData)); event.dataTransfer.setDragImage(actionItem.querySelector('img'), 60, 0); + } else { + super._onDragStart(event); } } } @@ -261,6 +263,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { * @param {DragEvent} event - The drag event */ async _onDrop(event) { + super._onDrop(event); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); if (data.fromInternal) return; diff --git a/module/applications/sheets/api/item-attachment-sheet.mjs b/module/applications/sheets/api/item-attachment-sheet.mjs index 73c39923..2898f5ac 100644 --- a/module/applications/sheets/api/item-attachment-sheet.mjs +++ b/module/applications/sheets/api/item-attachment-sheet.mjs @@ -41,7 +41,7 @@ export default function ItemAttachmentSheet(Base) { } async _onDrop(event) { - const data = TextEditor.getDragEventData(event); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const attachmentsSection = event.target.closest('.attachments-section'); if (!attachmentsSection) return super._onDrop(event); diff --git a/module/applications/sheets/items/ancestry.mjs b/module/applications/sheets/items/ancestry.mjs index c7796f9a..8c0a5620 100644 --- a/module/applications/sheets/items/ancestry.mjs +++ b/module/applications/sheets/items/ancestry.mjs @@ -27,6 +27,9 @@ export default class AncestrySheet extends DHHeritageSheet { * @param {DragEvent} event - The drag event */ async _onDrop(event) { + const data = TextEditor.getDragEventData(event); + if (data.type === 'ActiveEffect') return super._onDrop(event); + const target = event.target.closest('fieldset.drop-section'); const typeField = this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature']; diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index 79a689d8..01f4249a 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -115,16 +115,17 @@ export default class ClassSheet extends DHBaseItemSheet { async _onDrop(event) { event.stopPropagation(); const data = TextEditor.getDragEventData(event); - const item = await fromUuid(data.uuid); + const item = data.data ?? (await fromUuid(data.uuid)); + const itemType = data.data ? data.type : item.type; const target = event.target.closest('fieldset.drop-section'); - if (item.type === 'subclass') { + if (itemType === 'subclass') { await this.document.update({ 'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid] }); - } else if (item.type === 'feature') { + } else if (['feature', 'ActiveEffect'].includes(itemType)) { super._onDrop(event); } else if (this.document.parent?.type !== 'character') { - if (item.type === 'weapon') { + if (itemType === 'weapon') { if (target.classList.contains('primary-weapon-section')) { if (!item.system.secondary) await this.document.update({ @@ -136,21 +137,21 @@ export default class ClassSheet extends DHBaseItemSheet { 'system.characterGuide.suggestedSecondaryWeapon': item.uuid }); } - } else if (item.type === 'armor') { + } else if (itemType === 'armor') { if (target.classList.contains('armor-section')) { await this.document.update({ 'system.characterGuide.suggestedArmor': item.uuid }); } } else if (target.classList.contains('choice-a-section')) { - if (item.type === 'loot' || item.type === 'consumable') { + if (itemType === 'loot' || itemType === 'consumable') { const filteredChoiceA = this.document.system.inventory.choiceA; if (filteredChoiceA.length < 2) await this.document.update({ 'system.inventory.choiceA': [...filteredChoiceA.map(x => x.uuid), item.uuid] }); } - } else if (item.type === 'loot') { + } else if (itemType === 'loot') { if (target.classList.contains('take-section')) { const filteredTake = this.document.system.inventory.take.filter(x => x); if (filteredTake.length < 3) diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 8b4b12d3..a80974ed 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -108,7 +108,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo async onRollDamage(event, message) { event.stopPropagation(); const actor = await this.getActor(message.system.source.actor); - if (game.user.character?.id !== actor.id && !game.user.isGM) return true; + if(!actor.isOwner) return true; if (message.system.source.item && message.system.source.action) { const action = this.getAction(actor, message.system.source.item, message.system.source.action); if (!action || !action?.rollDamage) return; diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 45dfcfc8..bb6a8c65 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -95,7 +95,7 @@ export default class DhCharacter extends BaseDataActor { }), attack: new ActionField({ initial: { - name: 'Unarmed Attack', + name: 'DAGGERHEART.GENERAL.unarmedAttack', img: 'icons/skills/melee/unarmed-punch-fist-yellow-red.webp', _id: foundry.utils.randomID(), systemPath: 'attack', diff --git a/module/dice/_module.mjs b/module/dice/_module.mjs index f34f32d3..e6755a74 100644 --- a/module/dice/_module.mjs +++ b/module/dice/_module.mjs @@ -1,3 +1,4 @@ +export { default as BaseRoll } from './baseRoll.mjs'; export { default as D20Roll } from './d20Roll.mjs'; export { default as DamageRoll } from './damageRoll.mjs'; export { default as DHRoll } from './dhRoll.mjs'; diff --git a/module/dice/baseRoll.mjs b/module/dice/baseRoll.mjs new file mode 100644 index 00000000..4d065fff --- /dev/null +++ b/module/dice/baseRoll.mjs @@ -0,0 +1,7 @@ +export default class BaseRoll extends Roll { + /** @inheritdoc */ + static CHAT_TEMPLATE = 'systems/daggerheart/templates/ui/chat/foundryRoll.hbs'; + + /** @inheritdoc */ + static TOOLTIP_TEMPLATE = 'systems/daggerheart/templates/ui/chat/foundryRollTooltip.hbs'; +} diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index baf4ca17..a51686e6 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -13,6 +13,10 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { /* We can change to fully implementing the renderHTML function if needed, instead of augmenting it. */ const html = await super.renderHTML({ actor: actorData, author: this.author }); + if (this.flags.core?.RollTable) { + html.querySelector('.roll-buttons.apply-buttons').remove(); + } + this.enrichChatMessage(html); this.addChatListeners(html); @@ -54,26 +58,44 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { e.setAttribute('data-use-perm', document.testUserPermission(game.user, 'OWNER')); }); - if (this.isContentVisible && this.type === 'dualityRoll') { - html.classList.add('duality'); - switch (this.system.roll?.result?.duality) { - case 1: - html.classList.add('hope'); - break; - case -1: - html.classList.add('fear'); - break; - default: - html.classList.add('critical'); - break; + if (this.isContentVisible) { + if (this.type === 'dualityRoll') { + html.classList.add('duality'); + switch (this.system.roll?.result?.duality) { + case 1: + html.classList.add('hope'); + break; + case -1: + html.classList.add('fear'); + break; + default: + html.classList.add('critical'); + break; + } } + + const autoExpandRoll = game.settings.get( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.appearance + ).expandRollMessage, + rollSections = html.querySelectorAll('.roll-part'), + itemDesc = html.querySelector('.domain-card-move'); + rollSections.forEach(s => { + if (s.classList.contains('roll-section')) { + const toExpand = s.querySelector('[data-action="expandRoll"]'); + toExpand.classList.toggle('expanded', autoExpandRoll.roll); + } else if (s.classList.contains('damage-section')) + s.classList.toggle('expanded', autoExpandRoll.damage); + else if (s.classList.contains('target-section')) s.classList.toggle('expanded', autoExpandRoll.target); + }); + if (itemDesc && autoExpandRoll.desc) itemDesc.setAttribute('open', ''); } - - if(!game.user.isGM) { - const applyButtons = html.querySelector(".apply-buttons"); + + if (!game.user.isGM) { + const applyButtons = html.querySelector('.apply-buttons'); applyButtons?.remove(); - if(!this.isAuthor && !this.speakerActor?.isOwner) { - const buttons = html.querySelectorAll(".ability-card-footer > .ability-use-button"); + if (!this.isAuthor && !this.speakerActor?.isOwner) { + const buttons = html.querySelectorAll('.ability-card-footer > .ability-use-button'); buttons.forEach(b => b.remove()); } } diff --git a/module/documents/item.mjs b/module/documents/item.mjs index fb558e8c..8492f068 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -28,6 +28,14 @@ export default class DHItem extends foundry.documents.Item { return doc; } + /* -------------------------------------------- */ + + /** @inheritDoc */ + static migrateData(source) { + if(source.system?.attack && !source.system.attack.type) source.system.attack.type = "attack"; + return super.migrateData(source); + } + /** * @inheritdoc * @param {object} options - Options which modify the getRollData method. diff --git a/package.json b/package.json index 023ccff2..dbece0c7 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "rollup": "^4.40.0" }, "scripts": { - "start": "concurrently \"rollup -c --watch\" \"node ../../../../FoundryDev/main.js --dataPath=../../../ --noupnp\" \"gulp\"", + "start": "node ./tools/run-start.mjs", "start-test": "node ./resources/app/main.js --dataPath=./ && rollup -c --watch && gulp", "build": "npm run rollup && npm run gulp", "rollup": "rollup -c", @@ -16,7 +16,8 @@ "pushLDBtoYML": "node ./tools/pushLDBtoYML.mjs", "pullYMLtoLDB": "node ./tools/pullYMLtoLDB.mjs", "pullYMLtoLDBBuild": "node ./tools/pullYMLtoLDBBuild.mjs", - "createSymlink": "node ./tools/create-symlink.mjs" + "createSymlink": "node ./tools/create-symlink.mjs", + "setup:dev": "node ./tools/dev-setup.mjs" }, "devDependencies": { "@foundryvtt/foundryvtt-cli": "^1.0.2", diff --git a/pull_request_template.md b/pull_request_template.md index 194ce9f4..c1b8cbfa 100644 --- a/pull_request_template.md +++ b/pull_request_template.md @@ -1,3 +1,12 @@ +--- +name: Pull Request +about: Create a new pull request +title: "[PR] " +labels: pr +assignees: '' +--- +Is this a community PR? Please go to preview tab and click [here](?expand=1&template=community_pull_request_template.md). If not, delete this line. + ## Description Please include a summary of the change and which issue is fixed (if applicable). Also include relevant context or motivation for the change. diff --git a/templates/ui/chat/foundryRoll.hbs b/templates/ui/chat/foundryRoll.hbs index a3c55a9e..8fc62219 100644 --- a/templates/ui/chat/foundryRoll.hbs +++ b/templates/ui/chat/foundryRoll.hbs @@ -8,7 +8,9 @@

{{total}}

-
- - -
\ No newline at end of file +{{#unless flags.core.RollTable}} +
+ + +
+{{/unless}} \ No newline at end of file diff --git a/tools/dev-setup.mjs b/tools/dev-setup.mjs new file mode 100644 index 00000000..f232f5a8 --- /dev/null +++ b/tools/dev-setup.mjs @@ -0,0 +1,18 @@ +#!/usr/bin/env node +import fs from 'fs'; + +const args = process.argv.slice(2); +const foundryPath = args.find(arg => arg.startsWith('--foundry-path='))?.split('=')[1]; +const dataPath = args.find(arg => arg.startsWith('--data-path='))?.split('=')[1]; + +if (!foundryPath || !dataPath) { + console.log('Usage: npm run setup:dev -- --foundry-path="/path/to/foundry/main.js" --data-path="/path/to/data"'); + process.exit(1); +} + +const envContent = `FOUNDRY_MAIN_PATH=${foundryPath} +FOUNDRY_DATA_PATH=${dataPath} +`; + +fs.writeFileSync('.env', envContent); +console.log(`✅ Development environment configured: ${foundryPath}, ${dataPath}`); diff --git a/tools/run-start.mjs b/tools/run-start.mjs new file mode 100644 index 00000000..e620d13f --- /dev/null +++ b/tools/run-start.mjs @@ -0,0 +1,27 @@ +#!/usr/bin/env node +import { spawn } from 'child_process'; +import fs from 'fs'; + +// Load .env file if it exists +if (fs.existsSync('.env')) { + const envFile = fs.readFileSync('.env', 'utf8'); + envFile.split('\n').forEach(line => { + const [key, value] = line.split('='); + if (key && value) { + process.env[key] = value; + } + }); +} + +// Set defaults if not in environment +const foundryPath = process.env.FOUNDRY_MAIN_PATH || '../../../../FoundryDev/main.js'; +const dataPath = process.env.FOUNDRY_DATA_PATH || '../../../'; + +// Run the original command with proper environment +const args = ['rollup -c --watch', `node "${foundryPath}" --dataPath="${dataPath}" --noupnp`, 'gulp']; + +spawn('npx', ['concurrently', ...args.map(arg => `"${arg}"`)], { + stdio: 'inherit', + cwd: process.cwd(), + shell: true +});