Merge branch 'main' into compendium-init

This commit is contained in:
CPTN Cosmo 2025-05-23 16:42:18 +02:00 committed by GitHub
commit 88ba9d2c71
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 754 additions and 2794 deletions

33
README.md Normal file
View file

@ -0,0 +1,33 @@
# Daggerheart
#### For Foundry VTT
This is a repo for a Foundry VTT implementation of daggerheart. It is not associated with critical role
or darrington press.
# Table Of Contents
- [Overview](#overview)
- [Developer Guide](#developer-guide)
# Overview
# Developer Guide
#### Setup
- Open a terminal in the directory with the repo `cd <path>/<to>/<repo>`
- 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
```
"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",
```
- Replace `C:/FoundryDev/resources/app/main.js` with `<your>/<path>/<to>/<foundry>/<main.js>`
- The main is likely in `<Foundry Install Location>/resouces/app/main.js`
- Replace `--dataPath=C:/FoundryDevFiles` with `<your>/<path>/<to>/<foundry>/<data>`
Now you should be able to build the app using `npm start`
[Foundry VTT Website][1]
[1]: https://foundryvtt.com/

View file

@ -1,7 +1,7 @@
export default class DhpChatMesssage extends ChatMessage { export default class DhpChatMesssage extends ChatMessage {
async renderHTML() { async renderHTML() {
if(this.type === 'dualityRoll' || this.type === 'adversaryRoll' || this.type === 'abilityUse'){ if(this.type === 'dualityRoll' || this.type === 'adversaryRoll' || this.type === 'abilityUse'){
this.content = await renderTemplate(this.content, this.system); this.content = await foundry.applications.handlebars.renderTemplate(this.content, this.system);
} }
return super.renderHTML(); return super.renderHTML();

View file

@ -21,6 +21,10 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
id: "daggerheart-levelup", id: "daggerheart-levelup",
classes: ["daggerheart", "views", "levelup"], classes: ["daggerheart", "views", "levelup"],
position: { width: 1200, height: 'auto' }, position: { width: 1200, height: 'auto' },
window: {
resizable: true,
},
actions: { actions: {
toggleBox: this.toggleBox, toggleBox: this.toggleBox,
advanceLevel: this.advanceLevel, advanceLevel: this.advanceLevel,

View file

@ -64,6 +64,17 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
useAdvancementAbility: this.useAdvancementAbility, useAdvancementAbility: this.useAdvancementAbility,
selectFeatureSet: this.selectFeatureSet, selectFeatureSet: this.selectFeatureSet,
}, },
window: {
//frame: boolean;
//positioned: boolean;
//title: string;
//icon: string | false;
//controls: ApplicationHeaderControlsEntry[];
minimizable: false,
resizable: true
//contentTag: string;
//contentClasses: string[];
},
form: { form: {
handler: this.updateForm, handler: this.updateForm,
submitOnChange: true, submitOnChange: true,
@ -320,11 +331,11 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
this.render(); this.render();
} }
static async rollAttribute(_, event){ static async rollAttribute(event, target) {
const { roll, hope, fear, advantage, disadvantage, modifiers } = await this.document.dualityRoll({ title: 'Attribute Bonus', value: event.currentTarget.dataset.value }, event.shiftKey); const { roll, hope, fear, advantage, disadvantage, modifiers } = await this.document.dualityRoll({ title: 'Attribute Bonus', value: event.target.dataset.value }, event.shiftKey);
const cls = getDocumentClass("ChatMessage"); const cls = getDocumentClass("ChatMessage");
const msg = new cls({ const msgData = {
type: 'dualityRoll', type: 'dualityRoll',
system: { system: {
roll: roll._formula, roll: roll._formula,
@ -337,9 +348,9 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
user: game.user.id, user: game.user.id,
content: "systems/daggerheart/templates/chat/duality-roll.hbs", content: "systems/daggerheart/templates/chat/duality-roll.hbs",
rolls: [roll] rolls: [roll]
}); };
await cls.create(msg.toObject()); await cls.create(msgData);
} }
static async toggleMarks(_, button){ static async toggleMarks(_, button){

View file

@ -3,7 +3,7 @@ export default class DhpArmor extends foundry.abstract.TypeDataModel {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
baseScore: new fields.NumberField({ initial: 1, integer: true }), baseScore: new fields.NumberField({ initial: 1, integer: true }),
feature: new fields.StringField({ choices: SYSTEM.ITEM.armorFeatures, integer: false }), feature: new fields.StringField({ choices: SYSTEM.ITEM.armorFeatures, integer: false, blank:true}),
marks: new fields.SchemaField({ marks: new fields.SchemaField({
max: new fields.NumberField({ initial: 6, integer: true }), max: new fields.NumberField({ initial: 6, integer: true }),
value: new fields.NumberField({ initial: 0, integer: true }), value: new fields.NumberField({ initial: 0, integer: true }),

View file

@ -12,7 +12,7 @@ export default class DhpWeapon extends foundry.abstract.TypeDataModel {
type: new fields.StringField({ choices: SYSTEM.GENERAL.damageTypes, integer: false }), type: new fields.StringField({ choices: SYSTEM.GENERAL.damageTypes, integer: false }),
}), }),
burden: new fields.StringField({ choices: SYSTEM.GENERAL.burden, integer: false }), burden: new fields.StringField({ choices: SYSTEM.GENERAL.burden, integer: false }),
feature: new fields.StringField({ choices: SYSTEM.ITEM.weaponFeatures, integer: false }), feature: new fields.StringField({ choices: SYSTEM.ITEM.weaponFeatures, integer: false, blank:true }),
quantity: new fields.NumberField({ initial: 1, integer: true }), quantity: new fields.NumberField({ initial: 1, integer: true }),
description: new fields.HTMLField({}), description: new fields.HTMLField({}),
} }

View file

@ -87,9 +87,10 @@ export default class DhpActor extends Actor {
async dualityRoll(modifier, shiftKey, bonusDamage=[]){ async dualityRoll(modifier, shiftKey, bonusDamage=[]){
let hopeDice = 'd12', fearDice = 'd12', advantageDice = null, disadvantageDice = null, bonusDamageString = ""; let hopeDice = 'd12', fearDice = 'd12', advantageDice = null, disadvantageDice = null, bonusDamageString = "";
const modifiers = [ const modifiers = [
{ {
value: Number.parseInt(modifier.value), value: modifier.value ? Number.parseInt(modifier.value) : 0,
label: modifier.value >= 0 ? `+${modifier.value}` : `-${modifier.value}`, label: modifier.value >= 0 ? `+${modifier.value}` : `-${modifier.value}`,
title: modifier.title, title: modifier.title,
} }
@ -104,11 +105,11 @@ export default class DhpActor extends Actor {
bonusDamageString = result.bonusDamage; bonusDamageString = result.bonusDamage;
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope); const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
if(automateHope && result.hopeUsed){ if(automateHope && result.hopeUsed){
await this.update({ "system.resources.hope.value": this.system.resources.hope.value - result.hopeUsed }); await this.update({ "system.resources.hope.value": this.system.resources.hope.value - result.hopeUsed });
} }
} }
const roll = new Roll(`1${hopeDice} + 1${fearDice}${advantageDice ? ` + 1${advantageDice}` : disadvantageDice ? ` - 1${disadvantageDice}` : ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`); const roll = new Roll(`1${hopeDice} + 1${fearDice}${advantageDice ? ` + 1${advantageDice}` : disadvantageDice ? ` - 1${disadvantageDice}` : ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`);
let rollResult = await roll.evaluate(); let rollResult = await roll.evaluate();
rollResult.dice[0].options.appearance = { rollResult.dice[0].options.appearance = {

3459
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{ {
"dependencies": { "dependencies": {
"@yaireo/tagify": "^4.17.9", "@yaireo/tagify": "^4.17.9",
"gulp": "^4.0.2", "gulp": "^5.0.0",
"gulp-less": "^5.0.0", "gulp-less": "^5.0.0",
"rollup": "^4.40.0" "rollup": "^4.40.0"
}, },
@ -15,8 +15,8 @@
"@foundryvtt/foundryvtt-cli": "^1.0.2", "@foundryvtt/foundryvtt-cli": "^1.0.2",
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"concurrently": "^8.2.2",
"postcss": "^8.4.32", "postcss": "^8.4.32",
"rollup-plugin-postcss": "^4.0.2", "rollup-plugin-postcss": "^4.0.2"
"concurrently": "^8.2.2"
} }
} }

View file

@ -55,12 +55,12 @@
{{#if (eq effect.valueType ../config.valueTypes.select.id)}} {{#if (eq effect.valueType ../config.valueTypes.select.id)}}
<div class="flexrow"> <div class="flexrow">
<select name="system.effects.{{key}}.valueData.fromValue" value="{{effect.valueData.fromValue}}"> <select name="system.effects.{{key}}.valueData.fromValue" value="{{effect.valueData.fromValue}}">
{{selectOptions effect.options selected=effect.valueData.fromValue labelAttr="name" nameAttr="value" localize=true blank="" }} {{selectOptions effect.options selected=effect.valueData.fromValue labelAttr="name" valueAttr="value" localize=true blank="" }}
</select> </select>
</div> </div>
<div class="flexrow"> <div class="flexrow">
<select name="system.effects.{{key}}.valueData.value" value="{{effect.valueData.value}}"> <select name="system.effects.{{key}}.valueData.value" value="{{effect.valueData.value}}">
{{selectOptions effect.options selected=effect.valueData.value labelAttr="name" nameAttr="value" localize=true blank="" }} {{selectOptions effect.options selected=effect.valueData.value labelAttr="name" valueAttr="value" localize=true blank="" }}
</select> </select>
</div> </div>
{{/if}} {{/if}}

View file

@ -19,7 +19,7 @@
<label>Advantage</label> <label>Advantage</label>
<div class="form-fields"> <div class="form-fields">
<select name="advantage" {{#if this.disadvantage}}disabled{{/if}}> <select name="advantage" {{#if this.disadvantage}}disabled{{/if}}>
{{selectOptions this.diceOptions selected=this.advantage nameAttr="value" labelAttr="name" localize=true blank=""}} {{selectOptions this.diceOptions selected=this.advantage valueAttr="value" labelAttr="name" localize=true blank=""}}
</select> </select>
</div> </div>
</div> </div>
@ -27,7 +27,7 @@
<label>Disadvantage</label> <label>Disadvantage</label>
<div class="form-fields"> <div class="form-fields">
<select name="disadvantage" {{#if this.advantage}}disabled{{/if}}> <select name="disadvantage" {{#if this.advantage}}disabled{{/if}}>
{{selectOptions this.diceOptions selected=this.disadvantage nameAttr="value" labelAttr="name" localize=true blank=""}} {{selectOptions this.diceOptions selected=this.disadvantage valueAttr="value" labelAttr="name" localize=true blank=""}}
</select> </select>
</div> </div>
</div> --}} </div> --}}
@ -36,7 +36,7 @@
<label>Hope</label> <label>Hope</label>
<div class="form-fields"> <div class="form-fields">
<select name="hope"> <select name="hope">
{{selectOptions this.diceOptions selected=this.hope nameAttr="value" labelAttr="name" localize=true}} {{selectOptions this.diceOptions selected=this.hope valueAttr="value" labelAttr="name" localize=true}}
</select> </select>
</div> </div>
</div> </div>
@ -44,7 +44,7 @@
<label>Fear</label> <label>Fear</label>
<div class="form-fields"> <div class="form-fields">
<select name="fear"> <select name="fear">
{{selectOptions this.diceOptions selected=this.fear nameAttr="value" labelAttr="name" localize=true}} {{selectOptions this.diceOptions selected=this.fear valueAttr="value" labelAttr="name" localize=true}}
</select> </select>
</div> </div>
</div> </div>