mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-15 21:21:08 +01:00
Merge branch 'main' of https://github.com/Foundryborne/daggerheart
This commit is contained in:
commit
d4056b3c00
27 changed files with 279 additions and 62 deletions
2
.env.example
Normal file
2
.env.example
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
FOUNDRY_MAIN_PATH=/path/to/foundry/resources/app/main.js
|
||||||
|
FOUNDRY_DATA_PATH=/path/to/foundry/data
|
||||||
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -1,10 +1,10 @@
|
||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a report to help us improve
|
about: Create a bug report to help us identify issues and resolve them
|
||||||
title: "[BUG] - "
|
title: "[Bug] <Insert Title here> "
|
||||||
labels: bug
|
labels: bug
|
||||||
|
type: bug
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
**Describe the bug**
|
||||||
|
|
@ -24,10 +24,10 @@ A clear and concise description of what you expected to happen.
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Setup Information:**
|
**Setup Information:**
|
||||||
- OS: [e.g. iOS]
|
- OS: [e.g. iOS, Windows]
|
||||||
- Browser [e.g. chrome, safari]
|
- Browser [e.g. chrome, safari]
|
||||||
- Foundry Version [e.g. v13 b342]
|
- 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**
|
**Additional context**
|
||||||
|
|
|
||||||
14
.github/ISSUE_TEMPLATE/feature_report.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_report.md
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
name: Feature report
|
||||||
|
about: Create a feature report for suggestions on improving the system
|
||||||
|
title: "[Feature] <Insert Title here> "
|
||||||
|
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.
|
||||||
55
.github/PULL_REQUEST_TEMPLATE/community_pull_request_template.md
vendored
Normal file
55
.github/PULL_REQUEST_TEMPLATE/community_pull_request_template.md
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
---
|
||||||
|
name: Pull Request
|
||||||
|
about: Create a new pull request
|
||||||
|
title: "[Community PR] <Insert Title here>"
|
||||||
|
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! 🎉
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,4 +1,5 @@
|
||||||
.vscode
|
.vscode
|
||||||
|
.env
|
||||||
node_modules
|
node_modules
|
||||||
/packs
|
/packs
|
||||||
Build
|
Build
|
||||||
|
|
|
||||||
45
README.md
45
README.md
|
|
@ -24,24 +24,41 @@ You can find the documentation here: https://github.com/Foundryborne/daggerheart
|
||||||
|
|
||||||
## Development Setup
|
## Development Setup
|
||||||
|
|
||||||
- Open a terminal in the directory with the repo `cd <path>/<to>/<repo>`
|
1. **Navigate to the repo directory:**
|
||||||
- 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 <path to development folder> daggerheart` inside the system folder
|
|
||||||
- Install npm `npm install`
|
|
||||||
- Update package.json to match your profile
|
|
||||||
|
|
||||||
```
|
```bash
|
||||||
"start": "concurrently \"rollup -c --watch\" \"node C:/FoundryDev/resources/app/main.js --dataPath=C:/FoundryDevFiles --noupnp\" \"gulp\"",
|
cd <path>/<to>/<repo>
|
||||||
"start-test": "node C:/FoundryDev/resources/app/main.js --dataPath=C:/FoundryDevFiles && rollup -c --watch && gulp",
|
```
|
||||||
|
|
||||||
```
|
2. **Install dependencies:**
|
||||||
|
|
||||||
- Replace `C:/FoundryDev/resources/app/main.js` with `<your>/<path>/<to>/<foundry>/<main.js>`
|
```bash
|
||||||
- The main is likely in `<Foundry Install Location>/resouces/app/main.js`
|
npm install
|
||||||
- Replace `--dataPath=C:/FoundryDevFiles` with `<your>/<path>/<to>/<foundry>/<data>`
|
```
|
||||||
|
|
||||||
Now you should be able to build the app using `npm start`
|
3. **Configure your Foundry paths:**
|
||||||
[Foundry VTT Website][1]
|
|
||||||
|
```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="<path>" --data-path="<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 <path to development folder> 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/
|
[1]: https://foundryvtt.com/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs';
|
||||||
import { enricherConfig, enricherRenderSetup } from './module/enrichers/_module.mjs';
|
import { enricherConfig, enricherRenderSetup } from './module/enrichers/_module.mjs';
|
||||||
import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs';
|
import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs';
|
||||||
import { NarrativeCountdowns } from './module/applications/ui/countdowns.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 { enrichedDualityRoll } from './module/enrichers/DualityRollEnricher.mjs';
|
||||||
import { registerCountdownHooks } from './module/data/countdowns.mjs';
|
import { registerCountdownHooks } from './module/data/countdowns.mjs';
|
||||||
import {
|
import {
|
||||||
|
|
@ -49,9 +49,7 @@ Hooks.once('init', () => {
|
||||||
DamageRoll: DamageRoll
|
DamageRoll: DamageRoll
|
||||||
};
|
};
|
||||||
|
|
||||||
CONFIG.Dice.rolls = [...CONFIG.Dice.rolls, DHRoll, DualityRoll, D20Roll, DamageRoll];
|
CONFIG.Dice.rolls = [BaseRoll, 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.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate;
|
CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate;
|
||||||
|
|
||||||
const { DocumentSheetConfig } = foundry.applications.apps;
|
const { DocumentSheetConfig } = foundry.applications.apps;
|
||||||
|
|
|
||||||
|
|
@ -1985,7 +1985,7 @@
|
||||||
"true": "True",
|
"true": "True",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"unarmed": "Unarmed",
|
"unarmed": "Unarmed",
|
||||||
"unarmedStrike": "Unarmed Strike",
|
"unarmedAttack": "Unarmed Attack",
|
||||||
"unarmored": "Unarmored",
|
"unarmored": "Unarmored",
|
||||||
"use": "Use",
|
"use": "Use",
|
||||||
"used": "Used",
|
"used": "Used",
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ export default class AdversarySheet extends DHBaseActorSheet {
|
||||||
|
|
||||||
htmlElement.querySelectorAll('.inventory-item-resource').forEach(element => {
|
htmlElement.querySelectorAll('.inventory-item-resource').forEach(element => {
|
||||||
element.addEventListener('change', this.updateItemResource.bind(this));
|
element.addEventListener('change', this.updateItemResource.bind(this));
|
||||||
|
element.addEventListener('click', e => e.stopPropagation());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
|
|
||||||
htmlElement.querySelectorAll('.inventory-item-resource').forEach(element => {
|
htmlElement.querySelectorAll('.inventory-item-resource').forEach(element => {
|
||||||
element.addEventListener('change', this.updateItemResource.bind(this));
|
element.addEventListener('change', this.updateItemResource.bind(this));
|
||||||
|
element.addEventListener('click', e => e.stopPropagation());
|
||||||
});
|
});
|
||||||
htmlElement.querySelectorAll('.inventory-item-quantity').forEach(element => {
|
htmlElement.querySelectorAll('.inventory-item-quantity').forEach(element => {
|
||||||
element.addEventListener('change', this.updateItemQuantity.bind(this));
|
element.addEventListener('change', this.updateItemQuantity.bind(this));
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ export default function DHApplicationMixin(Base) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
dragDrop: [],
|
dragDrop: [{ dragSelector: '.inventory-item[data-type="effect"]', dropSelector: null }],
|
||||||
tagifyConfigs: []
|
tagifyConfigs: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -249,14 +249,37 @@ export default function DHApplicationMixin(Base) {
|
||||||
* @param {DragEvent} event
|
* @param {DragEvent} event
|
||||||
* @protected
|
* @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.
|
* Handle drop event.
|
||||||
* @param {DragEvent} event
|
* @param {DragEvent} event
|
||||||
* @protected
|
* @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 */
|
/* Context Menu */
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,8 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||||
};
|
};
|
||||||
event.dataTransfer.setData('text/plain', JSON.stringify(attackData));
|
event.dataTransfer.setData('text/plain', JSON.stringify(attackData));
|
||||||
event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0);
|
event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0);
|
||||||
|
} else if (this.document.type !== 'environment') {
|
||||||
|
super._onDragStart(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
};
|
};
|
||||||
event.dataTransfer.setData('text/plain', JSON.stringify(actionData));
|
event.dataTransfer.setData('text/plain', JSON.stringify(actionData));
|
||||||
event.dataTransfer.setDragImage(actionItem.querySelector('img'), 60, 0);
|
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
|
* @param {DragEvent} event - The drag event
|
||||||
*/
|
*/
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
|
super._onDrop(event);
|
||||||
|
|
||||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
if (data.fromInternal) return;
|
if (data.fromInternal) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export default function ItemAttachmentSheet(Base) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
const data = TextEditor.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
|
|
||||||
const attachmentsSection = event.target.closest('.attachments-section');
|
const attachmentsSection = event.target.closest('.attachments-section');
|
||||||
if (!attachmentsSection) return super._onDrop(event);
|
if (!attachmentsSection) return super._onDrop(event);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ export default class AncestrySheet extends DHHeritageSheet {
|
||||||
* @param {DragEvent} event - The drag event
|
* @param {DragEvent} event - The drag event
|
||||||
*/
|
*/
|
||||||
async _onDrop(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 target = event.target.closest('fieldset.drop-section');
|
||||||
const typeField =
|
const typeField =
|
||||||
this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature'];
|
this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature'];
|
||||||
|
|
|
||||||
|
|
@ -115,16 +115,17 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
async _onDrop(event) {
|
async _onDrop(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const data = TextEditor.getDragEventData(event);
|
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');
|
const target = event.target.closest('fieldset.drop-section');
|
||||||
if (item.type === 'subclass') {
|
if (itemType === 'subclass') {
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid]
|
'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);
|
super._onDrop(event);
|
||||||
} else if (this.document.parent?.type !== 'character') {
|
} else if (this.document.parent?.type !== 'character') {
|
||||||
if (item.type === 'weapon') {
|
if (itemType === 'weapon') {
|
||||||
if (target.classList.contains('primary-weapon-section')) {
|
if (target.classList.contains('primary-weapon-section')) {
|
||||||
if (!item.system.secondary)
|
if (!item.system.secondary)
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
|
|
@ -136,21 +137,21 @@ export default class ClassSheet extends DHBaseItemSheet {
|
||||||
'system.characterGuide.suggestedSecondaryWeapon': item.uuid
|
'system.characterGuide.suggestedSecondaryWeapon': item.uuid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (item.type === 'armor') {
|
} else if (itemType === 'armor') {
|
||||||
if (target.classList.contains('armor-section')) {
|
if (target.classList.contains('armor-section')) {
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.characterGuide.suggestedArmor': item.uuid
|
'system.characterGuide.suggestedArmor': item.uuid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (target.classList.contains('choice-a-section')) {
|
} 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;
|
const filteredChoiceA = this.document.system.inventory.choiceA;
|
||||||
if (filteredChoiceA.length < 2)
|
if (filteredChoiceA.length < 2)
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
'system.inventory.choiceA': [...filteredChoiceA.map(x => x.uuid), item.uuid]
|
'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')) {
|
if (target.classList.contains('take-section')) {
|
||||||
const filteredTake = this.document.system.inventory.take.filter(x => x);
|
const filteredTake = this.document.system.inventory.take.filter(x => x);
|
||||||
if (filteredTake.length < 3)
|
if (filteredTake.length < 3)
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
async onRollDamage(event, message) {
|
async onRollDamage(event, message) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const actor = await this.getActor(message.system.source.actor);
|
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) {
|
if (message.system.source.item && message.system.source.action) {
|
||||||
const action = this.getAction(actor, 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;
|
if (!action || !action?.rollDamage) return;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
}),
|
}),
|
||||||
attack: new ActionField({
|
attack: new ActionField({
|
||||||
initial: {
|
initial: {
|
||||||
name: 'Unarmed Attack',
|
name: 'DAGGERHEART.GENERAL.unarmedAttack',
|
||||||
img: 'icons/skills/melee/unarmed-punch-fist-yellow-red.webp',
|
img: 'icons/skills/melee/unarmed-punch-fist-yellow-red.webp',
|
||||||
_id: foundry.utils.randomID(),
|
_id: foundry.utils.randomID(),
|
||||||
systemPath: 'attack',
|
systemPath: 'attack',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
export { default as BaseRoll } from './baseRoll.mjs';
|
||||||
export { default as D20Roll } from './d20Roll.mjs';
|
export { default as D20Roll } from './d20Roll.mjs';
|
||||||
export { default as DamageRoll } from './damageRoll.mjs';
|
export { default as DamageRoll } from './damageRoll.mjs';
|
||||||
export { default as DHRoll } from './dhRoll.mjs';
|
export { default as DHRoll } from './dhRoll.mjs';
|
||||||
|
|
|
||||||
7
module/dice/baseRoll.mjs
Normal file
7
module/dice/baseRoll.mjs
Normal file
|
|
@ -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';
|
||||||
|
}
|
||||||
|
|
@ -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. */
|
/* 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 });
|
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.enrichChatMessage(html);
|
||||||
this.addChatListeners(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'));
|
e.setAttribute('data-use-perm', document.testUserPermission(game.user, 'OWNER'));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.isContentVisible && this.type === 'dualityRoll') {
|
if (this.isContentVisible) {
|
||||||
html.classList.add('duality');
|
if (this.type === 'dualityRoll') {
|
||||||
switch (this.system.roll?.result?.duality) {
|
html.classList.add('duality');
|
||||||
case 1:
|
switch (this.system.roll?.result?.duality) {
|
||||||
html.classList.add('hope');
|
case 1:
|
||||||
break;
|
html.classList.add('hope');
|
||||||
case -1:
|
break;
|
||||||
html.classList.add('fear');
|
case -1:
|
||||||
break;
|
html.classList.add('fear');
|
||||||
default:
|
break;
|
||||||
html.classList.add('critical');
|
default:
|
||||||
break;
|
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) {
|
if (!game.user.isGM) {
|
||||||
const applyButtons = html.querySelector(".apply-buttons");
|
const applyButtons = html.querySelector('.apply-buttons');
|
||||||
applyButtons?.remove();
|
applyButtons?.remove();
|
||||||
if(!this.isAuthor && !this.speakerActor?.isOwner) {
|
if (!this.isAuthor && !this.speakerActor?.isOwner) {
|
||||||
const buttons = html.querySelectorAll(".ability-card-footer > .ability-use-button");
|
const buttons = html.querySelectorAll('.ability-card-footer > .ability-use-button');
|
||||||
buttons.forEach(b => b.remove());
|
buttons.forEach(b => b.remove());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,14 @@ export default class DHItem extends foundry.documents.Item {
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
static migrateData(source) {
|
||||||
|
if(source.system?.attack && !source.system.attack.type) source.system.attack.type = "attack";
|
||||||
|
return super.migrateData(source);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
* @param {object} options - Options which modify the getRollData method.
|
* @param {object} options - Options which modify the getRollData method.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"rollup": "^4.40.0"
|
"rollup": "^4.40.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"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",
|
"start-test": "node ./resources/app/main.js --dataPath=./ && rollup -c --watch && gulp",
|
||||||
"build": "npm run rollup && npm run gulp",
|
"build": "npm run rollup && npm run gulp",
|
||||||
"rollup": "rollup -c",
|
"rollup": "rollup -c",
|
||||||
|
|
@ -16,7 +16,8 @@
|
||||||
"pushLDBtoYML": "node ./tools/pushLDBtoYML.mjs",
|
"pushLDBtoYML": "node ./tools/pushLDBtoYML.mjs",
|
||||||
"pullYMLtoLDB": "node ./tools/pullYMLtoLDB.mjs",
|
"pullYMLtoLDB": "node ./tools/pullYMLtoLDB.mjs",
|
||||||
"pullYMLtoLDBBuild": "node ./tools/pullYMLtoLDBBuild.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": {
|
"devDependencies": {
|
||||||
"@foundryvtt/foundryvtt-cli": "^1.0.2",
|
"@foundryvtt/foundryvtt-cli": "^1.0.2",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,12 @@
|
||||||
|
---
|
||||||
|
name: Pull Request
|
||||||
|
about: Create a new pull request
|
||||||
|
title: "[PR] <Insert Title here>"
|
||||||
|
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
|
## Description
|
||||||
|
|
||||||
Please include a summary of the change and which issue is fixed (if applicable). Also include relevant context or motivation for the change.
|
Please include a summary of the change and which issue is fixed (if applicable). Also include relevant context or motivation for the change.
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,9 @@
|
||||||
<h4 class="dice-total">{{total}}</h4>
|
<h4 class="dice-total">{{total}}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="roll-buttons apply-buttons">
|
{{#unless flags.core.RollTable}}
|
||||||
<button class="simple-roll-button">{{localize "DAGGERHEART.UI.Chat.damageRoll.dealDamage"}}</button>
|
<div class="roll-buttons apply-buttons">
|
||||||
<button class="simple-roll-button" data-type="healing">{{localize "DAGGERHEART.UI.Chat.healingRoll.applyHealing"}}</button>
|
<button class="simple-roll-button">{{localize "DAGGERHEART.UI.Chat.damageRoll.dealDamage"}}</button>
|
||||||
</div>
|
<button class="simple-roll-button" data-type="healing">{{localize "DAGGERHEART.UI.Chat.healingRoll.applyHealing"}}</button>
|
||||||
|
</div>
|
||||||
|
{{/unless}}
|
||||||
18
tools/dev-setup.mjs
Normal file
18
tools/dev-setup.mjs
Normal file
|
|
@ -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}`);
|
||||||
27
tools/run-start.mjs
Normal file
27
tools/run-start.mjs
Normal file
|
|
@ -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
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue