Adding Prettier

* Added prettier with automatic useage on pre-commit to avoid style breakage
* Ran Prettier on the project
This commit is contained in:
WBHarry 2025-05-23 18:57:50 +02:00 committed by GitHub
parent 820c2df1f4
commit b24cdcc9ed
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
136 changed files with 13929 additions and 12206 deletions

1
.husky/pre-commit Normal file
View file

@ -0,0 +1 @@
npx lint-staged

5
.prettierignore Normal file
View file

@ -0,0 +1,5 @@
node_modules
package-lock.json
package.json
.github
*.hbs

13
.prettierrc Normal file
View file

@ -0,0 +1,13 @@
{
"trailingComma": "none",
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "consistent",
"bracketSpacing": true,
"arrowParens": "avoid",
"printWidth": 120,
"endOfLine": "lf",
"bracketSameLine": true
}

View file

@ -1,27 +1,47 @@
# 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
#### Coding Practises
##### Branches And Pull Requests
During pre-release development, we are making use of `main` as the development branch. Once release is getting closer we will instead be making a `dev` branch to base development from to make `main` more stable.
When you work on an issue or feature, start from `main` and make a new branch. Branches should be topically named and with the associated Issue number if it relates to an Issue. EX: `#6/Level-Up-Bugginess`.
---
Once you're finished with an issue or feature, open a Pull Request on Github for that branch.
The Reviewers Team will be approving submissions. This is mainly since we have a wide spread of experience with system building and the system itself, and we do want the system to become something great. As time goes on, more collaborators are likely to be added as reviewers.
#### 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>`
@ -29,5 +49,4 @@ or darrington press.
Now you should be able to build the app using `npm start`
[Foundry VTT Website][1]
[1]: https://foundryvtt.com/

View file

@ -17,10 +17,13 @@ Hooks.once('init', () => {
game.system.api = {
applications,
models,
documents,
}
documents
};
CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({ ...x, name: game.i18n.localize(x.name) }));
CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({
...x,
name: game.i18n.localize(x.name)
}));
CONFIG.Item.documentClass = documents.DhpItem;
CONFIG.Item.dataModels = {
@ -33,45 +36,45 @@ Hooks.once('init', () => {
miscellaneous: models.DhpMiscellaneous,
consumable: models.DhpConsumable,
weapon: models.DhpWeapon,
armor: models.DhpArmor,
armor: models.DhpArmor
};
const { Items, Actors } = foundry.documents.collections;
Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
Items.registerSheet(SYSTEM.id, applications.DhpAncestry, {types: ["ancestry"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpCommunity, {types: ["community"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpClassSheet, {types: ["class"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpSubclass, {types: ["subclass"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpFeatureSheet, {types: ["feature"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpDomainCardSheet, {types: ["domainCard"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpMiscellaneous, {types: ["miscellaneous"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpConsumable, {types: ["consumable"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpWeapon, {types: ["weapon"], makeDefault: true});
Items.registerSheet(SYSTEM.id, applications.DhpArmor, {types: ["armor"], makeDefault: true});
Items.unregisterSheet('core', foundry.appv1.sheets.ItemSheet);
Items.registerSheet(SYSTEM.id, applications.DhpAncestry, { types: ['ancestry'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpCommunity, { types: ['community'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpClassSheet, { types: ['class'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpSubclass, { types: ['subclass'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpFeatureSheet, { types: ['feature'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpDomainCardSheet, { types: ['domainCard'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpMiscellaneous, { types: ['miscellaneous'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpConsumable, { types: ['consumable'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpWeapon, { types: ['weapon'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpArmor, { types: ['armor'], makeDefault: true });
CONFIG.Actor.documentClass = documents.DhpActor;
CONFIG.Actor.dataModels = {
pc: models.DhpPC,
adversary: models.DhpAdversary,
environment: models.DhpEnvironment,
environment: models.DhpEnvironment
};
Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
Actors.registerSheet(SYSTEM.id, applications.DhpPCSheet, {types: ["pc"], makeDefault: true});
Actors.registerSheet(SYSTEM.id, applications.DhpAdversarySheet, {types: ["adversary"], makeDefault: true});
Actors.registerSheet(SYSTEM.id, applications.DhpEnvironment, {types: ["environment"], makeDefault: true});
Actors.unregisterSheet('core', foundry.appv1.sheets.ActorSheet);
Actors.registerSheet(SYSTEM.id, applications.DhpPCSheet, { types: ['pc'], makeDefault: true });
Actors.registerSheet(SYSTEM.id, applications.DhpAdversarySheet, { types: ['adversary'], makeDefault: true });
Actors.registerSheet(SYSTEM.id, applications.DhpEnvironment, { types: ['environment'], makeDefault: true });
CONFIG.Combat.dataModels = {
base: models.DhpCombat,
base: models.DhpCombat
};
CONFIG.Combatant.dataModels = {
base: models.DhpCombatant,
base: models.DhpCombatant
};
CONFIG.ChatMessage.dataModels = {
dualityRoll: models.DhpDualityRoll,
adversaryRoll: models.DhpAdversaryRoll,
abilityUse: models.DhpAbilityUse,
abilityUse: models.DhpAbilityUse
};
CONFIG.ChatMessage.documentClass = applications.DhpChatMessage;
@ -90,9 +93,7 @@ Hooks.once('init', () => {
return preloadHandlebarsTemplates();
});
Hooks.once('dicesoniceready', () => {
});
Hooks.once('dicesoniceready', () => {});
Hooks.on(socketEvent.GMUpdate, async (action, uuid, update) => {
if (game.user.isGM) {
@ -105,7 +106,11 @@ Hooks.on(socketEvent.GMUpdate, async (action, uuid, update) => {
break;
case GMUpdateEvent.UpdateFear:
if (game.user.isGM) {
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, Math.max(Math.min(update, 6), 0));
await game.settings.set(
SYSTEM.id,
SYSTEM.SETTINGS.gameSettings.Resources.Fear,
Math.max(Math.min(update, 6), 0)
);
Hooks.callAll(socketEvent.DhpFearUpdate);
await game.socket.emit(`system.${SYSTEM.id}`, { action: socketEvent.DhpFearUpdate });
}
@ -116,25 +121,25 @@ Hooks.on(socketEvent.GMUpdate, async (action, uuid, update) => {
const preloadHandlebarsTemplates = async function () {
return foundry.applications.handlebars.loadTemplates([
"systems/daggerheart/templates/sheets/parts/attributes.hbs",
"systems/daggerheart/templates/sheets/parts/defense.hbs",
"systems/daggerheart/templates/sheets/parts/armor.hbs",
"systems/daggerheart/templates/sheets/parts/experience.hbs",
"systems/daggerheart/templates/sheets/parts/features.hbs",
"systems/daggerheart/templates/sheets/parts/gold.hbs",
"systems/daggerheart/templates/sheets/parts/health.hbs",
"systems/daggerheart/templates/sheets/parts/hope.hbs",
"systems/daggerheart/templates/sheets/parts/inventory.hbs",
"systems/daggerheart/templates/sheets/parts/weapons.hbs",
"systems/daggerheart/templates/sheets/parts/domainCard.hbs",
"systems/daggerheart/templates/sheets/parts/heritage.hbs",
"systems/daggerheart/templates/sheets/parts/subclassFeature.hbs",
"systems/daggerheart/templates/sheets/parts/effects.hbs",
"systems/daggerheart/templates/sheets/pc/sections/inventory.hbs",
"systems/daggerheart/templates/sheets/pc/sections/loadout.hbs",
"systems/daggerheart/templates/sheets/pc/parts/heritageCard.hbs",
"systems/daggerheart/templates/sheets/pc/parts/advancementCard.hbs",
"systems/daggerheart/templates/views/parts/level.hbs",
"systems/daggerheart/templates/components/slider.hbs",
'systems/daggerheart/templates/sheets/parts/attributes.hbs',
'systems/daggerheart/templates/sheets/parts/defense.hbs',
'systems/daggerheart/templates/sheets/parts/armor.hbs',
'systems/daggerheart/templates/sheets/parts/experience.hbs',
'systems/daggerheart/templates/sheets/parts/features.hbs',
'systems/daggerheart/templates/sheets/parts/gold.hbs',
'systems/daggerheart/templates/sheets/parts/health.hbs',
'systems/daggerheart/templates/sheets/parts/hope.hbs',
'systems/daggerheart/templates/sheets/parts/inventory.hbs',
'systems/daggerheart/templates/sheets/parts/weapons.hbs',
'systems/daggerheart/templates/sheets/parts/domainCard.hbs',
'systems/daggerheart/templates/sheets/parts/heritage.hbs',
'systems/daggerheart/templates/sheets/parts/subclassFeature.hbs',
'systems/daggerheart/templates/sheets/parts/effects.hbs',
'systems/daggerheart/templates/sheets/pc/sections/inventory.hbs',
'systems/daggerheart/templates/sheets/pc/sections/loadout.hbs',
'systems/daggerheart/templates/sheets/pc/parts/heritageCard.hbs',
'systems/daggerheart/templates/sheets/pc/parts/advancementCard.hbs',
'systems/daggerheart/templates/views/parts/level.hbs',
'systems/daggerheart/templates/components/slider.hbs'
]);
};

View file

@ -3,12 +3,7 @@ var gulp = require('gulp');
var less = require('gulp-less');
gulp.task('less', function (cb) {
gulp
.src('styles/daggerheart.less')
.pipe(less())
.pipe(
gulp.dest("styles")
);
gulp.src('styles/daggerheart.less').pipe(less()).pipe(gulp.dest('styles'));
cb();
});

View file

@ -1,7 +1,6 @@
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
constructor(resolve) {
super({});
@ -13,17 +12,17 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
name: '',
img: null,
customImg: 'icons/svg/mystery-man.svg',
description: '',
},
description: ''
}
};
}
static DEFAULT_OPTIONS = {
tag: 'form',
classes: ["daggerheart", "views", "ancestry-selection"],
classes: ['daggerheart', 'views', 'ancestry-selection'],
position: {
width: 800,
height: "auto"
height: 'auto'
},
actions: {
selectAncestry: this.selectAncestry,
@ -31,21 +30,21 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
viewItem: this.viewItem,
selectImage: this.selectImage,
editImage: this._onEditImage,
saveAncestry: this.saveAncestry,
saveAncestry: this.saveAncestry
},
form: {
submitOnChange: true,
closeOnSubmit: false,
closeOnSubmit: false
}
};
/** @override */
static PARTS = {
damageSelection: {
id: "ancestrySelection",
template: "systems/daggerheart/templates/views/ancestrySelection.hbs"
}
id: 'ancestrySelection',
template: 'systems/daggerheart/templates/views/ancestrySelection.hbs'
}
};
/* -------------------------------------------- */
@ -57,10 +56,10 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
_attachPartListeners(partId, htmlElement, options) {
super._attachPartListeners(partId, htmlElement, options);
const ancestryNameInput = $(htmlElement).find(".ancestry-name");
const ancestryNameInput = $(htmlElement).find('.ancestry-name');
if (ancestryNameInput.length > 0) {
ancestryNameInput.on("change", this.setName.bind(this));
$(htmlElement).find(".ancestry-description").on("change", this.setDescription.bind(this));
ancestryNameInput.on('change', this.setName.bind(this));
$(htmlElement).find('.ancestry-description').on('change', this.setDescription.bind(this));
}
// $(htmlElement).find(".ancestry-image").on("change", this.selectImage.bind(this));
}
@ -68,19 +67,26 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
async _prepareContext(_options) {
const systemAncestries = Array.from((await game.packs.get('daggerheart.playtest-ancestries')).index).map(x => ({
...x,
selected: this.data.ancestries.some(selected => selected.uuid === x.uuid),
selected: this.data.ancestries.some(selected => selected.uuid === x.uuid)
}));
const customAncestries = game.items.reduce((acc, x) => {
if (x.type === 'ancestry') {
acc.push({ ...x, uuid: x.uuid, selected: this.data.ancestries.some(selected => selected.uuid === x.uuid) });
acc.push({
...x,
uuid: x.uuid,
selected: this.data.ancestries.some(selected => selected.uuid === x.uuid)
});
}
return acc;
}, []);
const ancestryFeatures = this.data.ancestries.flatMap(x =>
x.system.abilities.map(x => ({ ...x, selected: this.data.features.some(selected => selected.uuid === x.uuid) }))
x.system.abilities.map(x => ({
...x,
selected: this.data.features.some(selected => selected.uuid === x.uuid)
}))
);
return {
@ -89,7 +95,7 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
ancestryFeatures,
selectedAncestries: this.data.ancestries,
selectedFeatures: this.data.features,
ancestryInfo: this.data.ancestryInfo,
ancestryInfo: this.data.ancestryInfo
};
}
@ -139,7 +145,7 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
static _onEditImage() {
const fp = new FilePicker({
current: this.data.ancestryInfo.img,
type: "image",
type: 'image',
redirectToRoot: ['icons/svg/mystery-man.svg'],
callback: async path => this._updateImage.bind(this)(path),
top: this.position.top + 40,
@ -158,7 +164,22 @@ export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(
if (this.data.ancestries.length === 2) {
const { name, img, description } = this.data.ancestryInfo;
this.resolve({ data: { name: name, img: img, type: "ancestry", system: { description: description, abilities: this.data.features.map(x => ({ name: x.name, img: x.img, uuid: x.uuid, subclassLevel: '' })) }}});
this.resolve({
data: {
name: name,
img: img,
type: 'ancestry',
system: {
description: description,
abilities: this.data.features.map(x => ({
name: x.name,
img: x.img,
uuid: x.uuid,
subclassLevel: ''
}))
}
}
});
} else {
this.resolve({ data: this.data.ancestries[0].toObject() });
}

View file

@ -15,35 +15,42 @@ export default class DaggerheartActionConfig extends DaggerheartSheet(Applicatio
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-action",
classes: ["daggerheart", "views", "action"],
id: 'daggerheart-action',
classes: ['daggerheart', 'views', 'action'],
position: { width: 600, height: 'auto' },
actions: {
toggleSection: this.toggleSection,
toggleSection: this.toggleSection
},
form: {
handler: this.updateForm,
closeOnSubmit: true,
},
closeOnSubmit: true
}
};
static PARTS = {
form: {
id: "action",
template: "systems/daggerheart/templates/views/action.hbs"
}
id: 'action',
template: 'systems/daggerheart/templates/views/action.hbs'
}
};
_getTabs() {
const tabs = {
effects: { active: true, cssClass: '', group: 'primary', id: 'effects', icon: null, label: 'Effects' },
useage: { active: false, cssClass: '', group: 'primary', id: 'useage', icon: null, label: 'Useage' },
conditions: { active: false, cssClass: '', group: 'primary', id: 'conditions', icon: null, label: 'Conditions' },
conditions: {
active: false,
cssClass: '',
group: 'primary',
id: 'conditions',
icon: null,
label: 'Conditions'
}
};
for (const v of Object.values(tabs)) {
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
v.cssClass = v.active ? "active" : "";
v.cssClass = v.active ? 'active' : '';
}
return tabs;
@ -69,6 +76,6 @@ export default class DaggerheartActionConfig extends DaggerheartSheet(Applicatio
newActions.push(data);
}
await this.action.parent.parent.update({ "system.actions": newActions });
await this.action.parent.parent.update({ 'system.actions': newActions });
}
}

View file

@ -1,13 +1,13 @@
export default function DhpApplicationMixin(Base) {
return class DhpSheet extends Base {
static applicationType = "sheets";
static documentType = "";
static applicationType = 'sheets';
static documentType = '';
static get defaultOptions() {
return Object.assign(super.defaultOptions, {
classes: ["daggerheart", "sheet", this.documentType],
classes: ['daggerheart', 'sheet', this.documentType],
template: `systems/${SYSTEM.id}/templates/${this.applicationType}/${this.documentType}.hbs`,
height: "auto",
height: 'auto',
submitOnChange: true,
submitOnClose: false,
width: 450
@ -32,7 +32,7 @@ export default function DhpApplicationMixin(Base) {
activateListeners(html) {
super.activateListeners(html);
html.on("click", "[data-action]", this.#onClickAction.bind(this));
html.on('click', '[data-action]', this.#onClickAction.bind(this));
}
async #onClickAction(event) {
@ -44,5 +44,5 @@ export default function DhpApplicationMixin(Base) {
}
async _handleAction(action, event, button) {}
}
};
}

View file

@ -1,7 +1,6 @@
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
export default class DamageSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
constructor(rollString, bonusDamage, hope, resolve) {
super({});
@ -9,45 +8,45 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
rollString,
bonusDamage: bonusDamage.reduce((acc, x) => {
if (x.appliesOn === SYSTEM.EFFECTS.applyLocations.damageRoll.id) {
acc.push(({
acc.push({
...x,
hopeUses: 0
}));
});
}
return acc;
}, []),
hope,
}
hope
};
this.resolve = resolve;
}
static DEFAULT_OPTIONS = {
tag: 'form',
classes: ["daggerheart", "views", "damage-selection"],
classes: ['daggerheart', 'views', 'damage-selection'],
position: {
width: 400,
height: "auto"
height: 'auto'
},
actions: {
decreaseHopeUse: this.decreaseHopeUse,
increaseHopeUse: this.increaseHopeUse,
rollDamage: this.rollDamage,
rollDamage: this.rollDamage
},
form: {
handler: this.updateSelection,
submitOnChange: true,
closeOnSubmit: false,
closeOnSubmit: false
}
};
/** @override */
static PARTS = {
damageSelection: {
id: "damageSelection",
template: "systems/daggerheart/templates/views/damageSelection.hbs"
}
id: 'damageSelection',
template: 'systems/daggerheart/templates/views/damageSelection.hbs'
}
};
/* -------------------------------------------- */
@ -61,8 +60,8 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
rollString: this.getRollString(),
bonusDamage: this.data.bonusDamage,
hope: this.data.hope + 1,
hopeUsed: this.getHopeUsed(),
}
hopeUsed: this.getHopeUsed()
};
}
static updateSelection(event, _, formData) {
@ -81,7 +80,8 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
}
getRollString() {
return this.data.rollString.concat(this.data.bonusDamage.reduce((acc, x) => {
return this.data.rollString.concat(
this.data.bonusDamage.reduce((acc, x) => {
if (x.initiallySelected) {
const nr = 1 + x.hopeUses;
const baseDamage = x.value;
@ -89,7 +89,8 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
}
return acc;
}, ""));
}, '')
);
}
getHopeUsed() {
@ -113,7 +114,11 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
}
static rollDamage() {
this.resolve({ rollString: this.getRollString(), bonusDamage: this.data.bonusDamage, hopeUsed: this.getHopeUsed() });
this.resolve({
rollString: this.getRollString(),
bonusDamage: this.data.bonusDamage,
hopeUsed: this.getHopeUsed()
});
this.close();
}
}

View file

@ -9,24 +9,24 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application
}
get title() {
return game.i18n.format("DAGGERHEART.Application.DeathMove.Title", { actor: this.actor.name });
return game.i18n.format('DAGGERHEART.Application.DeathMove.Title', { actor: this.actor.name });
}
static DEFAULT_OPTIONS = {
classes: ["daggerheart", "views", "death-move"],
classes: ['daggerheart', 'views', 'death-move'],
position: { width: 800, height: 'auto' },
actions: {
selectMove: this.selectMove,
takeMove: this.takeMove,
},
takeMove: this.takeMove
}
};
static PARTS = {
application: {
id: "death-move",
template: "systems/daggerheart/templates/views/deathMove.hbs"
}
id: 'death-move',
template: 'systems/daggerheart/templates/views/deathMove.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -36,7 +36,6 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application
return context;
}
static selectMove(_, button) {
const move = button.dataset.move;
this.selectedMove = SYSTEM.GENERAL.deathMoves[move];
@ -45,15 +44,15 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application
}
static async takeMove() {
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
content: await renderTemplate("systems/daggerheart/templates/chat/deathMove.hbs", {
content: await renderTemplate('systems/daggerheart/templates/chat/deathMove.hbs', {
player: game.user.character.name,
title: game.i18n.localize(this.selectedMove.name),
img: this.selectedMove.img,
description: game.i18n.localize(this.selectedMove.description),
}),
description: game.i18n.localize(this.selectedMove.description)
})
});
cls.create(msg.toObject());

View file

@ -17,21 +17,21 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
static DEFAULT_OPTIONS = {
tag: 'form',
classes: ["daggerheart", "views", "downtime"],
classes: ['daggerheart', 'views', 'downtime'],
position: { width: 800, height: 'auto' },
actions: {
selectActivity: this.selectActivity,
takeDowntime: this.takeDowntime,
takeDowntime: this.takeDowntime
},
form: { handler: this.updateData, submitOnChange: true }
};
static PARTS = {
application: {
id: "downtime",
template: "systems/daggerheart/templates/views/downtime.hbs"
}
id: 'downtime',
template: 'systems/daggerheart/templates/views/downtime.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -39,35 +39,44 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
context.options = this.shortrest ? SYSTEM.GENERAL.downtime.shortRest : SYSTEM.GENERAL.downtime.longRest;
context.customActivity = this.customActivity;
context.disabledDowntime = !this.selectedActivity || (this.selectedActivity.id === this.customActivity.id && (!this.customActivity.name || !this.customActivity.description));
context.disabledDowntime =
!this.selectedActivity ||
(this.selectedActivity.id === this.customActivity.id &&
(!this.customActivity.name || !this.customActivity.description));
return context;
}
static selectActivity(_, button) {
const activity = button.dataset.activity;
this.selectedActivity = activity === this.customActivity.id ? this.customActivity : this.shortrest ? SYSTEM.GENERAL.downtime.shortRest[activity] : SYSTEM.GENERAL.downtime.longRest[activity];
this.selectedActivity =
activity === this.customActivity.id
? this.customActivity
: this.shortrest
? SYSTEM.GENERAL.downtime.shortRest[activity]
: SYSTEM.GENERAL.downtime.longRest[activity];
this.render();
}
static async takeDowntime() {
const refreshedFeatures = this.shortrest ? this.actor.system.refreshableFeatures.shortRest : [...this.actor.system.refreshableFeatures.shortRest, ...this.actor.system.refreshableFeatures.longRest];
const refreshedFeatures = this.shortrest
? this.actor.system.refreshableFeatures.shortRest
: [...this.actor.system.refreshableFeatures.shortRest, ...this.actor.system.refreshableFeatures.longRest];
for (var feature of refreshedFeatures) {
await feature.system.refresh();
}
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
content: await renderTemplate("systems/daggerheart/templates/chat/downtime.hbs", {
content: await renderTemplate('systems/daggerheart/templates/chat/downtime.hbs', {
player: game.user.character.name,
title: game.i18n.localize(this.selectedActivity.name),
img: this.selectedActivity.img,
description: game.i18n.localize(this.selectedActivity.description),
refreshedFeatures: refreshedFeatures,
}),
refreshedFeatures: refreshedFeatures
})
});
cls.create(msg.toObject());

View file

@ -1,6 +1,6 @@
import SelectDialog from "../dialogs/selectDialog.mjs";
import { getTier } from "../helpers/utils.mjs";
import DhpMulticlassDialog from "./multiclassDialog.mjs";
import SelectDialog from '../dialogs/selectDialog.mjs';
import { getTier } from '../helpers/utils.mjs';
import DhpMulticlassDialog from './multiclassDialog.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -18,30 +18,33 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
}
static DEFAULT_OPTIONS = {
id: "daggerheart-levelup",
classes: ["daggerheart", "views", "levelup"],
id: 'daggerheart-levelup',
classes: ['daggerheart', 'views', 'levelup'],
position: { width: 1200, height: 'auto' },
window: {
resizable: true,
resizable: true
},
actions: {
toggleBox: this.toggleBox,
advanceLevel: this.advanceLevel,
finishLevelup: this.finishLevelup,
},
finishLevelup: this.finishLevelup
}
};
static PARTS = {
form: {
id: "levelup",
template: "systems/daggerheart/templates/views/levelup.hbs"
}
id: 'levelup',
template: 'systems/daggerheart/templates/views/levelup.hbs'
}
};
async _prepareContext(_options) {
let selectedChoices = 0, multiclassing = {}, subclassing = {};
const leveledTiers = Object.keys(this.data.levelups).reduce((acc, levelKey) => {
let selectedChoices = 0,
multiclassing = {},
subclassing = {};
const leveledTiers = Object.keys(this.data.levelups).reduce(
(acc, levelKey) => {
const levelData = this.data.levelups[levelKey];
['tier1', 'tier2', 'tier3'].forEach(tierKey => {
let tierUpdate = {};
@ -71,7 +74,9 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
});
return acc;
}, { tier1: {}, tier2: {}, tier3: {} });
},
{ tier1: {}, tier2: {}, tier3: {} }
);
const activeTier = getTier(this.activeLevel);
const data = Object.keys(SYSTEM.ACTOR.levelupData).reduce((acc, tierKey) => {
@ -87,19 +92,33 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
acc[propertyKey] = { description: property.description, cost: property.cost ?? 1, values: [] };
for (var i = 0; i < property.maxChoices; i++) {
const leveledValue = leveledTiers[tierKey][propertyKey]?.[i];
const subclassLock = propertyKey === 'subclass' && Object.keys(multiclassing).find(x => getTier(Number.parseInt(x)) === tierKey);
const subclassLock =
propertyKey === 'subclass' &&
Object.keys(multiclassing).find(x => getTier(Number.parseInt(x)) === tierKey);
const subclassMulticlassLock = propertyKey === 'multiclass' && subclassing[tierKey];
const multiclassLock = propertyKey === 'multiclass' && Object.keys(multiclassing).length > 0 && !(leveledValue && Object.keys(multiclassing).find(x => Number.parseInt(x) === leveledValue.level));
const locked = leveledValue && leveledValue.level !== this.activeLevel || subclassLock || subclassMulticlassLock || multiclassLock;
const disabled = tierKey > activeTier || (selectedChoices === 2 && !(leveledValue && leveledValue.level === this.activeLevel)) || locked;
const multiclassLock =
propertyKey === 'multiclass' &&
Object.keys(multiclassing).length > 0 &&
!(
leveledValue &&
Object.keys(multiclassing).find(x => Number.parseInt(x) === leveledValue.level)
);
const locked =
(leveledValue && leveledValue.level !== this.activeLevel) ||
subclassLock ||
subclassMulticlassLock ||
multiclassLock;
const disabled =
tierKey > activeTier ||
(selectedChoices === 2 && !(leveledValue && leveledValue.level === this.activeLevel)) ||
locked;
acc[propertyKey].values.push({
selected: leveledValue?.value !== undefined,
path: `levelups.${this.activeLevel}.${tierKey}.${propertyKey}.${i}`,
description: game.i18n.localize(property.description),
disabled: disabled,
locked: locked,
locked: locked
});
}
@ -114,8 +133,8 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
data: data,
activeLevel: this.activeLevel,
changedLevel: this.actor.system.levelData.changedLevel,
completedSelection: selectedChoices === 2,
}
completedSelection: selectedChoices === 2
};
}
static async toggleBox(_, button) {
@ -126,8 +145,7 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
let array = foundry.utils.getProperty(this.data, arrayPart);
if (button.dataset.levelAttribute === 'multiclass') {
array = [];
}
else {
} else {
delete array[Number.parseInt(pathParts[pathParts.length - 1])];
}
foundry.utils.setProperty(this.data, arrayPart, array);
@ -136,21 +154,40 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
const levelChoices = SYSTEM.ACTOR.levelChoices[button.dataset.levelAttribute];
if (button.dataset.levelAttribute === 'subclass') {
if (!this.actor.system.multiclassSubclass) {
updates[0].value.value = { multiclass: false, feature: this.actor.system.subclass.system.specializationFeature.unlocked ? 'mastery' : 'specialization' };
updates[0].value.value = {
multiclass: false,
feature: this.actor.system.subclass.system.specializationFeature.unlocked
? 'mastery'
: 'specialization'
};
} else {
const choices = [
{ name: this.actor.system.subclass.name, value: this.actor.system.subclass.uuid },
{
name: this.actor.system.multiclassSubclass.name,
value: this.actor.system.multiclassSubclass.uuid
}
else {
const choices = [{name: this.actor.system.subclass.name, value: this.actor.system.subclass.uuid}, {name: this.actor.system.multiclassSubclass.name, value: this.actor.system.multiclassSubclass.uuid}];
const indexes = await SelectDialog.selectItem({ actor: this.actor, choices: choices, title: levelChoices.title, nrChoices: 1 });
];
const indexes = await SelectDialog.selectItem({
actor: this.actor,
choices: choices,
title: levelChoices.title,
nrChoices: 1
});
if (indexes.length === 0) {
this.render();
return;
}
const multiclassSubclass = choices[indexes[0]].name === this.actor.system.multiclassSubclass.name;
updates[0].value.value = { multiclass: multiclassSubclass, feature: this.actor.system.multiclassSubclass.system.specializationFeature.unlocked ? 'mastery' : 'specialization' };
updates[0].value.value = {
multiclass: multiclassSubclass,
feature: this.actor.system.multiclassSubclass.system.specializationFeature.unlocked
? 'mastery'
: 'specialization'
};
}
}
else if (button.dataset.levelAttribute === 'multiclass'){
const multiclassAwait = new Promise((resolve) => {
} else if (button.dataset.levelAttribute === 'multiclass') {
const multiclassAwait = new Promise(resolve => {
new DhpMulticlassDialog(this.actor.name, this.actor.system.class, resolve).render(true);
});
const multiclassData = await multiclassAwait;
@ -161,22 +198,56 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
const pathParts = path.split('.');
const arrayPart = pathParts.slice(0, pathParts.length - 1).join('.');
updates[0] = { path: [arrayPart, '0'].join('.'), value: { level: this.activeLevel, value: { class: multiclassData.class, subclass: multiclassData.subclass, domain: multiclassData.domain, level: this.activeLevel } } };
updates[1] = { path: [arrayPart, '1'].join('.'), value: { level: this.activeLevel, value: { class: multiclassData.class, subclass: multiclassData.subclass, domain: multiclassData.domain, level: this.activeLevel } } };
updates[0] = {
path: [arrayPart, '0'].join('.'),
value: {
level: this.activeLevel,
value: {
class: multiclassData.class,
subclass: multiclassData.subclass,
domain: multiclassData.domain,
level: this.activeLevel
}
else {
}
};
updates[1] = {
path: [arrayPart, '1'].join('.'),
value: {
level: this.activeLevel,
value: {
class: multiclassData.class,
subclass: multiclassData.subclass,
domain: multiclassData.domain,
level: this.activeLevel
}
}
};
} else {
if (levelChoices.choices.length > 0) {
if (typeof levelChoices.choices === 'string') {
const choices = foundry.utils.getProperty(this.actor, levelChoices.choices).map(x => ({ name: x.description, value: x.id }));
const indexes = await SelectDialog.selectItem({ actor: this.actor, choices: choices, title: levelChoices.title, nrChoices: levelChoices.nrChoices });
const choices = foundry.utils
.getProperty(this.actor, levelChoices.choices)
.map(x => ({ name: x.description, value: x.id }));
const indexes = await SelectDialog.selectItem({
actor: this.actor,
choices: choices,
title: levelChoices.title,
nrChoices: levelChoices.nrChoices
});
if (indexes.length === 0) {
this.render();
return;
}
updates[0].value.value = choices.filter((_, index) => indexes.includes(index)).map(x => x.value);
}
else {
const indexes = await SelectDialog.selectItem({ actor: this.actor, choices: levelChoices.choices, title: levelChoices.title, nrChoices: levelChoices.nrChoices });
updates[0].value.value = choices
.filter((_, index) => indexes.includes(index))
.map(x => x.value);
} else {
const indexes = await SelectDialog.selectItem({
actor: this.actor,
choices: levelChoices.choices,
title: levelChoices.title,
nrChoices: levelChoices.nrChoices
});
if (indexes.length === 0) {
this.render();
return;
@ -214,20 +285,33 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
multiclass = this.data.levelups[level][tier][category][value].value;
this.data.levelups[level][tier][category][value] = true;
} else {
this.data.levelups[level][tier][category][value] = this.data.levelups[level][tier][category][value].value ?? true;
this.data.levelups[level][tier][category][value] =
this.data.levelups[level][tier][category][value].value ?? true;
}
}
}
}
}
const tiersMoved = getTier(this.actor.system.levelData.changedLevel, true) - getTier(this.actor.system.levelData.currentLevel, true);
const experiences = Array.from(Array(tiersMoved), (_,index) => ({ id: foundry.utils.randomID(), level: this.actor.system.experiences.length+index*3, description: '', value: 1 }));
const tiersMoved =
getTier(this.actor.system.levelData.changedLevel, true) -
getTier(this.actor.system.levelData.currentLevel, true);
const experiences = Array.from(Array(tiersMoved), (_, index) => ({
id: foundry.utils.randomID(),
level: this.actor.system.experiences.length + index * 3,
description: '',
value: 1
}));
await this.actor.update({ system: {
await this.actor.update(
{
system: {
levelData: this.data,
experiences: [...this.actor.system.experiences, ...experiences],
}}, { diff: false });
experiences: [...this.actor.system.experiences, ...experiences]
}
},
{ diff: false }
);
if (!this.actor.multiclass && multiclass) {
const multiclassClass = (await fromUuid(multiclass.class.uuid)).toObject();
@ -245,7 +329,11 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
multiclassSubclass.system.multiclass = multiclass.level;
const multiclassSubclassFeatures = {};
const features = [multiclassSubclass.system.foundationFeature, multiclassSubclass.system.specializationFeature, multiclassSubclass.system.masteryFeature];
const features = [
multiclassSubclass.system.foundationFeature,
multiclassSubclass.system.specializationFeature,
multiclassSubclass.system.masteryFeature
];
for (var i = 0; i < features.length; i++) {
const path = i === 0 ? 'foundationFeature' : i === 1 ? 'specializationFeature' : 'masteryFeature';
const feature = features[i];
@ -272,10 +360,13 @@ export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2
}
}
await this.actor.createEmbeddedDocuments('Item', [multiclassClass, ...multiclassFeatures, multiclassSubclass]);
await this.actor.createEmbeddedDocuments('Item', [
multiclassClass,
...multiclassFeatures,
multiclassSubclass
]);
}
this.close();
}
}

View file

@ -8,20 +8,22 @@ export default class DhpMulticlassDialog extends HandlebarsApplicationMixin(Appl
this.actorClass = actorClass;
this.resolve = resolve;
this.classChoices = Array.from(game.items.reduce((acc, x) => {
this.classChoices = Array.from(
game.items.reduce((acc, x) => {
if (x.type === 'class' && x.name !== actorClass.name) {
acc.add(x);
}
return acc;
}, new Set()));
}, new Set())
);
this.subclassChoices = [];
this.domainChoices = [];
this.data = {
class: null,
subclass: null,
domain: null,
domain: null
};
}
@ -30,22 +32,22 @@ export default class DhpMulticlassDialog extends HandlebarsApplicationMixin(Appl
}
static DEFAULT_OPTIONS = {
classes: ["daggerheart", "views", "multiclass"],
classes: ['daggerheart', 'views', 'multiclass'],
position: { width: 600, height: 'auto' },
actions: {
selectClass: this.selectClass,
selectSubclass: this.selectSubclass,
selectDomain: this.selectDomain,
finish: this.finish,
},
finish: this.finish
}
};
static PARTS = {
form: {
id: "levelup",
template: "systems/daggerheart/templates/views/multiclass.hbs"
}
id: 'levelup',
template: 'systems/daggerheart/templates/views/multiclass.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -65,22 +67,35 @@ export default class DhpMulticlassDialog extends HandlebarsApplicationMixin(Appl
this.data.subclass = null;
this.data.domain = null;
this.subclassChoices = this.data.class ? this.data.class.system.subclasses : [];
this.domainChoices = this.data.class ? this.data.class.system.domains.map(x => {
this.domainChoices = this.data.class
? this.data.class.system.domains.map(x => {
const config = SYSTEM.DOMAIN.domains[x];
return { name: game.i18n.localize(config.name), id: config.id, img: config.src, disabled: this.actorClass.system.domains.includes(config.id) };
}) : [];
return {
name: game.i18n.localize(config.name),
id: config.id,
img: config.src,
disabled: this.actorClass.system.domains.includes(config.id)
};
})
: [];
}
this.render(true);
}
static async selectSubclass(_, button) {
this.data.subclass = this.data.subclass?.uuid === button.dataset.subclass ? null : this.subclassChoices.find(x => x.uuid === button.dataset.subclass);
this.data.subclass =
this.data.subclass?.uuid === button.dataset.subclass
? null
: this.subclassChoices.find(x => x.uuid === button.dataset.subclass);
this.render(true);
}
static async selectDomain(_, button) {
const domain = this.data.domain?.id === button.dataset.domain ? null : this.domainChoices.find(x => x.id === button.dataset.domain);;
const domain =
this.data.domain?.id === button.dataset.domain
? null
: this.domainChoices.find(x => x.id === button.dataset.domain);
if (domain?.disabled) return;
this.data.domain = domain;

View file

@ -7,7 +7,7 @@ export default class NpcRollSelectionDialog extends FormApplication {
this.selectedExperiences = [];
this.data = {
nrDice: 1,
advantage: null,
advantage: null
};
}
@ -24,7 +24,7 @@ export default class NpcRollSelectionDialog extends FormApplication {
template: 'systems/daggerheart/templates/views/npcRollSelection.hbs',
closeOnSubmit: false,
submitOnChange: true,
classes: ["daggerheart", "views", "npc-roll-selection"],
classes: ['daggerheart', 'views', 'npc-roll-selection']
};
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
@ -36,7 +36,10 @@ export default class NpcRollSelectionDialog extends FormApplication {
const context = super.getData();
context.nrDice = this.data.nrDice;
context.advantage = this.data.advantage;
context.experiences = this.experiences.map(x => ({ ...x, selected: this.selectedExperiences.find(selected => selected.id === x.id) }));
context.experiences = this.experiences.map(x => ({
...x,
selected: this.selectedExperiences.find(selected => selected.id === x.id)
}));
return context;
}
@ -64,7 +67,9 @@ export default class NpcRollSelectionDialog extends FormApplication {
selectExperience(event) {
const experience = this.experiences[event.currentTarget.dataset.key];
this.selectedExperiences = this.selectedExperiences.find(x => x.name === experience.name) ? this.selectedExperiences.filter(x => x.name !== experience.name) : [...this.selectedExperiences, experience];
this.selectedExperiences = this.selectedExperiences.find(x => x.name === experience.name)
? this.selectedExperiences.filter(x => x.name !== experience.name)
: [...this.selectedExperiences, experience];
this.render();
}

View file

@ -9,31 +9,34 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
this.isNpc;
this.selectedExperiences = [];
this.data = {
diceOptions: [{ name: 'd12', value: 'd12' }, { name: 'd20', value: 'd20' }],
diceOptions: [
{ name: 'd12', value: 'd12' },
{ name: 'd20', value: 'd20' }
],
hope: ['d12'],
fear: ['d12'],
advantage: null,
disadvantage: null,
bonusDamage: bonusDamage.reduce((acc, x) => {
if (x.appliesOn === SYSTEM.EFFECTS.applyLocations.attackRoll.id) {
acc.push(({
acc.push({
...x,
hopeUses: 0
}));
});
}
return acc;
}, []),
hopeResource: hopeResource,
hopeResource: hopeResource
};
}
static DEFAULT_OPTIONS = {
tag: 'form',
classes: ["daggerheart", "views", "roll-selection"],
classes: ['daggerheart', 'views', 'roll-selection'],
position: {
width: 400,
height: "auto"
height: 'auto'
},
actions: {
selectExperience: this.selectExperience,
@ -41,22 +44,22 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
increaseHopeUse: this.increaseHopeUse,
setAdvantage: this.setAdvantage,
setDisadvantage: this.setDisadvantage,
finish: this.finish,
finish: this.finish
},
form: {
handler: this.updateSelection,
submitOnChange: true,
submitOnClose: false,
submitOnClose: false
}
};
/** @override */
static PARTS = {
damageSelection: {
id: "damageSelection",
template: "systems/daggerheart/templates/views/rollSelection.hbs"
}
id: 'damageSelection',
template: 'systems/daggerheart/templates/views/rollSelection.hbs'
}
};
get title() {
return `Roll Options`;
@ -70,7 +73,10 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
context.fear = this.data.fear;
context.advantage = this.data.advantage;
context.disadvantage = this.data.disadvantage;
context.experiences = this.experiences.map(x => ({ ...x, selected: this.selectedExperiences.find(selected => selected.id === x.id) }));
context.experiences = this.experiences.map(x => ({
...x,
selected: this.selectedExperiences.find(selected => selected.id === x.id)
}));
context.bonusDamage = this.data.bonusDamage;
context.hopeResource = this.data.hopeResource + 1;
context.hopeUsed = this.getHopeUsed();
@ -97,7 +103,10 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
if (this.selectedExperiences.find(x => x.id === button.dataset.key)) {
this.selectedExperiences = this.selectedExperiences.filter(x => x.id !== button.dataset.key);
} else {
this.selectedExperiences = [...this.selectedExperiences, this.experiences.find(x => x.id === button.dataset.key)];
this.selectedExperiences = [
...this.selectedExperiences,
this.experiences.find(x => x.id === button.dataset.key)
];
}
this.render();
@ -139,7 +148,12 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
static async finish() {
const { diceOptions, ...rest } = this.data;
this.resolve({ ...rest, experiences: this.selectedExperiences, hopeUsed: this.getHopeUsed(), bonusDamage: this.data.bonusDamage.reduce((acc, x) => acc.concat(` + ${1+x.hopeUses}${x.value}`), "") });
this.resolve({
...rest,
experiences: this.selectedExperiences,
hopeUsed: this.getHopeUsed(),
bonusDamage: this.data.bonusDamage.reduce((acc, x) => acc.concat(` + ${1 + x.hopeUses}${x.value}`), '')
});
this.close();
}
}

View file

@ -12,7 +12,7 @@ class DhpAutomationSettings extends FormApplication {
template: 'systems/daggerheart/templates/views/automation-settings.hbs',
closeOnSubmit: true,
submitOnChange: false,
classes: ["daggerheart", "views", "settings"],
classes: ['daggerheart', 'views', 'settings']
};
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
@ -56,7 +56,7 @@ class DhpHomebrewSettings extends FormApplication {
template: 'systems/daggerheart/templates/views/homebrew-settings.hbs',
closeOnSubmit: true,
submitOnChange: false,
classes: ["daggerheart", "views", "settings"],
classes: ['daggerheart', 'views', 'settings']
};
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
@ -101,7 +101,7 @@ class DhpRangeSettings extends FormApplication {
template: 'systems/daggerheart/templates/views/range-settings.hbs',
closeOnSubmit: false,
submitOnChange: true,
classes: ["daggerheart", "views", "settings"],
classes: ['daggerheart', 'views', 'settings']
};
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
@ -113,7 +113,15 @@ class DhpRangeSettings extends FormApplication {
const context = super.getData();
context.settings = SYSTEM.SETTINGS.gameSettings.General;
context.range = this.range;
context.disabled = context.range.enabled && [context.range.melee, context.range.veryClose, context.range.close, context.range.far, context.range.veryFar].some(x => x === null || x === false);
context.disabled =
context.range.enabled &&
[
context.range.melee,
context.range.veryClose,
context.range.close,
context.range.far,
context.range.veryFar
].some(x => x === null || x === false);
return context;
}
@ -121,9 +129,9 @@ class DhpRangeSettings extends FormApplication {
activateListeners(html) {
super.activateListeners(html);
html.find(".range-reset").click(this.reset.bind(this));
html.find(".save").click(this.save.bind(this));
html.find(".close").click(this.close.bind(this));
html.find('.range-reset').click(this.reset.bind(this));
html.find('.save').click(this.save.bind(this));
html.find('.close').click(this.close.bind(this));
}
async _updateObject(_, formData) {
@ -154,44 +162,44 @@ export const registerDHPSettings = () => {
// const debouncedReload = foundry.utils.debounce(() => window.location.reload(), 100);
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.AbilityArray, {
name: game.i18n.localize("DAGGERHEART.Settings.General.AbilityArray.Name"),
hint: game.i18n.localize("DAGGERHEART.Settings.General.AbilityArray.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.General.AbilityArray.Name'),
hint: game.i18n.localize('DAGGERHEART.Settings.General.AbilityArray.Hint'),
scope: 'world',
config: false,
type: String,
default: '[2,1,1,0,0,-1]',
default: '[2,1,1,0,0,-1]'
});
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, {
name: game.i18n.localize("DAGGERHEART.Settings.Resources.Fear.Name"),
hint: game.i18n.localize("DAGGERHEART.Settings.Resources.Fear.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.Resources.Fear.Name'),
hint: game.i18n.localize('DAGGERHEART.Settings.Resources.Fear.Hint'),
scope: 'world',
config: false,
type: Number,
default: 0,
default: 0
});
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope, {
name: game.i18n.localize("DAGGERHEART.Settings.Automation.Hope.Name"),
hint: game.i18n.localize("DAGGERHEART.Settings.Automation.Hope.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.Automation.Hope.Name'),
hint: game.i18n.localize('DAGGERHEART.Settings.Automation.Hope.Hint'),
scope: 'world',
config: false,
type: Boolean,
default: false,
default: false
});
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.ActionPoints, {
name: game.i18n.localize("DAGGERHEART.Settings.Automation.ActionPoints.Name"),
hint: game.i18n.localize("DAGGERHEART.Settings.Automation.ActionPoints.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.Automation.ActionPoints.Name'),
hint: game.i18n.localize('DAGGERHEART.Settings.Automation.ActionPoints.Hint'),
scope: 'world',
config: false,
type: Boolean,
default: true,
default: true
});
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.General.RangeMeasurement, {
name: game.i18n.localize("DAGGERHEART.Settings.General.RangeMeasurement.Name"),
hint: game.i18n.localize("DAGGERHEART.Settings.General.RangeMeasurement.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.General.RangeMeasurement.Name'),
hint: game.i18n.localize('DAGGERHEART.Settings.General.RangeMeasurement.Hint'),
scope: 'world',
config: false,
type: Object,
@ -202,35 +210,34 @@ export const registerDHPSettings = () => {
close: 30,
far: 60,
veryFar: 120
},
}
});
game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Automation.Name, {
name: game.i18n.localize("DAGGERHEART.Settings.Menu.Automation.Name"),
label: game.i18n.localize("DAGGERHEART.Settings.Menu.Automation.Label"),
hint: game.i18n.localize("DAGGERHEART.Settings.Menu.Automation.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'),
label: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Label'),
hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Hint'),
icon: SYSTEM.SETTINGS.menu.Automation.Icon,
type: DhpAutomationSettings,
restricted: true
});
game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Homebrew.Name, {
name: game.i18n.localize("DAGGERHEART.Settings.Menu.Homebrew.Name"),
label: game.i18n.localize("DAGGERHEART.Settings.Menu.Homebrew.Label"),
hint: game.i18n.localize("DAGGERHEART.Settings.Menu.Homebrew.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Name'),
label: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Label'),
hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Hint'),
icon: SYSTEM.SETTINGS.menu.Homebrew.Icon,
type: DhpHomebrewSettings,
restricted: true
});
game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Range.Name, {
name: game.i18n.localize("DAGGERHEART.Settings.Menu.Range.Name"),
label: game.i18n.localize("DAGGERHEART.Settings.Menu.Range.Label"),
hint: game.i18n.localize("DAGGERHEART.Settings.Menu.Range.Hint"),
name: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Name'),
label: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Label'),
hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Hint'),
icon: SYSTEM.SETTINGS.menu.Range.Icon,
type: DhpRangeSettings,
restricted: true
});
}
};
// const {HandlebarsApplicationMixin, ApplicationV2} = foundry.applications.api;

View file

@ -1,4 +1,3 @@
// import DhpApplicationMixin from '../daggerheart-sheet.mjs';
// export class Teest extends DhpApplicationMixin(ActorSheet) {
@ -206,8 +205,8 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-adversary",
classes: ["daggerheart", "sheet", "adversary"],
id: 'daggerheart-adversary',
classes: ['daggerheart', 'sheet', 'adversary'],
position: { width: 600 },
actions: {
viewMove: this.viewMove,
@ -221,21 +220,21 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
addExperience: this.addExperience,
removeExperience: this.removeExperience,
toggleHP: this.toggleHP,
toggleStress: this.toggleStress,
toggleStress: this.toggleStress
},
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
},
closeOnSubmit: false
}
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/adversary.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/adversary.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -252,25 +251,39 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
attack: {
name: this.document.system.attack.name,
attackModifier: this.document.system.attackModifier,
range: this.document.system.attack.range ? game.i18n.localize(SYSTEM.GENERAL.range[this.document.system.attack.range].name) : null,
range: this.document.system.attack.range
? game.i18n.localize(SYSTEM.GENERAL.range[this.document.system.attack.range].name)
: null,
damage: {
value: this.document.system.attack.damage.value,
type: this.document.system.attack.damage.type,
typeName: this.document.system.attack.damage.type ? game.i18n.localize(SYSTEM.GENERAL.damageTypes[this.document.system.attack.damage.type].abbreviation).toLowerCase() : null,
},
typeName: this.document.system.attack.damage.type
? game.i18n
.localize(
SYSTEM.GENERAL.damageTypes[this.document.system.attack.damage.type].abbreviation
)
.toLowerCase()
: null
}
},
damageThresholds: this.document.system.damageThresholds,
difficulty: this.document.system.difficulty,
hp: { ...this.document.system.resources.health, lastRowIndex: Math.floor(this.document.system.resources.health.max/5)*5 },
stress: { ...this.document.system.resources.stress, lastRowIndex: Math.floor(this.document.system.resources.stress.max/5)*5 },
moves: this.document.system.moves,
hp: {
...this.document.system.resources.health,
lastRowIndex: Math.floor(this.document.system.resources.health.max / 5) * 5
},
stress: {
...this.document.system.resources.stress,
lastRowIndex: Math.floor(this.document.system.resources.stress.max / 5) * 5
},
moves: this.document.system.moves
};
return context;
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
@ -280,10 +293,12 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
}
static async addMove() {
const result = await this.document.createEmbeddedDocuments("Item", [{
const result = await this.document.createEmbeddedDocuments('Item', [
{
name: game.i18n.localize('DAGGERHEART.Sheets.Adversary.NewMove'),
type: 'feature',
}]);
type: 'feature'
}
]);
await result[0].sheet.render(true);
}
@ -298,26 +313,33 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
}
static async addMotive() {
await this.document.update({ "system.motivesAndTactics": [...this.document.system.motivesAndTactics, ''] });
await this.document.update({ 'system.motivesAndTactics': [...this.document.system.motivesAndTactics, ''] });
}
static async removeMotive(button) {
await this.document.update({ "system.motivesAndTactics": this.document.system.motivesAndTactics.filter((_, index) => index !== Number.parseInt(button.dataset.motive) )});
await this.document.update({
'system.motivesAndTactics': this.document.system.motivesAndTactics.filter(
(_, index) => index !== Number.parseInt(button.dataset.motive)
)
});
}
static async reactionRoll(event) {
const { roll, diceResults, modifiers } = await this.actor.diceRoll({ title: `${this.actor.name} - Reaction Roll`, value: 0 }, event.shiftKey);
const { roll, diceResults, modifiers } = await this.actor.diceRoll(
{ title: `${this.actor.name} - Reaction Roll`, value: 0 },
event.shiftKey
);
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
type: 'adversaryRoll',
system: {
roll: roll._formula,
total: roll._total,
modifiers: modifiers,
diceResults: diceResults,
diceResults: diceResults
},
content: "systems/daggerheart/templates/chat/adversary-roll.hbs",
content: 'systems/daggerheart/templates/chat/adversary-roll.hbs',
rolls: [roll]
});
@ -327,17 +349,20 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
static async attackRoll(event, button) {
const modifier = Number.parseInt(button.dataset.value);
const { roll, diceResults, modifiers } = await this.actor.diceRoll({ title: `${this.actor.name} - Attack Roll`, value: modifier }, event.shiftKey);
const { roll, diceResults, modifiers } = await this.actor.diceRoll(
{ title: `${this.actor.name} - Attack Roll`, value: modifier },
event.shiftKey
);
const targets = Array.from(game.user.targets).map(x => ({
id: x.id,
name: x.actor.name,
img: x.actor.img,
difficulty: x.actor.system.difficulty,
evasion: x.actor.system.evasion,
evasion: x.actor.system.evasion
}));
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
type: 'adversaryRoll',
system: {
@ -346,9 +371,9 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
modifiers: modifiers,
diceResults: diceResults,
targets: targets,
damage: { value: button.dataset.damage, type: button.dataset.damageType },
damage: { value: button.dataset.damage, type: button.dataset.damageType }
},
content: "systems/daggerheart/templates/chat/adversary-attack-roll.hbs",
content: 'systems/daggerheart/templates/chat/adversary-attack-roll.hbs',
rolls: [roll]
});
@ -356,22 +381,28 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
}
static async addExperience() {
await this.document.update({ "system.experiences": [...this.document.system.experiences, { name: 'Experience', value: 1 }] });
await this.document.update({
'system.experiences': [...this.document.system.experiences, { name: 'Experience', value: 1 }]
});
}
static async removeExperience(_, button) {
await this.document.update({ "system.experiences": this.document.system.experiences.filter((_, index) => index !== Number.parseInt(button.dataset.experience) )});
await this.document.update({
'system.experiences': this.document.system.experiences.filter(
(_, index) => index !== Number.parseInt(button.dataset.experience)
)
});
}
static async toggleHP(_, button) {
const index = Number.parseInt(button.dataset.index);
const newHP = index < this.document.system.resources.health.value ? index : index + 1;
await this.document.update({ "system.resources.health.value": newHP });
await this.document.update({ 'system.resources.health.value': newHP });
}
static async toggleStress(_, button) {
const index = Number.parseInt(button.dataset.index);
const newStress = index < this.document.system.resources.stress.value ? index : index + 1;
await this.document.update({ "system.resources.stress.value": newStress });
await this.document.update({ 'system.resources.stress.value': newStress });
}
}

View file

@ -24,7 +24,6 @@
// return context;
// }
// async _handleAction(action, event, button) {
// switch(action){
// case 'editAbility':
@ -62,27 +61,27 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class AncestrySheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-ancestry",
classes: ["daggerheart", "sheet", "heritage"],
id: 'daggerheart-ancestry',
classes: ['daggerheart', 'sheet', 'heritage'],
position: { width: 600 },
actions: {
editAbility: this.editAbility,
deleteAbility: this.deleteAbility,
deleteAbility: this.deleteAbility
},
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
closeOnSubmit: false
},
dragDrop: [{ dragSelector: null, dropSelector: null }],
dragDrop: [{ dragSelector: null, dropSelector: null }]
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/ancestry.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/ancestry.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -92,7 +91,7 @@ export default class AncestrySheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
@ -104,14 +103,21 @@ export default class AncestrySheet extends DaggerheartSheet(ItemSheetV2) {
static async deleteAbility(event, button) {
event.preventDefault();
event.stopPropagation();
await this.item.update({ "system.abilities": this.item.system.abilities.filter(x => x.uuid !== button.dataset.ability) })
await this.item.update({
'system.abilities': this.item.system.abilities.filter(x => x.uuid !== button.dataset.ability)
});
}
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
const item = await fromUuid(data.uuid);
if (item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.ancestry.id) {
await this.document.update({ "system.abilities": [...this.document.system.abilities, { img: item.img, name: item.name, uuid: item.uuid }] });
await this.document.update({
'system.abilities': [
...this.document.system.abilities,
{ img: item.img, name: item.name, uuid: item.uuid }
]
});
}
}
}

View file

@ -20,7 +20,6 @@
// return context;
// }
// async _handleAction(action, event, button) {
// switch(action){
// }
@ -32,23 +31,23 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class ArmorSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-armor",
classes: ["daggerheart", "sheet", "armor"],
id: 'daggerheart-armor',
classes: ['daggerheart', 'sheet', 'armor'],
position: { width: 400 },
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
closeOnSubmit: false
},
dragDrop: [{ dragSelector: null, dropSelector: null }],
dragDrop: [{ dragSelector: null, dropSelector: null }]
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/armor.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/armor.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -59,7 +58,7 @@ export default class ArmorSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
}

View file

@ -210,14 +210,14 @@
// }
import DaggerheartSheet from './daggerheart-sheet.mjs';
import Tagify from "@yaireo/tagify";
import Tagify from '@yaireo/tagify';
const { ItemSheetV2 } = foundry.applications.sheets;
export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-class",
classes: ["daggerheart", "sheet", "class"],
id: 'daggerheart-class',
classes: ['daggerheart', 'sheet', 'class'],
position: { width: 600 },
actions: {
removeSubclass: this.removeSubclass,
@ -228,13 +228,12 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
viewItem: this.viewItem,
removePrimaryWeapon: this.removePrimaryWeapon,
removeSecondaryWeapon: this.removeSecondaryWeapon,
removeArmor: this.removeArmor,
removeArmor: this.removeArmor
},
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
closeOnSubmit: false
},
dragDrop: [
{ dragSelector: '.suggested-item', dropSelector: null },
@ -244,25 +243,39 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
{ dragSelector: null, dropSelector: '.primary-weapon-section' },
{ dragSelector: null, dropSelector: '.secondary-weapon-section' },
{ dragSelector: null, dropSelector: '.armor-section' },
{ dragSelector: null, dropSelector: null },
{ dragSelector: null, dropSelector: null }
]
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/class.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/class.hbs'
}
};
_getTabs() {
const tabs = {
features: { active: true, cssClass: '', group: 'primary', id: 'features', icon: null, label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Features') },
guide: { active: false, cssClass: '', group: 'primary', id: 'guide', icon: null, label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Guide') },
features: {
active: true,
cssClass: '',
group: 'primary',
id: 'features',
icon: null,
label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Features')
},
guide: {
active: false,
cssClass: '',
group: 'primary',
id: 'guide',
icon: null,
label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Guide')
}
};
for (const v of Object.values(tabs)) {
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
v.cssClass = v.active ? "active" : "";
v.cssClass = v.active ? 'active' : '';
}
return tabs;
@ -273,11 +286,16 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
const domainInput = htmlElement.querySelector('.domain-input');
const domainTagify = new Tagify(domainInput, {
tagTextProp: "name",
tagTextProp: 'name',
enforceWhitelist: true,
whitelist: Object.keys(SYSTEM.DOMAIN.domains).map(key => {
const domain = SYSTEM.DOMAIN.domains[key];
return { value: key, name: game.i18n.localize(domain.label), src: domain.src, background: domain.background };
return {
value: key,
name: game.i18n.localize(domain.label),
src: domain.src,
background: domain.background
};
}),
maxTags: 2,
callbacks: { invalid: this.onAddTag },
@ -287,15 +305,16 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
enabled: 0,
maxItems: 20,
closeOnSelect: true,
highlightFirst: false,
highlightFirst: false
},
templates: {
tag(tagData){ //z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips?
return `<tag title="${(tagData.title || tagData.value)}"
tag(tagData) {
//z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips?
return `<tag title="${tagData.title || tagData.value}"
contenteditable='false'
spellcheck='false'
tabIndex="${this.settings.a11y.focusableTags ? 0 : -1}"
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ""}"
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ''}"
${this.getAttributes(tagData)}>
<x class="${this.settings.classNames.tagX}" role='button' aria-label='remove tag'></x>
<div>
@ -303,7 +322,8 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
<img src="${tagData.src}"></i>
</div>
</tag>`;
}}
}
}
});
domainTagify.on('change', this.onDomainSelect.bind(this));
@ -319,24 +339,26 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
onAddTag(e) {
if (e.detail.index === 2) {
ui.notifications.info(game.i18n.localize("DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains"));
ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains'));
}
}
async onDomainSelect(event) {
const domains = event.detail?.value ? JSON.parse(event.detail.value) : [];
await this.document.update({ "system.domains": domains.map(x => x.value) });
await this.document.update({ 'system.domains': domains.map(x => x.value) });
this.render(true);
}
static async removeSubclass(_, button) {
await this.document.update({ "system.subclasses": this.document.system.subclasses.filter(x => x.uuid !== button.dataset.subclass)});
await this.document.update({
'system.subclasses': this.document.system.subclasses.filter(x => x.uuid !== button.dataset.subclass)
});
}
static async viewSubclass(_, button) {
@ -345,7 +367,9 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async removeFeature(_, button) {
await this.document.update({ "system.features": this.document.system.features.filter(x => x.uuid !== button.dataset.feature)});
await this.document.update({
'system.features': this.document.system.features.filter(x => x.uuid !== button.dataset.feature)
});
}
static async viewFeature(_, button) {
@ -357,7 +381,9 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
event.stopPropagation();
const type = button.dataset.type;
const path = `system.inventory.${type}`;
await this.document.update({ [path]: this.document.system.inventory[type].filter(x => x.uuid !== button.dataset.item)});
await this.document.update({
[path]: this.document.system.inventory[type].filter(x => x.uuid !== button.dataset.item)
});
}
static async viewItem(_, button) {
@ -367,52 +393,90 @@ export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) {
static async removePrimaryWeapon(event) {
event.stopPropagation();
await this.document.update({ "system.characterGuide.suggestedPrimaryWeapon": null }, { diff: false });
await this.document.update({ 'system.characterGuide.suggestedPrimaryWeapon': null }, { diff: false });
}
static async removeSecondaryWeapon(event) {
event.stopPropagation();
await this.document.update({ "system.characterGuide.suggestedSecondaryWeapon": null }, { diff: false });
await this.document.update({ 'system.characterGuide.suggestedSecondaryWeapon': null }, { diff: false });
}
static async removeArmor(event) {
event.stopPropagation();
await this.document.update({ "system.characterGuide.suggestedArmor": null }, { diff: false });
await this.document.update({ 'system.characterGuide.suggestedArmor': null }, { diff: false });
}
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
const item = await fromUuid(data.uuid);
if (item.type === 'subclass') {
await this.document.update({ "system.subclasses": [...this.document.system.subclasses, { img: item.img, name: item.name, uuid: item.uuid }] });
}
else if(item.type === 'feature') {
await this.document.update({ "system.features": [...this.document.system.features, { img: item.img, name: item.name, uuid: item.uuid }] });
}
else if(item.type === 'weapon'){
await this.document.update({
'system.subclasses': [
...this.document.system.subclasses,
{ img: item.img, name: item.name, uuid: item.uuid }
]
});
} else if (item.type === 'feature') {
await this.document.update({
'system.features': [
...this.document.system.features,
{ img: item.img, name: item.name, uuid: item.uuid }
]
});
} else if (item.type === 'weapon') {
if (event.currentTarget.classList.contains('primary-weapon-section')) {
if(!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary) await this.document.update({ "system.characterGuide.suggestedPrimaryWeapon": { img: item.img, name: item.name, uuid: item.uuid } });
if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary)
await this.document.update({
'system.characterGuide.suggestedPrimaryWeapon': {
img: item.img,
name: item.name,
uuid: item.uuid
}
});
} else if (event.currentTarget.classList.contains('secondary-weapon-section')) {
if(!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary) await this.document.update({ "system.characterGuide.suggestedSecondaryWeapon": { img: item.img, name: item.name, uuid: item.uuid } });
if (!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary)
await this.document.update({
'system.characterGuide.suggestedSecondaryWeapon': {
img: item.img,
name: item.name,
uuid: item.uuid
}
});
}
else if(item.type === 'armor'){
} else if (item.type === 'armor') {
if (event.currentTarget.classList.contains('armor-section')) {
if(!this.document.system.characterGuide.suggestedArmor) await this.document.update({ "system.characterGuide.suggestedArmor": { img: item.img, name: item.name, uuid: item.uuid } });
if (!this.document.system.characterGuide.suggestedArmor)
await this.document.update({
'system.characterGuide.suggestedArmor': { img: item.img, name: item.name, uuid: item.uuid }
});
}
}
else if(event.currentTarget.classList.contains('choice-a-section')){
} else if (event.currentTarget.classList.contains('choice-a-section')) {
if (item.type === 'miscellaneous' || item.type === 'consumable') {
if(this.document.system.inventory.choiceA.length < 2) await this.document.update({ "system.inventory.choiceA": [...this.document.system.inventory.choiceA, { img: item.img, name: item.name, uuid: item.uuid }] });
if (this.document.system.inventory.choiceA.length < 2)
await this.document.update({
'system.inventory.choiceA': [
...this.document.system.inventory.choiceA,
{ img: item.img, name: item.name, uuid: item.uuid }
]
});
}
}
else if(item.type === 'miscellaneous'){
} else if (item.type === 'miscellaneous') {
if (event.currentTarget.classList.contains('take-section')) {
if(this.document.system.inventory.take.length < 3) await this.document.update({ "system.inventory.take": [...this.document.system.inventory.take, { img: item.img, name: item.name, uuid: item.uuid }] });
}
else if(event.currentTarget.classList.contains('choice-b-section')){
if(this.document.system.inventory.choiceB.length < 2) await this.document.update({ "system.inventory.choiceB": [...this.document.system.inventory.choiceB, { img: item.img, name: item.name, uuid: item.uuid }] });
if (this.document.system.inventory.take.length < 3)
await this.document.update({
'system.inventory.take': [
...this.document.system.inventory.take,
{ img: item.img, name: item.name, uuid: item.uuid }
]
});
} else if (event.currentTarget.classList.contains('choice-b-section')) {
if (this.document.system.inventory.choiceB.length < 2)
await this.document.update({
'system.inventory.choiceB': [
...this.document.system.inventory.choiceB,
{ img: item.img, name: item.name, uuid: item.uuid }
]
});
}
}
}

View file

@ -24,7 +24,6 @@
// return context;
// }
// async _handleAction(action, event, button) {
// switch(action){
// case 'editAbility':
@ -62,27 +61,27 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class CommunitySheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-community",
classes: ["daggerheart", "sheet", "heritage"],
id: 'daggerheart-community',
classes: ['daggerheart', 'sheet', 'heritage'],
position: { width: 600 },
actions: {
editAbility: this.editAbility,
deleteAbility: this.deleteAbility,
deleteAbility: this.deleteAbility
},
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
closeOnSubmit: false
},
dragDrop: [{ dragSelector: null, dropSelector: null }],
dragDrop: [{ dragSelector: null, dropSelector: null }]
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/community.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/community.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -92,7 +91,7 @@ export default class CommunitySheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
@ -104,14 +103,21 @@ export default class CommunitySheet extends DaggerheartSheet(ItemSheetV2) {
static async deleteAbility(event, button) {
event.preventDefault();
event.stopPropagation();
await this.item.update({ "system.abilities": this.item.system.abilities.filter(x => x.uuid !== button.dataset.ability) })
await this.item.update({
'system.abilities': this.item.system.abilities.filter(x => x.uuid !== button.dataset.ability)
});
}
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
const item = await fromUuid(data.uuid);
if (item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.community.id) {
await this.document.update({ "system.abilities": [...this.document.system.abilities, { img: item.img, name: item.name, uuid: item.uuid }] });
await this.document.update({
'system.abilities': [
...this.document.system.abilities,
{ img: item.img, name: item.name, uuid: item.uuid }
]
});
}
}
}

View file

@ -26,22 +26,22 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class ConsumableSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-consumable",
classes: ["daggerheart", "sheet", "consumable"],
id: 'daggerheart-consumable',
classes: ['daggerheart', 'sheet', 'consumable'],
position: { width: 480 },
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
},
closeOnSubmit: false
}
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/consumable.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/consumable.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -51,7 +51,7 @@ export default class ConsumableSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
}

View file

@ -17,12 +17,12 @@ export default function DhpApplicationMixin(Base) {
static DEFAULT_OPTIONS = {
position: {
width: 480,
height: "auto"
height: 'auto'
},
actions: {
onEditImage: this._onEditImage
},
dragDrop: [],
dragDrop: []
};
async _prepareContext(_options, objectPath = 'document') {
@ -40,7 +40,7 @@ export default function DhpApplicationMixin(Base) {
const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {};
const fp = new FilePicker({
current,
type: "image",
type: 'image',
redirectToRoot: img ? [img] : [],
callback: async path => this._updateImage.bind(this)(path),
top: this.position.top + 40,
@ -50,7 +50,7 @@ export default function DhpApplicationMixin(Base) {
}
async _updateImage(path) {
await this.document.update({ "img": path });
await this.document.update({ img: path });
}
_createDragDropHandlers() {
@ -69,5 +69,5 @@ export default function DhpApplicationMixin(Base) {
}
_onDrop(event) {}
}
};
}

View file

@ -21,7 +21,6 @@
// return context;
// }
// async _handleAction(action, event, button) {
// switch(action){
// case 'attributeRoll':
@ -39,36 +38,36 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class DomainCardSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-domainCard",
classes: ["daggerheart", "sheet", "domain-card"],
id: 'daggerheart-domainCard',
classes: ['daggerheart', 'sheet', 'domain-card'],
position: { width: 600, height: 600 },
actions: {
addAction: this.addAction,
editAction: this.editAction,
removeAction: this.removeAction,
removeAction: this.removeAction
},
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
},
closeOnSubmit: false
}
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/domainCard.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/domainCard.hbs'
}
};
_getTabs() {
const tabs = {
general: { active: true, cssClass: '', group: 'primary', id: 'general', icon: null, label: 'General' },
actions: { active: false, cssClass: '', group: 'primary', id: 'actions', icon: null, label: 'Actions' },
}
actions: { active: false, cssClass: '', group: 'primary', id: 'actions', icon: null, label: 'Actions' }
};
for (const v of Object.values(tabs)) {
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
v.cssClass = v.active ? "active" : "";
v.cssClass = v.active ? 'active' : '';
}
return tabs;
@ -83,28 +82,37 @@ export default class DomainCardSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
static async addAction() {
const actionIndexes = this.document.system.actions.map(x => x.id.split('-')[2]).sort((a, b) => a - b);
const action = await new DaggerheartAction({
id: `${this.document.id}-Action-${actionIndexes.length > 0 ? actionIndexes[0]+1 : 1}`,
}, {
parent: this.document,
});
await this.document.update({ "system.actions": [...this.document.system.actions, action] });
await (new DaggerheartActionConfig(this.document.system.actions[this.document.system.actions.length-1])).render(true);
const action = await new DaggerheartAction(
{
id: `${this.document.id}-Action-${actionIndexes.length > 0 ? actionIndexes[0] + 1 : 1}`
},
{
parent: this.document
}
);
await this.document.update({ 'system.actions': [...this.document.system.actions, action] });
await new DaggerheartActionConfig(this.document.system.actions[this.document.system.actions.length - 1]).render(
true
);
}
static async editAction(_, button) {
const action = this.document.system.actions[button.dataset.index];
await (new DaggerheartActionConfig(action)).render(true);
await new DaggerheartActionConfig(action).render(true);
}
static async removeAction(event, button) {
event.stopPropagation();
await this.document.update({ "system.actions": this.document.system.actions.filter((_, index) => index !== Number.parseInt(button.dataset.index)) });
await this.document.update({
'system.actions': this.document.system.actions.filter(
(_, index) => index !== Number.parseInt(button.dataset.index)
)
});
}
}

View file

@ -1,8 +1,7 @@
import DaggerheartSheet from "./daggerheart-sheet.mjs";
import DaggerheartSheet from './daggerheart-sheet.mjs';
const { DocumentSheetV2 } = foundry.applications.api;
export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) {
constructor(options) {
super(options);
@ -11,10 +10,10 @@ export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
classes: ["daggerheart", "sheet", "adversary", "environment"],
classes: ['daggerheart', 'sheet', 'adversary', 'environment'],
position: {
width: 600,
height: "auto"
height: 'auto'
},
actions: {
toggleSlider: this.toggleSlider,
@ -23,22 +22,22 @@ export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) {
removeFeature: this.removeFeature,
addTone: this.addTone,
removeTone: this.removeTone,
useFeature: this.useFeature,
useFeature: this.useFeature
},
form: {
handler: this._updateForm,
closeOnSubmit: false,
submitOnChange: true,
submitOnChange: true
}
};
/** @override */
static PARTS = {
form: {
id: "form",
template: "systems/daggerheart/templates/sheets/environment.hbs"
}
id: 'form',
template: 'systems/daggerheart/templates/sheets/environment.hbs'
}
};
/* -------------------------------------------- */
@ -69,15 +68,15 @@ export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) {
}
return acc;
}, []),
}, [])
},
editMode: this.editMode,
config: SYSTEM,
}
config: SYSTEM
};
}
static async _updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
@ -92,10 +91,12 @@ export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) {
}
static async addFeature() {
const result = await this.document.createEmbeddedDocuments("Item", [{
const result = await this.document.createEmbeddedDocuments('Item', [
{
name: game.i18n.localize('DAGGERHEART.Sheets.Environment.NewFeature'),
type: 'feature',
}]);
type: 'feature'
}
]);
await result[0].sheet.render(true);
}
@ -105,23 +106,27 @@ export default class DhpEnvironment extends DaggerheartSheet(DocumentSheetV2) {
}
static async addTone() {
await this.document.update({ "system.toneAndFeel": [...this.document.system.toneAndFeel, ''] });
await this.document.update({ 'system.toneAndFeel': [...this.document.system.toneAndFeel, ''] });
}
static async removeTone(button) {
await this.document.update({ "system.toneAndFeel": this.document.system.toneAndFeel.filter((_, index) => index !== Number.parseInt(button.dataset.tone) )});
await this.document.update({
'system.toneAndFeel': this.document.system.toneAndFeel.filter(
(_, index) => index !== Number.parseInt(button.dataset.tone)
)
});
}
static async useFeature(_, button) {
const item = this.document.items.find(x => x.uuid === button.dataset.feature);
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
content: await renderTemplate("systems/daggerheart/templates/chat/ability-use.hbs", {
title: game.i18n.format("DAGGERHEART.Chat.EnvironmentTitle", { actionType: button.dataset.actionType }),
card: { name: item.name, img: item.img, description: item.system.description },
}),
content: await renderTemplate('systems/daggerheart/templates/chat/ability-use.hbs', {
title: game.i18n.format('DAGGERHEART.Chat.EnvironmentTitle', { actionType: button.dataset.actionType }),
card: { name: item.name, img: item.img, description: item.system.description }
})
});
cls.create(msg.toObject());

View file

@ -12,39 +12,39 @@ export default class FeatureSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-feature",
classes: ["daggerheart", "sheet", "feature"],
id: 'daggerheart-feature',
classes: ['daggerheart', 'sheet', 'feature'],
position: { width: 600, height: 600 },
actions: {
addEffect: this.addEffect,
removeEffect: this.removeEffect,
addAction: this.addAction,
editAction: this.editAction,
removeAction: this.removeAction,
removeAction: this.removeAction
},
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
},
closeOnSubmit: false
}
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/feature.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/feature.hbs'
}
};
_getTabs() {
const tabs = {
features: { active: true, cssClass: '', group: 'primary', id: 'features', icon: null, label: 'Features' },
effects: { active: false, cssClass: '', group: 'primary', id: 'effects', icon: null, label: 'Effects' },
actions: { active: false, cssClass: '', group: 'primary', id: 'actions', icon: null, label: 'Actions' },
}
actions: { active: false, cssClass: '', group: 'primary', id: 'actions', icon: null, label: 'Actions' }
};
for (const v of Object.values(tabs)) {
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
v.cssClass = v.active ? "active" : "";
v.cssClass = v.active ? 'active' : '';
}
return tabs;
@ -52,14 +52,13 @@ export default class FeatureSheet extends DaggerheartSheet(ItemSheetV2) {
_attachPartListeners(partId, htmlElement, options) {
super._attachPartListeners(partId, htmlElement, options);
$(htmlElement).find(".effect-select").on("change", this.effectSelect.bind(this));
$(htmlElement).find('.effect-select').on('change', this.effectSelect.bind(this));
}
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
context.document = this.document;
context.tabs = this._getTabs(),
context.generalConfig = SYSTEM.GENERAL;
(context.tabs = this._getTabs()), (context.generalConfig = SYSTEM.GENERAL);
context.itemConfig = SYSTEM.ITEM;
context.properties = SYSTEM.ACTOR.featureProperties;
context.dice = SYSTEM.GENERAL.diceTypes;
@ -70,7 +69,7 @@ export default class FeatureSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
@ -90,7 +89,7 @@ export default class FeatureSheet extends DaggerheartSheet(ItemSheetV2) {
...rest
}
};
await this.item.update({ "system.effects": update });
await this.item.update({ 'system.effects': update });
}
static async removeEffect(_, button) {
@ -100,17 +99,23 @@ export default class FeatureSheet extends DaggerheartSheet(ItemSheetV2) {
static async addAction() {
const action = await new DaggerheartAction({}, { parent: this.document });
await this.document.update({ "system.actions": [...this.document.system.actions, action] });
await (new DaggerheartActionConfig(this.document.system.actions[this.document.system.actions.length-1])).render(true);
await this.document.update({ 'system.actions': [...this.document.system.actions, action] });
await new DaggerheartActionConfig(this.document.system.actions[this.document.system.actions.length - 1]).render(
true
);
}
static async editAction(_, button) {
const action = this.document.system.actions[button.dataset.index];
await (new DaggerheartActionConfig(action)).render(true);
await new DaggerheartActionConfig(action).render(true);
}
static async removeAction(event, button) {
event.stopPropagation();
await this.document.update({ "system.actions": this.document.system.actions.filter((_, index) => index !== Number.parseInt(button.dataset.index)) });
await this.document.update({
'system.actions': this.document.system.actions.filter(
(_, index) => index !== Number.parseInt(button.dataset.index)
)
});
}
}

View file

@ -26,22 +26,22 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class MiscellaneousSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-miscellaneous",
classes: ["daggerheart", "sheet", "miscellaneous"],
id: 'daggerheart-miscellaneous',
classes: ['daggerheart', 'sheet', 'miscellaneous'],
position: { width: 400 },
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
},
closeOnSubmit: false
}
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/miscellaneous.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/miscellaneous.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -51,7 +51,7 @@ export default class MiscellaneousSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
}

File diff suppressed because it is too large Load diff

View file

@ -79,35 +79,63 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-subclass",
classes: ["daggerheart", "sheet", "subclass"],
id: 'daggerheart-subclass',
classes: ['daggerheart', 'sheet', 'subclass'],
position: { width: 600 },
actions: {
editAbility: this.editAbility,
deleteFeatureAbility: this.deleteFeatureAbility,
deleteFeatureAbility: this.deleteFeatureAbility
},
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
closeOnSubmit: false
},
dragDrop: [
{ dragSelector: null, dropSelector: '.foundation-tab' },
{ dragSelector: null, dropSelector: '.specialization-tab' },
{ dragSelector: null, dropSelector: '.mastery-tab' }
],
]
};
_getTabs() {
const tabs = {
general: { active: true, cssClass: '', group: 'primary', id: 'general', icon: null, label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.General') },
foundation: { active: false, cssClass: '', group: 'primary', id: 'foundation', icon: null, label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Foundation') },
specialization: { active: false, cssClass: '', group: 'primary', id: 'specialization', icon: null, label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Specialization') },
mastery: { active: false, cssClass: '', group: 'primary', id: 'mastery', icon: null, label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Mastery') },
general: {
active: true,
cssClass: '',
group: 'primary',
id: 'general',
icon: null,
label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.General')
},
foundation: {
active: false,
cssClass: '',
group: 'primary',
id: 'foundation',
icon: null,
label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Foundation')
},
specialization: {
active: false,
cssClass: '',
group: 'primary',
id: 'specialization',
icon: null,
label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Specialization')
},
mastery: {
active: false,
cssClass: '',
group: 'primary',
id: 'mastery',
icon: null,
label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Mastery')
}
};
for (const v of Object.values(tabs)) {
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
v.cssClass = v.active ? "active" : "";
v.cssClass = v.active ? 'active' : '';
}
return tabs;
@ -115,10 +143,10 @@ export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/subclass.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/subclass.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -130,7 +158,7 @@ export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
@ -144,7 +172,9 @@ export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
event.stopPropagation();
const feature = button.dataset.feature;
const newAbilities = this.document.system[`${feature}Feature`].abilities.filter(x => x.uuid !== button.dataset.ability);
const newAbilities = this.document.system[`${feature}Feature`].abilities.filter(
x => x.uuid !== button.dataset.ability
);
const path = `system.${feature}Feature.abilities`;
await this.document.update({ [path]: newAbilities });
@ -155,13 +185,23 @@ export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) {
const item = await fromUuid(data.uuid);
if (item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id) {
if (event.currentTarget.classList.contains('foundation-tab')) {
await this.document.update({ "system.foundationFeature.abilities": [...this.document.system.foundationFeature.abilities, item.system] });
}
else if(event.currentTarget.classList.contains('specialization-tab')){
await this.document.update({ "system.specializationFeature.abilities": [...this.document.system.specializationFeature.abilities, data.system] });
}
else if(event.currentTarget.classList.contains('mastery-tab')){
await this.document.update({ "system.masteryFeature.abilities": [...this.document.system.masteryFeature.abilities, data.system] });
await this.document.update({
'system.foundationFeature.abilities': [
...this.document.system.foundationFeature.abilities,
item.system
]
});
} else if (event.currentTarget.classList.contains('specialization-tab')) {
await this.document.update({
'system.specializationFeature.abilities': [
...this.document.system.specializationFeature.abilities,
data.system
]
});
} else if (event.currentTarget.classList.contains('mastery-tab')) {
await this.document.update({
'system.masteryFeature.abilities': [...this.document.system.masteryFeature.abilities, data.system]
});
}
}
}

View file

@ -20,7 +20,6 @@
// return context;
// }
// async _handleAction(action, event, button) {
// switch(action){
// }
@ -33,22 +32,22 @@ const { ItemSheetV2 } = foundry.applications.sheets;
export default class WeaponSheet extends DaggerheartSheet(ItemSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
id: "daggerheart-weapon",
classes: ["daggerheart", "sheet", "weapon"],
id: 'daggerheart-weapon',
classes: ['daggerheart', 'sheet', 'weapon'],
position: { width: 400 },
form: {
handler: this.updateForm,
submitOnChange: true,
closeOnSubmit: false,
},
closeOnSubmit: false
}
};
static PARTS = {
form: {
id: "feature",
template: "systems/daggerheart/templates/sheets/weapon.hbs"
}
id: 'feature',
template: 'systems/daggerheart/templates/sheets/weapon.hbs'
}
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
@ -59,7 +58,7 @@ export default class WeaponSheet extends DaggerheartSheet(ItemSheetV2) {
}
static async updateForm(event, _, formData) {
await this.document.update(formData.object)
await this.document.update(formData.object);
this.render();
}
}

View file

@ -1,17 +1,17 @@
export const actionTypes = {
damage: {
id: "damage",
name: "DAGGERHEART.Effects.Types.Health.Name"
},
id: 'damage',
name: 'DAGGERHEART.Effects.Types.Health.Name'
}
};
export const targetTypes = {
self: {
id: 'self',
label: 'Self',
label: 'Self'
},
other: {
id: 'other',
label: 'Other',
},
label: 'Other'
}
};

View file

@ -1,164 +1,191 @@
export const abilities = {
agility: {
label: "DAGGERHEART.Abilities.Agility.Name",
verbs: ["DAGGERHEART.Abilities.Agility.Verb.Sprint", "DAGGERHEART.Abilities.Agility.Verb.Leap", "DAGGERHEART.Abilities.Agility.Verb.Maneuver"],
label: 'DAGGERHEART.Abilities.Agility.Name',
verbs: [
'DAGGERHEART.Abilities.Agility.Verb.Sprint',
'DAGGERHEART.Abilities.Agility.Verb.Leap',
'DAGGERHEART.Abilities.Agility.Verb.Maneuver'
]
},
strength: {
label: "DAGGERHEART.Abilities.Strength.Name",
verbs: ["DAGGERHEART.Abilities.Strength.Verb.Lift", "DAGGERHEART.Abilities.Strength.Verb.Smash", "DAGGERHEART.Abilities.Strength.Verb.Grapple"],
label: 'DAGGERHEART.Abilities.Strength.Name',
verbs: [
'DAGGERHEART.Abilities.Strength.Verb.Lift',
'DAGGERHEART.Abilities.Strength.Verb.Smash',
'DAGGERHEART.Abilities.Strength.Verb.Grapple'
]
},
finesse: {
label: "DAGGERHEART.Abilities.Finesse.Name",
verbs: ["DAGGERHEART.Abilities.Finesse.Verb.Control", "DAGGERHEART.Abilities.Finesse.Verb.Hide", "DAGGERHEART.Abilities.Finesse.Verb.Tinker"],
label: 'DAGGERHEART.Abilities.Finesse.Name',
verbs: [
'DAGGERHEART.Abilities.Finesse.Verb.Control',
'DAGGERHEART.Abilities.Finesse.Verb.Hide',
'DAGGERHEART.Abilities.Finesse.Verb.Tinker'
]
},
instinct: {
label: "DAGGERHEART.Abilities.Instinct.Name",
verbs: ["DAGGERHEART.Abilities.Instinct.Verb.Perceive", "DAGGERHEART.Abilities.Instinct.Verb.Sense", "DAGGERHEART.Abilities.Instinct.Verb.Navigate"],
label: 'DAGGERHEART.Abilities.Instinct.Name',
verbs: [
'DAGGERHEART.Abilities.Instinct.Verb.Perceive',
'DAGGERHEART.Abilities.Instinct.Verb.Sense',
'DAGGERHEART.Abilities.Instinct.Verb.Navigate'
]
},
presence: {
label: "DAGGERHEART.Abilities.Presence.Name",
verbs: ["DAGGERHEART.Abilities.Presence.Verb.Charm", "DAGGERHEART.Abilities.Presence.Verb.Perform", "DAGGERHEART.Abilities.Presence.Verb.Deceive"],
label: 'DAGGERHEART.Abilities.Presence.Name',
verbs: [
'DAGGERHEART.Abilities.Presence.Verb.Charm',
'DAGGERHEART.Abilities.Presence.Verb.Perform',
'DAGGERHEART.Abilities.Presence.Verb.Deceive'
]
},
knowledge: {
label: "DAGGERHEART.Abilities.Knowledge.Name",
verbs: ["DAGGERHEART.Abilities.Knowledge.Verb.Recall", "DAGGERHEART.Abilities.Knowledge.Verb.Analyze", "DAGGERHEART.Abilities.Knowledge.Verb.Comprehend"],
},
label: 'DAGGERHEART.Abilities.Knowledge.Name',
verbs: [
'DAGGERHEART.Abilities.Knowledge.Verb.Recall',
'DAGGERHEART.Abilities.Knowledge.Verb.Analyze',
'DAGGERHEART.Abilities.Knowledge.Verb.Comprehend'
]
}
};
export const featureProperties = {
agility: {
name: "DAGGERHEART.Abilities.Agility.Name",
path: actor => actor.system.attributes.agility.data.value,
name: 'DAGGERHEART.Abilities.Agility.Name',
path: actor => actor.system.attributes.agility.data.value
},
strength: {
name: "DAGGERHEART.Abilities.Strength.Name",
path: actor => actor.system.attributes.strength.data.value,
name: 'DAGGERHEART.Abilities.Strength.Name',
path: actor => actor.system.attributes.strength.data.value
},
finesse: {
name: "DAGGERHEART.Abilities.Finesse.Name",
path: actor => actor.system.attributes.finesse.data.value,
name: 'DAGGERHEART.Abilities.Finesse.Name',
path: actor => actor.system.attributes.finesse.data.value
},
instinct: {
name: "DAGGERHEART.Abilities.Instinct.Name",
path: actor => actor.system.attributes.instinct.data.value,
name: 'DAGGERHEART.Abilities.Instinct.Name',
path: actor => actor.system.attributes.instinct.data.value
},
presence: {
name: "DAGGERHEART.Abilities.Presence.Name",
path: actor => actor.system.attributes.presence.data.value,
name: 'DAGGERHEART.Abilities.Presence.Name',
path: actor => actor.system.attributes.presence.data.value
},
knowledge: {
name: "DAGGERHEART.Abilities.Knowledge.Name",
path: actor => actor.system.attributes.knowledge.data.value,
name: 'DAGGERHEART.Abilities.Knowledge.Name',
path: actor => actor.system.attributes.knowledge.data.value
},
spellcastingTrait: {
name: "DAGGERHEART.FeatureProperty.SpellcastingTrait",
path: actor => actor.system.attributes[actor.system.subclass.system.spellcastingTrait].data.value,
},
name: 'DAGGERHEART.FeatureProperty.SpellcastingTrait',
path: actor => actor.system.attributes[actor.system.subclass.system.spellcastingTrait].data.value
}
};
export const adversaryTypes = {
bruiser: {
name: "DAGGERHEART.Adversary.Bruiser.Name",
description: "DAGGERHEART.Adversary.Bruiser.Description"
name: 'DAGGERHEART.Adversary.Bruiser.Name',
description: 'DAGGERHEART.Adversary.Bruiser.Description'
},
horde: {
name: "DAGGERHEART.Adversary.Horde.Name",
description: "DAGGERHEART.Adversary.Horde.Description"
name: 'DAGGERHEART.Adversary.Horde.Name',
description: 'DAGGERHEART.Adversary.Horde.Description'
},
leader: {
name: "DAGGERHEART.Adversary.Leader.Name",
description: "DAGGERHEART.Adversary.Leader.Description"
name: 'DAGGERHEART.Adversary.Leader.Name',
description: 'DAGGERHEART.Adversary.Leader.Description'
},
minion: {
name: "DAGGERHEART.Adversary.Minion.Name",
description: "DAGGERHEART.Adversary.Minion.Description"
name: 'DAGGERHEART.Adversary.Minion.Name',
description: 'DAGGERHEART.Adversary.Minion.Description'
},
ranged: {
name: "DAGGERHEART.Adversary.Ranged.Name",
description: "DAGGERHEART.Adversary.Ranged.Description"
name: 'DAGGERHEART.Adversary.Ranged.Name',
description: 'DAGGERHEART.Adversary.Ranged.Description'
},
skulker: {
name: "DAGGERHEART.Adversary.Skulker.Name",
description: "DAGGERHEART.Adversary.Skulker.Description"
name: 'DAGGERHEART.Adversary.Skulker.Name',
description: 'DAGGERHEART.Adversary.Skulker.Description'
},
social: {
name: "DAGGERHEART.Adversary.Social.Name",
description: "DAGGERHEART.Adversary.Social.Description"
name: 'DAGGERHEART.Adversary.Social.Name',
description: 'DAGGERHEART.Adversary.Social.Description'
},
solo: {
name: "DAGGERHEART.Adversary.Solo.Name",
description: "DAGGERHEART.Adversary.Solo.Description"
name: 'DAGGERHEART.Adversary.Solo.Name',
description: 'DAGGERHEART.Adversary.Solo.Description'
},
standard: {
name: "DAGGERHEART.Adversary.Standard.Name",
description: "DAGGERHEART.Adversary.Standard.Description"
name: 'DAGGERHEART.Adversary.Standard.Name',
description: 'DAGGERHEART.Adversary.Standard.Description'
},
support: {
name: "DAGGERHEART.Adversary.Support.Name",
description: "DAGGERHEART.Adversary.Support.Description"
},
name: 'DAGGERHEART.Adversary.Support.Name',
description: 'DAGGERHEART.Adversary.Support.Description'
}
};
export const adversaryTraits = {
relentless: {
name: "DAGGERHEART.Adversary.Trait..Name",
description: "DAGGERHEART.Adversary.Trait..Description",
tip: "DAGGERHEART.Adversary.Trait..Tip",
name: 'DAGGERHEART.Adversary.Trait..Name',
description: 'DAGGERHEART.Adversary.Trait..Description',
tip: 'DAGGERHEART.Adversary.Trait..Tip'
},
slow: {
name: "DAGGERHEART.Adversary.Trait..Name",
description: "DAGGERHEART.Adversary.Trait..Description",
tip: "DAGGERHEART.Adversary.Trait..Tip",
name: 'DAGGERHEART.Adversary.Trait..Name',
description: 'DAGGERHEART.Adversary.Trait..Description',
tip: 'DAGGERHEART.Adversary.Trait..Tip'
},
minion: {
name: "DAGGERHEART.Adversary.Trait..Name",
description: "DAGGERHEART.Adversary.Trait..Description",
tip: "DAGGERHEART.Adversary.Trait..Tip",
},
name: 'DAGGERHEART.Adversary.Trait..Name',
description: 'DAGGERHEART.Adversary.Trait..Description',
tip: 'DAGGERHEART.Adversary.Trait..Tip'
}
};
export const levelChoices = {
attributes: {
name: 'attributes',
title: '',
choices: [],
choices: []
},
hitPointSlots: {
name: 'hitPointSlots',
title: '',
choices: [],
choices: []
},
stressSlots: {
name: 'stressSlots',
title: '',
choices: [],
choices: []
},
experiences: {
name: 'experiences',
title: '',
choices: 'system.experiences',
nrChoices: 2,
nrChoices: 2
},
proficiency: {
name: 'proficiency',
title: '',
choices: [],
choices: []
},
armorOrEvasionSlot: {
name: 'armorOrEvasionSlot',
title: 'Permanently add one Armor Slot or take +1 to your Evasion',
choices: [{ name: 'Armor Marks +1', path: 'armor' }, { name: 'Evasion +1', path: 'evasion' }],
nrChoices: 1,
choices: [
{ name: 'Armor Marks +1', path: 'armor' },
{ name: 'Evasion +1', path: 'evasion' }
],
nrChoices: 1
},
majorDamageThreshold2: {
name: 'majorDamageThreshold2',
title: '',
choices: [],
choices: []
},
severeDamageThreshold2: {
name: 'severeDamageThreshold2',
title: '',
choices: [],
choices: []
},
// minorDamageThreshold2: {
// name: 'minorDamageThreshold2',
@ -168,7 +195,7 @@ export const levelChoices = {
severeDamageThreshold3: {
name: 'severeDamageThreshold3',
title: '',
choices: [],
choices: []
},
// major2OrSevere4DamageThreshold: {
// name: 'major2OrSevere4DamageThreshold',
@ -185,7 +212,7 @@ export const levelChoices = {
severeDamageThreshold4: {
name: 'severeDamageThreshold4',
title: '',
choices: [],
choices: []
},
// majorDamageThreshold1: {
// name: 'majorDamageThreshold2',
@ -195,161 +222,161 @@ export const levelChoices = {
subclass: {
name: 'subclass',
title: 'Select subclass to upgrade',
choices: [],
choices: []
},
multiclass: {
name: 'multiclass',
title: '',
choices: [{}],
choices: [{}]
}
};
export const levelupData = {
tier1: {
id: "2_4",
id: '2_4',
tier: 1,
levels: [2, 3, 4],
label: 'DAGGERHEART.LevelUp.Tier1.Label',
info: "DAGGERHEART.LevelUp.Tier1.InfoLabel",
pretext: "DAGGERHEART.LevelUp.Tier1.Pretext",
posttext: "DAGGERHEART.LevelUp.Tier1.Posttext",
info: 'DAGGERHEART.LevelUp.Tier1.InfoLabel',
pretext: 'DAGGERHEART.LevelUp.Tier1.Pretext',
posttext: 'DAGGERHEART.LevelUp.Tier1.Posttext',
choices: {
[levelChoices.attributes.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Attributes",
maxChoices: 3,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Attributes',
maxChoices: 3
},
[levelChoices.hitPointSlots.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.HitPointSlots",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.HitPointSlots',
maxChoices: 1
},
[levelChoices.stressSlots.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.StressSlots",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.StressSlots',
maxChoices: 1
},
[levelChoices.experiences.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Experiences",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Experiences',
maxChoices: 1
},
[levelChoices.proficiency.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Proficiency",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Proficiency',
maxChoices: 1
},
[levelChoices.armorOrEvasionSlot.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.ArmorOrEvasionSlot",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.ArmorOrEvasionSlot',
maxChoices: 1
},
[levelChoices.majorDamageThreshold2.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.MajorDamageThreshold2",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.MajorDamageThreshold2',
maxChoices: 1
},
[levelChoices.severeDamageThreshold2.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.SevereDamageThreshold2",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.SevereDamageThreshold2',
maxChoices: 1
}
}
},
tier2: {
id: "5_7",
id: '5_7',
tier: 2,
levels: [5, 6, 7],
label: 'DAGGERHEART.LevelUp.Tier2.Label',
info: "DAGGERHEART.LevelUp.Tier2.InfoLabel",
pretext: "DAGGERHEART.LevelUp.Tier2.Pretext",
posttext: "DAGGERHEART.LevelUp.Tier2.Posttext",
info: 'DAGGERHEART.LevelUp.Tier2.InfoLabel',
pretext: 'DAGGERHEART.LevelUp.Tier2.Pretext',
posttext: 'DAGGERHEART.LevelUp.Tier2.Posttext',
choices: {
[levelChoices.attributes.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Attributes",
maxChoices: 3,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Attributes',
maxChoices: 3
},
[levelChoices.hitPointSlots.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.HitPointSlots",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.HitPointSlots',
maxChoices: 2
},
[levelChoices.stressSlots.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.StressSlots",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.StressSlots',
maxChoices: 2
},
[levelChoices.experiences.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Experiences",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Experiences',
maxChoices: 1
},
[levelChoices.proficiency.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Proficiency",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Proficiency',
maxChoices: 2
},
[levelChoices.armorOrEvasionSlot.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.ArmorOrEvasionSlot",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.ArmorOrEvasionSlot',
maxChoices: 2
},
[levelChoices.majorDamageThreshold2.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.MajorDamageThreshold2",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.MajorDamageThreshold2',
maxChoices: 1
},
[levelChoices.severeDamageThreshold3.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.SevereDamageThreshold3",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.SevereDamageThreshold3',
maxChoices: 1
},
[levelChoices.subclass.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Subclass",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Subclass',
maxChoices: 1
},
[levelChoices.multiclass.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Multiclass",
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Multiclass',
maxChoices: 1,
cost: 2,
},
},
cost: 2
}
}
},
tier3: {
id: "8_10",
id: '8_10',
tier: 3,
levels: [8, 9, 10],
label: 'DAGGERHEART.LevelUp.Tier3.Label',
info: "DAGGERHEART.LevelUp.Tier3.InfoLabel",
pretext: "DAGGERHEART.LevelUp.Tier3.Pretext",
posttext: "DAGGERHEART.LevelUp.Tier3.Posttext",
info: 'DAGGERHEART.LevelUp.Tier3.InfoLabel',
pretext: 'DAGGERHEART.LevelUp.Tier3.Pretext',
posttext: 'DAGGERHEART.LevelUp.Tier3.Posttext',
choices: {
[levelChoices.attributes.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Attributes",
maxChoices: 3,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Attributes',
maxChoices: 3
},
[levelChoices.hitPointSlots.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.HitPointSlots",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.HitPointSlots',
maxChoices: 2
},
[levelChoices.stressSlots.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.StressSlots",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.StressSlots',
maxChoices: 2
},
[levelChoices.experiences.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Experiences",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Experiences',
maxChoices: 1
},
[levelChoices.proficiency.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Proficiency",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Proficiency',
maxChoices: 2
},
[levelChoices.armorOrEvasionSlot.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.ArmorOrEvasionSlot",
maxChoices: 2,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.ArmorOrEvasionSlot',
maxChoices: 2
},
[levelChoices.majorDamageThreshold2.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.MajorDamageThreshold2",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.MajorDamageThreshold2',
maxChoices: 1
},
[levelChoices.severeDamageThreshold4.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.SevereDamageThreshold4",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.SevereDamageThreshold4',
maxChoices: 1
},
[levelChoices.subclass.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Subclass",
maxChoices: 1,
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Subclass',
maxChoices: 1
},
[levelChoices.multiclass.name]: {
description: "DAGGERHEART.LevelUp.ChoiceDescriptions.Multiclass",
description: 'DAGGERHEART.LevelUp.ChoiceDescriptions.Multiclass',
maxChoices: 1,
cost: 2,
},
},
cost: 2
}
}
}
};

View file

@ -3,99 +3,99 @@ export const domains = {
id: 'arcana',
label: 'Arcana',
src: 'icons/magic/symbols/circled-gem-pink.webp',
description: 'DAGGERHEART.Domains.Arcana',
description: 'DAGGERHEART.Domains.Arcana'
},
blade: {
id: 'blade',
label: 'Blade',
src: 'icons/weapons/swords/sword-broad-crystal-paired.webp',
description: 'DAGGERHEART.Domains.Blade',
description: 'DAGGERHEART.Domains.Blade'
},
bone: {
id: 'bone',
label: 'Bone',
src: 'icons/skills/wounds/bone-broken-marrow-red.webp',
description: 'DAGGERHEART.Domains.Bone',
description: 'DAGGERHEART.Domains.Bone'
},
codex: {
id: 'codex',
label: 'Codex',
src: 'icons/sundries/books/book-embossed-jewel-gold-purple.webp',
description: 'DAGGERHEART.Domains.Codex',
description: 'DAGGERHEART.Domains.Codex'
},
grace: {
id: 'grace',
label: 'Grace',
src: 'icons/skills/movement/feet-winged-boots-glowing-yellow.webp',
description: 'DAGGERHEART.Domains.Grace',
description: 'DAGGERHEART.Domains.Grace'
},
midnight: {
id: 'midnight',
label: 'Midnight',
src: 'icons/environment/settlement/watchtower-castle-night.webp',
background: 'systems/daggerheart/assets/backgrounds/MidnightBackground.webp',
description: 'DAGGERHEART.Domains.Midnight',
description: 'DAGGERHEART.Domains.Midnight'
},
sage: {
id: 'sage',
label: 'Sage',
src: 'icons/sundries/misc/pipe-wooden-straight-brown.webp',
description: 'DAGGERHEART.Domains.Sage',
description: 'DAGGERHEART.Domains.Sage'
},
splendor: {
id: 'splendor',
label: 'Splendor',
src: 'icons/magic/control/control-influence-crown-gold.webp',
description: 'DAGGERHEART.Domains.Splendor',
description: 'DAGGERHEART.Domains.Splendor'
},
valor: {
id: 'valor',
label: 'Valor',
src: 'icons/magic/control/control-influence-rally-purple.webp',
description: 'DAGGERHEART.Domains.Valor',
},
description: 'DAGGERHEART.Domains.Valor'
}
};
export const classDomainMap = {
rogue: [domains.midnight, domains.grace],
rogue: [domains.midnight, domains.grace]
};
export const subclassMap = {
syndicate: {
id: 'syndicate',
label: 'Syndicate',
label: 'Syndicate'
},
nightwalker: {
id: 'nightwalker',
label: 'Nightwalker',
},
label: 'Nightwalker'
}
};
export const classMap = {
rogue: {
label: "Rogue",
subclasses: [subclassMap.syndicate.id, subclassMap.nightwalker.id],
label: 'Rogue',
subclasses: [subclassMap.syndicate.id, subclassMap.nightwalker.id]
},
seraph: {
label: "Seraph",
label: 'Seraph',
subclasses: []
},
}
};
export const cardTypes = {
ability: {
id: 'ability',
label: "DAGGERHEART.Domain.CardTypes.Ability",
img: "",
label: 'DAGGERHEART.Domain.CardTypes.Ability',
img: ''
},
spell: {
id: 'spell',
label: "DAGGERHEART.Domain.CardTypes.Spell",
img: ""
label: 'DAGGERHEART.Domain.CardTypes.Spell',
img: ''
},
grimoire: {
id: 'grimoire',
label: "DAGGERHEART.Domain.CardTypes.Grimoire",
img: ""
label: 'DAGGERHEART.Domain.CardTypes.Grimoire',
img: ''
}
};

View file

@ -1,64 +1,64 @@
import { range } from "./generalConfig.mjs";
import { range } from './generalConfig.mjs';
export const valueTypes = {
numberString: {
id: 'numberString',
id: 'numberString'
},
select: {
id: 'select',
}
id: 'select'
}
};
export const parseTypes = {
string: {
id: 'string',
id: 'string'
},
number: {
id: 'number',
},
id: 'number'
}
};
export const applyLocations = {
attackRoll: {
id: 'attackRoll',
name: "DAGGERHEART.Effects.ApplyLocations.AttackRoll.Name",
name: 'DAGGERHEART.Effects.ApplyLocations.AttackRoll.Name'
},
damageRoll: {
id: 'damageRoll',
name: "DAGGERHEART.Effects.ApplyLocations.DamageRoll.Name",
name: 'DAGGERHEART.Effects.ApplyLocations.DamageRoll.Name'
}
};
export const effectTypes = {
health: {
id: "health",
name: "DAGGERHEART.Effects.Types.Health.Name",
id: 'health',
name: 'DAGGERHEART.Effects.Types.Health.Name',
values: [],
valueType: valueTypes.numberString.id,
parseType: parseTypes.number.id,
parseType: parseTypes.number.id
},
stress: {
id: "stress",
name: "DAGGERHEART.Effects.Types.Stress.Name",
id: 'stress',
name: 'DAGGERHEART.Effects.Types.Stress.Name',
valueType: valueTypes.numberString.id,
parseType: parseTypes.number.id,
parseType: parseTypes.number.id
},
reach: {
id: "reach",
name: "DAGGERHEART.Effects.Types.Reach.Name",
id: 'reach',
name: 'DAGGERHEART.Effects.Types.Reach.Name',
valueType: valueTypes.select.id,
parseType: parseTypes.string.id,
options: Object.keys(range).map(x => ({ name: range[x].name, value: x }))
},
damage: {
id: "damage",
name: "DAGGERHEART.Effects.Types.Damage.Name",
id: 'damage',
name: 'DAGGERHEART.Effects.Types.Damage.Name',
valueType: valueTypes.numberString.id,
parseType: parseTypes.string.id,
appliesOn: applyLocations.damageRoll.id,
applyLocationChoices: {
[applyLocations.damageRoll.id]: applyLocations.damageRoll.name,
[applyLocations.attackRoll.id]: applyLocations.attackRoll.name,
},
[applyLocations.attackRoll.id]: applyLocations.attackRoll.name
}
}
};

View file

@ -1,170 +1,170 @@
export const range = {
melee: {
label: "DAGGERHEART.Range.Melee.Name",
description: "DAGGERHEART.Range.Melee.Description",
label: 'DAGGERHEART.Range.Melee.Name',
description: 'DAGGERHEART.Range.Melee.Description',
distance: 1
},
veryClose: {
label: "DAGGERHEART.Range.VeryClose.Name",
description: "DAGGERHEART.Range.VeryClose.Description",
label: 'DAGGERHEART.Range.VeryClose.Name',
description: 'DAGGERHEART.Range.VeryClose.Description',
distance: 3
},
close: {
label: "DAGGERHEART.Range.Close.Name",
description: "DAGGERHEART.Range.Close.Description",
label: 'DAGGERHEART.Range.Close.Name',
description: 'DAGGERHEART.Range.Close.Description',
distance: 10
},
far: {
label: "DAGGERHEART.Range.Far.Name",
description: "DAGGERHEART.Range.Far.Description",
label: 'DAGGERHEART.Range.Far.Name',
description: 'DAGGERHEART.Range.Far.Description',
distance: 20
},
veryFar: {
label: "DAGGERHEART.Range.VeryFar.Name",
description: "DAGGERHEART.Range.VeryFar.Description",
label: 'DAGGERHEART.Range.VeryFar.Name',
description: 'DAGGERHEART.Range.VeryFar.Description',
distance: 30
}
}
};
export const burden = {
oneHanded: "DAGGERHEART.Burden.OneHanded",
twoHanded: "DAGGERHEART.Burden.TwoHanded"
}
oneHanded: 'DAGGERHEART.Burden.OneHanded',
twoHanded: 'DAGGERHEART.Burden.TwoHanded'
};
export const damageTypes = {
physical: {
id: 'physical',
label: "DAGGERHEART.DamageType.Physical.Name",
abbreviation: "DAGGERHEART.DamageType.Physical.Abbreviation",
label: 'DAGGERHEART.DamageType.Physical.Name',
abbreviation: 'DAGGERHEART.DamageType.Physical.Abbreviation'
},
magical: {
id: 'magical',
label: "DAGGERHEART.DamageType.Magical.Name",
abbreviation: "DAGGERHEART.DamageType.Magical.Abbreviation",
},
label: 'DAGGERHEART.DamageType.Magical.Name',
abbreviation: 'DAGGERHEART.DamageType.Magical.Abbreviation'
}
};
export const healingTypes = {
health: {
id: 'health',
label: "DAGGERHEART.HealingType.HitPoints.Name",
abbreviation: "DAGGERHEART.HealingType.HitPoints.Abbreviation"
label: 'DAGGERHEART.HealingType.HitPoints.Name',
abbreviation: 'DAGGERHEART.HealingType.HitPoints.Abbreviation'
},
stress: {
id: 'stress',
label: "DAGGERHEART.HealingType.Stress.Name",
abbreviation: "DAGGERHEART.HealingType.Stress.Abbreviation"
},
label: 'DAGGERHEART.HealingType.Stress.Name',
abbreviation: 'DAGGERHEART.HealingType.Stress.Abbreviation'
}
};
export const conditions = {
vulnerable: {
id: 'vulnerable',
name: "DAGGERHEART.Condition.Vulnerable.Name",
icon: "icons/magic/control/silhouette-fall-slip-prone.webp",
description: "DAGGERHEART.Condition.Vulnerable.Description"
name: 'DAGGERHEART.Condition.Vulnerable.Name',
icon: 'icons/magic/control/silhouette-fall-slip-prone.webp',
description: 'DAGGERHEART.Condition.Vulnerable.Description'
},
hidden: {
id: 'hidden',
name: "DAGGERHEART.Condition.Hidden.Name",
icon: "icons/magic/perception/silhouette-stealth-shadow.webp",
description: "DAGGERHEART.Condition.Hidden.Description"
name: 'DAGGERHEART.Condition.Hidden.Name',
icon: 'icons/magic/perception/silhouette-stealth-shadow.webp',
description: 'DAGGERHEART.Condition.Hidden.Description'
},
restrained: {
id: 'restrained',
name: "DAGGERHEART.Condition.Restrained.Name",
icon: "icons/magic/control/debuff-chains-shackle-movement-red.webp",
description: "DAGGERHEART.Condition.Restrained.Description"
},
name: 'DAGGERHEART.Condition.Restrained.Name',
icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp',
description: 'DAGGERHEART.Condition.Restrained.Description'
}
};
export const downtime = {
shortRest: {
tendToWounds: {
id: "tendToWounds",
name: "DAGGERHEART.Downtime.TendToWounds.Name",
img: "icons/magic/life/cross-worn-green.webp",
description: "DAGGERHEART.Downtime.TendToWounds.Description",
id: 'tendToWounds',
name: 'DAGGERHEART.Downtime.TendToWounds.Name',
img: 'icons/magic/life/cross-worn-green.webp',
description: 'DAGGERHEART.Downtime.TendToWounds.Description'
},
clearStress: {
id: "clearStress",
name: "DAGGERHEART.Downtime.ClearStress.Name",
img: "icons/magic/perception/eye-ringed-green.webp",
description: "DAGGERHEART.Downtime.ClearStress.Description",
id: 'clearStress',
name: 'DAGGERHEART.Downtime.ClearStress.Name',
img: 'icons/magic/perception/eye-ringed-green.webp',
description: 'DAGGERHEART.Downtime.ClearStress.Description'
},
repairArmor: {
id: "repairArmor",
name: "DAGGERHEART.Downtime.RepairArmor.Name",
img: "icons/skills/trades/smithing-anvil-silver-red.webp",
description: "DAGGERHEART.Downtime.RepairArmor.Description",
id: 'repairArmor',
name: 'DAGGERHEART.Downtime.RepairArmor.Name',
img: 'icons/skills/trades/smithing-anvil-silver-red.webp',
description: 'DAGGERHEART.Downtime.RepairArmor.Description'
},
prepare: {
id: "prepare",
name: "DAGGERHEART.Downtime.Prepare.Name",
img: "icons/skills/trades/academics-merchant-scribe.webp",
description: "DAGGERHEART.Downtime.Prepare.Description",
},
id: 'prepare',
name: 'DAGGERHEART.Downtime.Prepare.Name',
img: 'icons/skills/trades/academics-merchant-scribe.webp',
description: 'DAGGERHEART.Downtime.Prepare.Description'
}
},
longRest: {
tendToWounds: {
id: "tendToWounds",
name: "DAGGERHEART.Downtime.TendToWounds.Name",
img: "icons/magic/life/cross-worn-green.webp",
description: "DAGGERHEART.Downtime.TendToWounds.Description",
id: 'tendToWounds',
name: 'DAGGERHEART.Downtime.TendToWounds.Name',
img: 'icons/magic/life/cross-worn-green.webp',
description: 'DAGGERHEART.Downtime.TendToWounds.Description'
},
clearStress: {
id: "clearStress",
name: "DAGGERHEART.Downtime.ClearStress.Name",
img: "icons/magic/perception/eye-ringed-green.webp",
description: "DAGGERHEART.Downtime.ClearStress.Description",
id: 'clearStress',
name: 'DAGGERHEART.Downtime.ClearStress.Name',
img: 'icons/magic/perception/eye-ringed-green.webp',
description: 'DAGGERHEART.Downtime.ClearStress.Description'
},
repairArmor: {
id: "repairArmor",
name: "DAGGERHEART.Downtime.RepairArmor.Name",
img: "icons/skills/trades/smithing-anvil-silver-red.webp",
description: "DAGGERHEART.Downtime.RepairArmor.Description",
id: 'repairArmor',
name: 'DAGGERHEART.Downtime.RepairArmor.Name',
img: 'icons/skills/trades/smithing-anvil-silver-red.webp',
description: 'DAGGERHEART.Downtime.RepairArmor.Description'
},
prepare: {
id: "prepare",
name: "DAGGERHEART.Downtime.Prepare.Name",
img: "icons/skills/trades/academics-merchant-scribe.webp",
description: "DAGGERHEART.Downtime.Prepare.Description",
id: 'prepare',
name: 'DAGGERHEART.Downtime.Prepare.Name',
img: 'icons/skills/trades/academics-merchant-scribe.webp',
description: 'DAGGERHEART.Downtime.Prepare.Description'
},
workOnAProject: {
id: "workOnAProject",
name: "DAGGERHEART.Downtime.WorkOnAProject.Name",
img: "icons/skills/social/thumbsup-approval-like.webp",
description: "DAGGERHEART.Downtime.WorkOnAProject.Description",
id: 'workOnAProject',
name: 'DAGGERHEART.Downtime.WorkOnAProject.Name',
img: 'icons/skills/social/thumbsup-approval-like.webp',
description: 'DAGGERHEART.Downtime.WorkOnAProject.Description'
}
},
custom: {
id: 'customActivity',
name: "",
img: "icons/skills/trades/academics-investigation-puzzles.webp",
description: "",
namePlaceholder: "DAGGERHEART.Downtime.Custom.NamePlaceholder",
placeholder: "DAGGERHEART.Downtime.Custom.Placeholder",
}
name: '',
img: 'icons/skills/trades/academics-investigation-puzzles.webp',
description: '',
namePlaceholder: 'DAGGERHEART.Downtime.Custom.NamePlaceholder',
placeholder: 'DAGGERHEART.Downtime.Custom.Placeholder'
}
};
export const deathMoves = {
avoidDeath: {
id: "avoidDeath",
name: "DAGGERHEART.DeathMoves.AvoidDeath.Name",
img: "icons/magic/time/hourglass-yellow-green.webp",
description: "DAGGERHEART.DeathMoves.AvoidDeath.Description",
id: 'avoidDeath',
name: 'DAGGERHEART.DeathMoves.AvoidDeath.Name',
img: 'icons/magic/time/hourglass-yellow-green.webp',
description: 'DAGGERHEART.DeathMoves.AvoidDeath.Description'
},
riskItAll: {
id: 'riskItAll',
name: "DAGGERHEART.DeathMoves.RiskItAll.Name",
img: "icons/sundries/gaming/dice-pair-white-green.webp",
description: "DAGGERHEART.DeathMoves.RiskItAll.Description",
name: 'DAGGERHEART.DeathMoves.RiskItAll.Name',
img: 'icons/sundries/gaming/dice-pair-white-green.webp',
description: 'DAGGERHEART.DeathMoves.RiskItAll.Description'
},
blazeOfGlory: {
id: "blazeOfGlory",
name: "DAGGERHEART.DeathMoves.BlazeOfGlory.Name",
img: "icons/magic/life/heart-cross-strong-flame-purple-orange.webp",
description: "DAGGERHEART.DeathMoves.BlazeOfGlory.Description",
id: 'blazeOfGlory',
name: 'DAGGERHEART.DeathMoves.BlazeOfGlory.Name',
img: 'icons/magic/life/heart-cross-strong-flame-purple-orange.webp',
description: 'DAGGERHEART.DeathMoves.BlazeOfGlory.Description'
}
};
@ -172,97 +172,97 @@ export const tiers = {
0: {
key: 0,
id: 'tier0',
name: 'DAGGERHEART.General.Tier.0',
name: 'DAGGERHEART.General.Tier.0'
},
1: {
key: 1,
id: 'tier1',
name: 'DAGGERHEART.General.Tier.1',
name: 'DAGGERHEART.General.Tier.1'
},
2: {
key: 2,
id: 'tier2',
name: 'DAGGERHEART.General.Tier.2',
name: 'DAGGERHEART.General.Tier.2'
},
3: {
key: 3,
id: 'tier3',
name: 'DAGGERHEART.General.Tier.3',
name: 'DAGGERHEART.General.Tier.3'
}
};
export const objectTypes = {
pc: {
name: "TYPES.Actor.pc",
name: 'TYPES.Actor.pc'
},
npc: {
name: "TYPES.Actor.npc",
name: 'TYPES.Actor.npc'
},
adversary: {
name: "TYPES.Actor.adversary",
name: 'TYPES.Actor.adversary'
},
ancestry: {
name: "TYPES.Item.ancestry",
name: 'TYPES.Item.ancestry'
},
community: {
name: "TYPES.Item.community",
name: 'TYPES.Item.community'
},
class: {
name: "TYPES.Item.class",
name: 'TYPES.Item.class'
},
subclass: {
name: "TYPES.Item.subclass",
name: 'TYPES.Item.subclass'
},
feature: {
name: "TYPES.Item.feature",
name: 'TYPES.Item.feature'
},
domainCard: {
name: "TYPES.Item.domainCard",
name: 'TYPES.Item.domainCard'
},
consumable: {
name: "TYPES.Item.consumable",
name: 'TYPES.Item.consumable'
},
miscellaneous: {
name: "TYPES.Item.miscellaneous",
name: 'TYPES.Item.miscellaneous'
},
weapon: {
name: "TYPES.Item.weapon",
name: 'TYPES.Item.weapon'
},
armor: {
name: "TYPES.Item.armor",
name: 'TYPES.Item.armor'
}
};
export const diceTypes = {
d4: "d4",
d6: "d6",
d8: "d8",
d12: "d12",
d20: "d20"
d4: 'd4',
d6: 'd6',
d8: 'd8',
d12: 'd12',
d20: 'd20'
};
export const refreshTypes = {
session: {
id: 'session',
label: "DAGGERHEART.General.RefreshType.Session"
label: 'DAGGERHEART.General.RefreshType.Session'
},
shortRest: {
id: 'shortRest',
label: "DAGGERHEART.General.RefreshType.Shortrest",
label: 'DAGGERHEART.General.RefreshType.Shortrest'
},
longRest: {
id: 'longRest',
label: "DAGGERHEART.General.RefreshType.Longrest"
}
label: 'DAGGERHEART.General.RefreshType.Longrest'
}
};
export const abilityCosts = {
hope: {
id: 'hope',
label: 'Hope',
label: 'Hope'
},
stress: {
id: 'stress',
label: 'Stress',
}
label: 'Stress'
}
};

View file

@ -1,351 +1,351 @@
export const armorFeatures = {
light: {
label: "DAGGERHEART.ArmorFeature.Light.Name",
description: "DAGGERHEART.ArmorFeature.Light.Description",
label: 'DAGGERHEART.ArmorFeature.Light.Name',
description: 'DAGGERHEART.ArmorFeature.Light.Description'
},
heavy: {
label: "DAGGERHEART.ArmorFeature.Heavy.Name",
description: "DAGGERHEART.ArmorFeature.Heavy.Description",
label: 'DAGGERHEART.ArmorFeature.Heavy.Name',
description: 'DAGGERHEART.ArmorFeature.Heavy.Description'
},
veryHeavy: {
label: "DAGGERHEART.ArmorFeature.VeryHeavy.Name",
description: "DAGGERHEART.ArmorFeature.VeryHeavy.Description",
label: 'DAGGERHEART.ArmorFeature.VeryHeavy.Name',
description: 'DAGGERHEART.ArmorFeature.VeryHeavy.Description'
},
reinforced: {
label: "DAGGERHEART.ArmorFeature.Reinforced.Name",
description: "DAGGERHEART.ArmorFeature.Reinforced.Description",
label: 'DAGGERHEART.ArmorFeature.Reinforced.Name',
description: 'DAGGERHEART.ArmorFeature.Reinforced.Description'
},
sturdy: {
label: "DAGGERHEART.ArmorFeature.Sturdy.Name",
description: "DAGGERHEART.ArmorFeature.Sturdy.Description",
label: 'DAGGERHEART.ArmorFeature.Sturdy.Name',
description: 'DAGGERHEART.ArmorFeature.Sturdy.Description'
},
warded: {
label: "DAGGERHEART.ArmorFeature.Warded.Name",
description: "DAGGERHEART.ArmorFeature.Warded.Description",
label: 'DAGGERHEART.ArmorFeature.Warded.Name',
description: 'DAGGERHEART.ArmorFeature.Warded.Description'
},
resistant: {
label: "DAGGERHEART.ArmorFeature.Resistant.Name",
description: "DAGGERHEART.ArmorFeature.Resistant.Description",
label: 'DAGGERHEART.ArmorFeature.Resistant.Name',
description: 'DAGGERHEART.ArmorFeature.Resistant.Description'
},
quiet: {
label: "DAGGERHEART.ArmorFeature.Quiet.Name",
description: "DAGGERHEART.ArmorFeature.Quiet.Description",
label: 'DAGGERHEART.ArmorFeature.Quiet.Name',
description: 'DAGGERHEART.ArmorFeature.Quiet.Description'
},
hopeful: {
label: "DAGGERHEART.ArmorFeature.Hopeful.Name",
description: "DAGGERHEART.ArmorFeature.Hopeful.Description",
label: 'DAGGERHEART.ArmorFeature.Hopeful.Name',
description: 'DAGGERHEART.ArmorFeature.Hopeful.Description'
},
impenetrable: {
label: "DAGGERHEART.ArmorFeature.Impenetrable.Name",
description: "DAGGERHEART.ArmorFeature.Impenetrable.Description",
label: 'DAGGERHEART.ArmorFeature.Impenetrable.Name',
description: 'DAGGERHEART.ArmorFeature.Impenetrable.Description'
},
painful: {
label: "DAGGERHEART.ArmorFeature.Painful.Name",
description: "DAGGERHEART.ArmorFeature.Painful.Description",
label: 'DAGGERHEART.ArmorFeature.Painful.Name',
description: 'DAGGERHEART.ArmorFeature.Painful.Description'
},
gilded: {
label: "DAGGERHEART.ArmorFeature.Gilded.Name",
description: "DAGGERHEART.ArmorFeature.Gilded.Description",
label: 'DAGGERHEART.ArmorFeature.Gilded.Name',
description: 'DAGGERHEART.ArmorFeature.Gilded.Description'
},
physical: {
label: "DAGGERHEART.ArmorFeature.Physical.Name",
description: "DAGGERHEART.ArmorFeature.Physical.Description",
label: 'DAGGERHEART.ArmorFeature.Physical.Name',
description: 'DAGGERHEART.ArmorFeature.Physical.Description'
},
magic: {
label: "DAGGERHEART.ArmorFeature.Magic.Name",
description: "DAGGERHEART.ArmorFeature.Magic.Description",
label: 'DAGGERHEART.ArmorFeature.Magic.Name',
description: 'DAGGERHEART.ArmorFeature.Magic.Description'
},
sharp: {
label: "DAGGERHEART.ArmorFeature.Sharp.Name",
description: "DAGGERHEART.ArmorFeature.Sharp.Description",
label: 'DAGGERHEART.ArmorFeature.Sharp.Name',
description: 'DAGGERHEART.ArmorFeature.Sharp.Description'
},
burning: {
label: "DAGGERHEART.ArmorFeature.Burning.Name",
description: "DAGGERHEART.ArmorFeature.Burning.Description",
label: 'DAGGERHEART.ArmorFeature.Burning.Name',
description: 'DAGGERHEART.ArmorFeature.Burning.Description'
},
timeslowing: {
label: "DAGGERHEART.ArmorFeature.Timeslowing.Name",
description: "DAGGERHEART.ArmorFeature.Timeslowing.Description",
label: 'DAGGERHEART.ArmorFeature.Timeslowing.Name',
description: 'DAGGERHEART.ArmorFeature.Timeslowing.Description'
},
truthseeking: {
label: "DAGGERHEART.ArmorFeature.Truthseeking.Name",
description: "DAGGERHEART.ArmorFeature.Truthseeking.Description",
label: 'DAGGERHEART.ArmorFeature.Truthseeking.Name',
description: 'DAGGERHEART.ArmorFeature.Truthseeking.Description'
},
channeling: {
label: "DAGGERHEART.ArmorFeature.Channeling.Name",
description: "DAGGERHEART.ArmorFeature.Channeling.Description",
label: 'DAGGERHEART.ArmorFeature.Channeling.Name',
description: 'DAGGERHEART.ArmorFeature.Channeling.Description'
},
difficult: {
label: "DAGGERHEART.ArmorFeature.Difficult.Name",
description: "DAGGERHEART.ArmorFeature.Difficult.Description",
label: 'DAGGERHEART.ArmorFeature.Difficult.Name',
description: 'DAGGERHEART.ArmorFeature.Difficult.Description'
},
variable: {
label: "DAGGERHEART.ArmorFeature.Variable.Name",
description: "DAGGERHEART.ArmorFeature.Variable.Description",
},
label: 'DAGGERHEART.ArmorFeature.Variable.Name',
description: 'DAGGERHEART.ArmorFeature.Variable.Description'
}
};
export const weaponFeatures = {
light: {
label: "DAGGERHEART.WeaponFeature.Light.Name",
description: "DAGGERHEART.WeaponFeature.Light.Description",
label: 'DAGGERHEART.WeaponFeature.Light.Name',
description: 'DAGGERHEART.WeaponFeature.Light.Description'
},
heavy: {
label: "DAGGERHEART.WeaponFeature.Heavy.Name",
description: "DAGGERHEART.WeaponFeature.Heavy.Description",
label: 'DAGGERHEART.WeaponFeature.Heavy.Name',
description: 'DAGGERHEART.WeaponFeature.Heavy.Description'
},
massive: {
label: "DAGGERHEART.WeaponFeature.Massive.Name",
description: "DAGGERHEART.WeaponFeature.Massive.Description",
label: 'DAGGERHEART.WeaponFeature.Massive.Name',
description: 'DAGGERHEART.WeaponFeature.Massive.Description'
},
reliable: {
label: "DAGGERHEART.WeaponFeature.Reliable.Name",
description: "DAGGERHEART.WeaponFeature.Reliable.Description",
label: 'DAGGERHEART.WeaponFeature.Reliable.Name',
description: 'DAGGERHEART.WeaponFeature.Reliable.Description'
},
quick: {
label: "DAGGERHEART.WeaponFeature.Quick.Name",
description: "DAGGERHEART.WeaponFeature.Quick.Description",
label: 'DAGGERHEART.WeaponFeature.Quick.Name',
description: 'DAGGERHEART.WeaponFeature.Quick.Description'
},
cumbersome: {
label: "DAGGERHEART.WeaponFeature.Cumbersome.Name",
description: "DAGGERHEART.WeaponFeature.Cumbersome.Description",
label: 'DAGGERHEART.WeaponFeature.Cumbersome.Name',
description: 'DAGGERHEART.WeaponFeature.Cumbersome.Description'
},
versatile: {
label: "DAGGERHEART.WeaponFeature.Versatile.Name",
description: "DAGGERHEART.WeaponFeature.Versatile.Description",
label: 'DAGGERHEART.WeaponFeature.Versatile.Name',
description: 'DAGGERHEART.WeaponFeature.Versatile.Description',
override: {
damage: "",
damage: ''
}
},
powerful: {
label: "DAGGERHEART.WeaponFeature.Powerful.Name",
description: "DAGGERHEART.WeaponFeature.Powerful.Description",
label: 'DAGGERHEART.WeaponFeature.Powerful.Name',
description: 'DAGGERHEART.WeaponFeature.Powerful.Description'
},
scary: {
label: "DAGGERHEART.WeaponFeature.Scary.Name",
description: "DAGGERHEART.WeaponFeature.Scary.Description",
label: 'DAGGERHEART.WeaponFeature.Scary.Name',
description: 'DAGGERHEART.WeaponFeature.Scary.Description'
},
brutal: {
label: "DAGGERHEART.WeaponFeature.Brutal.Name",
description: "DAGGERHEART.WeaponFeature.Brutal.Description",
label: 'DAGGERHEART.WeaponFeature.Brutal.Name',
description: 'DAGGERHEART.WeaponFeature.Brutal.Description'
},
reloading: {
label: "DAGGERHEART.WeaponFeature.Reloading.Name",
description: "DAGGERHEART.WeaponFeature.Reloading.Description",
label: 'DAGGERHEART.WeaponFeature.Reloading.Name',
description: 'DAGGERHEART.WeaponFeature.Reloading.Description'
},
eruptive: {
label: "DAGGERHEART.WeaponFeature.Eruptive.Name",
description: "DAGGERHEART.WeaponFeature.Eruptive.Description",
label: 'DAGGERHEART.WeaponFeature.Eruptive.Name',
description: 'DAGGERHEART.WeaponFeature.Eruptive.Description'
},
persuasive: {
label: "DAGGERHEART.WeaponFeature.Persuasive.Name",
description: "DAGGERHEART.WeaponFeature.Persuasive.Description",
label: 'DAGGERHEART.WeaponFeature.Persuasive.Name',
description: 'DAGGERHEART.WeaponFeature.Persuasive.Description'
},
pompous: {
label: "DAGGERHEART.WeaponFeature.Pompous.Name",
description: "DAGGERHEART.WeaponFeature.Pompous.Description",
label: 'DAGGERHEART.WeaponFeature.Pompous.Name',
description: 'DAGGERHEART.WeaponFeature.Pompous.Description'
},
invigorating: {
label: "DAGGERHEART.WeaponFeature.Invigorating.Name",
description: "DAGGERHEART.WeaponFeature.Invigorating.Description",
label: 'DAGGERHEART.WeaponFeature.Invigorating.Name',
description: 'DAGGERHEART.WeaponFeature.Invigorating.Description'
},
dense: {
label: "DAGGERHEART.WeaponFeature.Dense.Name",
description: "DAGGERHEART.WeaponFeature.Dense.Description",
label: 'DAGGERHEART.WeaponFeature.Dense.Name',
description: 'DAGGERHEART.WeaponFeature.Dense.Description'
},
soulswift: {
label: "DAGGERHEART.WeaponFeature.Soulswift.Name",
description: "DAGGERHEART.WeaponFeature.Soulswift.Description",
label: 'DAGGERHEART.WeaponFeature.Soulswift.Name',
description: 'DAGGERHEART.WeaponFeature.Soulswift.Description'
},
protective: {
label: "DAGGERHEART.WeaponFeature.Protective.Name",
description: "DAGGERHEART.WeaponFeature.Protective.Description",
label: 'DAGGERHEART.WeaponFeature.Protective.Name',
description: 'DAGGERHEART.WeaponFeature.Protective.Description'
},
devastating: {
label: "DAGGERHEART.WeaponFeature.Devastating.Name",
description: "DAGGERHEART.WeaponFeature.Devastating.Description",
label: 'DAGGERHEART.WeaponFeature.Devastating.Name',
description: 'DAGGERHEART.WeaponFeature.Devastating.Description'
},
retractable: {
label: "DAGGERHEART.WeaponFeature.Retractable.Name",
description: "DAGGERHEART.WeaponFeature.Retractable.Description",
label: 'DAGGERHEART.WeaponFeature.Retractable.Name',
description: 'DAGGERHEART.WeaponFeature.Retractable.Description'
},
burn: {
label: "DAGGERHEART.WeaponFeature.Burn.Name",
description: "DAGGERHEART.WeaponFeature.Burn.Description",
label: 'DAGGERHEART.WeaponFeature.Burn.Name',
description: 'DAGGERHEART.WeaponFeature.Burn.Description'
},
painful: {
label: "DAGGERHEART.WeaponFeature.Painful.Name",
description: "DAGGERHEART.WeaponFeature.Painful.Description",
label: 'DAGGERHEART.WeaponFeature.Painful.Name',
description: 'DAGGERHEART.WeaponFeature.Painful.Description'
},
otherwordly: {
label: "DAGGERHEART.WeaponFeature.Otherwordly.Name",
description: "DAGGERHEART.WeaponFeature.Otherwordly.Description",
label: 'DAGGERHEART.WeaponFeature.Otherwordly.Name',
description: 'DAGGERHEART.WeaponFeature.Otherwordly.Description'
},
lucky: {
label: "DAGGERHEART.WeaponFeature.Lucky.Name",
description: "DAGGERHEART.WeaponFeature.Lucky.Description",
label: 'DAGGERHEART.WeaponFeature.Lucky.Name',
description: 'DAGGERHEART.WeaponFeature.Lucky.Description'
},
selfCorrecting: {
label: "DAGGERHEART.WeaponFeature.SelfCorrecting.Name",
description: "DAGGERHEART.WeaponFeature.SelfCorrecting.Description",
label: 'DAGGERHEART.WeaponFeature.SelfCorrecting.Name',
description: 'DAGGERHEART.WeaponFeature.SelfCorrecting.Description'
},
healing: {
label: "DAGGERHEART.WeaponFeature.Healing.Name",
description: "DAGGERHEART.WeaponFeature.Healing.Description",
label: 'DAGGERHEART.WeaponFeature.Healing.Name',
description: 'DAGGERHEART.WeaponFeature.Healing.Description'
},
timebender: {
label: "DAGGERHEART.WeaponFeature.Timebender.Name",
description: "DAGGERHEART.WeaponFeature.Timebender.Description",
label: 'DAGGERHEART.WeaponFeature.Timebender.Name',
description: 'DAGGERHEART.WeaponFeature.Timebender.Description'
},
enchanted: {
label: "DAGGERHEART.WeaponFeature.Enchanted.Name",
description: "DAGGERHEART.WeaponFeature.Enchanted.Description",
label: 'DAGGERHEART.WeaponFeature.Enchanted.Name',
description: 'DAGGERHEART.WeaponFeature.Enchanted.Description'
},
serrated: {
label: "DAGGERHEART.WeaponFeature.Serrated.Name",
description: "DAGGERHEART.WeaponFeature.Serrated.Description",
label: 'DAGGERHEART.WeaponFeature.Serrated.Name',
description: 'DAGGERHEART.WeaponFeature.Serrated.Description'
},
grappling: {
label: "DAGGERHEART.WeaponFeature.Grappling.Name",
description: "DAGGERHEART.WeaponFeature.Grappling.Description",
label: 'DAGGERHEART.WeaponFeature.Grappling.Name',
description: 'DAGGERHEART.WeaponFeature.Grappling.Description'
},
long: {
label: "DAGGERHEART.WeaponFeature.Long.Name",
description: "DAGGERHEART.WeaponFeature.Long.Description",
label: 'DAGGERHEART.WeaponFeature.Long.Name',
description: 'DAGGERHEART.WeaponFeature.Long.Description'
},
destructive: {
label: "DAGGERHEART.WeaponFeature.Destructive.Name",
description: "DAGGERHEART.WeaponFeature.Destructive.Description",
label: 'DAGGERHEART.WeaponFeature.Destructive.Name',
description: 'DAGGERHEART.WeaponFeature.Destructive.Description'
},
concussive: {
label: "DAGGERHEART.WeaponFeature.Concussive.Name",
description: "DAGGERHEART.WeaponFeature.Concussive.Description",
label: 'DAGGERHEART.WeaponFeature.Concussive.Name',
description: 'DAGGERHEART.WeaponFeature.Concussive.Description'
},
bouncing: {
label: "DAGGERHEART.WeaponFeature.Bouncing.Name",
description: "DAGGERHEART.WeaponFeature.Bouncing.Description",
label: 'DAGGERHEART.WeaponFeature.Bouncing.Name',
description: 'DAGGERHEART.WeaponFeature.Bouncing.Description'
},
penetrating: {
label: "DAGGERHEART.WeaponFeature.Penetrating.Name",
description: "DAGGERHEART.WeaponFeature.Penetrating.Description",
label: 'DAGGERHEART.WeaponFeature.Penetrating.Name',
description: 'DAGGERHEART.WeaponFeature.Penetrating.Description'
},
lifestealing: {
label: "DAGGERHEART.WeaponFeature.Lifestealing.Name",
description: "DAGGERHEART.WeaponFeature.Lifestealing.Description",
label: 'DAGGERHEART.WeaponFeature.Lifestealing.Name',
description: 'DAGGERHEART.WeaponFeature.Lifestealing.Description'
},
greedy: {
label: "DAGGERHEART.WeaponFeature.Greedy.Name",
description: "DAGGERHEART.WeaponFeature.Greedy.Description",
label: 'DAGGERHEART.WeaponFeature.Greedy.Name',
description: 'DAGGERHEART.WeaponFeature.Greedy.Description'
},
bonded: {
label: "DAGGERHEART.WeaponFeature.Bonded.Name",
description: "DAGGERHEART.WeaponFeature.Bonded.Description",
label: 'DAGGERHEART.WeaponFeature.Bonded.Name',
description: 'DAGGERHEART.WeaponFeature.Bonded.Description'
},
barrier: {
label: "DAGGERHEART.WeaponFeature.Barrier.Name",
description: "DAGGERHEART.WeaponFeature.Barrier.Description",
label: 'DAGGERHEART.WeaponFeature.Barrier.Name',
description: 'DAGGERHEART.WeaponFeature.Barrier.Description'
},
paired: {
label: "DAGGERHEART.WeaponFeature.Paired.Name",
description: "DAGGERHEART.WeaponFeature.Paired.Description",
label: 'DAGGERHEART.WeaponFeature.Paired.Name',
description: 'DAGGERHEART.WeaponFeature.Paired.Description'
},
whipcrack: {
label: "DAGGERHEART.WeaponFeature.Whipcrack.Name",
description: "DAGGERHEART.WeaponFeature.Whipcrack.Description",
label: 'DAGGERHEART.WeaponFeature.Whipcrack.Name',
description: 'DAGGERHEART.WeaponFeature.Whipcrack.Description'
},
hook: {
label: "DAGGERHEART.WeaponFeature.Hook.Name",
description: "DAGGERHEART.WeaponFeature.Hook.Description",
label: 'DAGGERHEART.WeaponFeature.Hook.Name',
description: 'DAGGERHEART.WeaponFeature.Hook.Description'
},
doubleDuty: {
label: "DAGGERHEART.WeaponFeature.DoubleDuty.Name",
description: "DAGGERHEART.WeaponFeature.DoubleDuty.Description",
label: 'DAGGERHEART.WeaponFeature.DoubleDuty.Name',
description: 'DAGGERHEART.WeaponFeature.DoubleDuty.Description'
},
parry: {
label: "DAGGERHEART.WeaponFeature.Parry.Name",
description: "DAGGERHEART.WeaponFeature.Parry.Description",
label: 'DAGGERHEART.WeaponFeature.Parry.Name',
description: 'DAGGERHEART.WeaponFeature.Parry.Description'
},
retrieve: {
label: "DAGGERHEART.WeaponFeature.Retrieve.Name",
description: "DAGGERHEART.WeaponFeature.Retrieve.Description",
label: 'DAGGERHEART.WeaponFeature.Retrieve.Name',
description: 'DAGGERHEART.WeaponFeature.Retrieve.Description'
},
deflecting: {
label: "DAGGERHEART.WeaponFeature.Deflecting.Name",
description: "DAGGERHEART.WeaponFeature.Deflecting.Description",
label: 'DAGGERHEART.WeaponFeature.Deflecting.Name',
description: 'DAGGERHEART.WeaponFeature.Deflecting.Description'
},
chargedAttack: {
label: "DAGGERHEART.WeaponFeature.ChargedAttack.Name",
description: "DAGGERHEART.WeaponFeature.ChargedAttack.Description",
label: 'DAGGERHEART.WeaponFeature.ChargedAttack.Name',
description: 'DAGGERHEART.WeaponFeature.ChargedAttack.Description'
},
sheltering: {
label: "DAGGERHEART.WeaponFeature.Sheltering.Name",
description: "DAGGERHEART.WeaponFeature.Sheltering.Description",
label: 'DAGGERHEART.WeaponFeature.Sheltering.Name',
description: 'DAGGERHEART.WeaponFeature.Sheltering.Description'
},
doubledUp: {
label: "DAGGERHEART.WeaponFeature.DoubledUp.Name",
description: "DAGGERHEART.WeaponFeature.DoubledUp.Description",
label: 'DAGGERHEART.WeaponFeature.DoubledUp.Name',
description: 'DAGGERHEART.WeaponFeature.DoubledUp.Description'
},
lockedOn: {
label: "DAGGERHEART.WeaponFeature.LockedOn.Name",
description: "DAGGERHEART.WeaponFeature.LockedOn.Description",
},
label: 'DAGGERHEART.WeaponFeature.LockedOn.Name',
description: 'DAGGERHEART.WeaponFeature.LockedOn.Description'
}
};
export const featureTypes = {
ancestry: {
id: "ancestry",
label: "DAGGERHEART.Feature.Type.Ancestry"
id: 'ancestry',
label: 'DAGGERHEART.Feature.Type.Ancestry'
},
community: {
id: "community",
label: "DAGGERHEART.Feature.Type.Community"
id: 'community',
label: 'DAGGERHEART.Feature.Type.Community'
},
class: {
id: "class",
label: "DAGGERHEART.Feature.Type.Class"
id: 'class',
label: 'DAGGERHEART.Feature.Type.Class'
},
subclass: {
id: "subclass",
label: "DAGGERHEART.Feature.Type.Subclass"
},
id: 'subclass',
label: 'DAGGERHEART.Feature.Type.Subclass'
}
};
export const valueTypes = {
normal: {
id: 'normal',
name: "DAGGERHEART.Feature.ValueType.Normal",
name: 'DAGGERHEART.Feature.ValueType.Normal',
data: {
value: 0,
max: 0,
max: 0
}
},
input: {
id: 'input',
name: "DAGGERHEART.Feature.ValueType.Input",
name: 'DAGGERHEART.Feature.ValueType.Input',
data: {
value: null,
value: null
}
},
dice: {
id: 'dice',
name: "DAGGERHEART.Feature.ValueType.Dice",
name: 'DAGGERHEART.Feature.ValueType.Dice',
data: {
value: null,
}
value: null
}
}
};
export const actionTypes = {
passive: {
id: "passive",
label: "DAGGERHEART.ActionType.Passive"
id: 'passive',
label: 'DAGGERHEART.ActionType.Passive'
},
action: {
id: "action",
label: "DAGGERHEART.ActionType.Action"
id: 'action',
label: 'DAGGERHEART.ActionType.Action'
},
reaction: {
id: "reaction",
label: "DAGGERHEART.ActionType.Reaction"
id: 'reaction',
label: 'DAGGERHEART.ActionType.Reaction'
}
};

View file

@ -1,28 +1,28 @@
export const menu = {
Automation: {
Name: "GameSettingsAutomation",
Icon: "fa-solid fa-robot",
Name: 'GameSettingsAutomation',
Icon: 'fa-solid fa-robot'
},
Homebrew: {
Name: "GameSettingsHomebrew",
Icon: "fa-solid fa-flask-vial",
Name: 'GameSettingsHomebrew',
Icon: 'fa-solid fa-flask-vial'
},
Range: {
Name: "GameSettingsRange",
Icon: "fa-solid fa-ruler",
},
Name: 'GameSettingsRange',
Icon: 'fa-solid fa-ruler'
}
};
export const gameSettings = {
Automation: {
Hope: "AutomationHope",
ActionPoints: "AutomationActionPoints",
Hope: 'AutomationHope',
ActionPoints: 'AutomationActionPoints'
},
Resources: {
Fear: "ResourcesFear"
Fear: 'ResourcesFear'
},
General: {
AbilityArray: "AbilityArray",
RangeMeasurement: "RangeMeasurement",
}
AbilityArray: 'AbilityArray',
RangeMeasurement: 'RangeMeasurement'
}
};

View file

@ -1,12 +1,12 @@
import * as GENERAL from './generalConfig.mjs';
import * as DOMAIN from "./domainConfig.mjs";
import * as DOMAIN from './domainConfig.mjs';
import * as ACTOR from './actorConfig.mjs';
import * as ITEM from './itemConfig.mjs';
import * as SETTINGS from './settingsConfig.mjs';
import * as EFFECTS from './effectConfig.mjs';
import * as ACTIONS from './actionConfig.mjs';
export const SYSTEM_ID = "daggerheart";
export const SYSTEM_ID = 'daggerheart';
export const SYSTEM = {
id: SYSTEM_ID,
@ -16,5 +16,5 @@ export const SYSTEM = {
ITEM,
SETTINGS,
EFFECTS,
ACTIONS,
ACTIONS
};

View file

@ -7,24 +7,26 @@ export default class DhpAbilityUse extends foundry.abstract.TypeDataModel {
img: new fields.StringField({}),
name: new fields.StringField({}),
description: new fields.StringField({}),
actions: new fields.ArrayField(new fields.SchemaField({
actions: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
damage: new fields.SchemaField({
type: new fields.StringField({}),
value: new fields.StringField({}),
value: new fields.StringField({})
}),
healing: new fields.SchemaField({
type: new fields.StringField({}),
value: new fields.StringField({}),
value: new fields.StringField({})
}),
cost: new fields.SchemaField({
type: new fields.StringField({ nullable: true }),
value: new fields.NumberField({ nullable: true }),
value: new fields.NumberField({ nullable: true })
}),
target: new fields.SchemaField({
type: new fields.StringField({}),
}),
})),
}
type: new fields.StringField({})
})
})
)
};
}
}

View file

@ -6,30 +6,35 @@ export default class DaggerheartAction extends foundry.abstract.DataModel {
name: new fields.StringField({ initial: 'New Action' }),
damage: new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.GENERAL.damageTypes, nullable: true, initial: null }),
value: new fields.StringField({}),
value: new fields.StringField({})
}),
healing: new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.GENERAL.healingTypes, nullable: true, initial: null }),
value: new fields.StringField(),
value: new fields.StringField()
}),
conditions: new fields.ArrayField(new fields.SchemaField({
conditions: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField(),
icon: new fields.StringField(),
description: new fields.StringField(),
})),
description: new fields.StringField()
})
),
cost: new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.GENERAL.abilityCosts, nullable: true, initial: null }),
value: new fields.NumberField({ nullable: true, initial: null }),
value: new fields.NumberField({ nullable: true, initial: null })
}),
target: new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.ACTIONS.targetTypes, initial: SYSTEM.ACTIONS.targetTypes.other.id })
}),
type: new fields.StringField({
choices: SYSTEM.ACTIONS.targetTypes,
initial: SYSTEM.ACTIONS.targetTypes.other.id
})
})
// uses: new fields.SchemaField({
// nr: new fields.StringField({}),
// refreshType: new fields.StringField({ choices: SYSTEM.GENERAL.refreshTypes, initial: SYSTEM.GENERAL.refreshTypes.session.id }),
// refreshed: new fields.BooleanField({ initial: true }),
// }),
}
};
}
use = async () => {

View file

@ -1,4 +1,4 @@
import { MappingField } from "./fields.mjs";
import { MappingField } from './fields.mjs';
export default class DhpAdversary extends foundry.abstract.TypeDataModel {
static defineSchema() {
@ -8,16 +8,20 @@ export default class DhpAdversary extends foundry.abstract.TypeDataModel {
health: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
min: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 0, integer: true })
}),
stress: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
min: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 0, integer: true }),
}),
max: new fields.NumberField({ initial: 0, integer: true })
})
}),
tier: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.tiers), integer: false }),
type: new fields.StringField({ choices: Object.keys(SYSTEM.ACTOR.adversaryTypes), integer: false, initial: Object.keys(SYSTEM.ACTOR.adversaryTypes).find(x => x === 'standard') }),
type: new fields.StringField({
choices: Object.keys(SYSTEM.ACTOR.adversaryTypes),
integer: false,
initial: Object.keys(SYSTEM.ACTOR.adversaryTypes).find(x => x === 'standard')
}),
description: new fields.StringField({}),
motivesAndTactics: new fields.ArrayField(new fields.StringField({})),
attackModifier: new fields.NumberField({ integer: true, nullabe: true, initial: null }),
@ -26,20 +30,22 @@ export default class DhpAdversary extends foundry.abstract.TypeDataModel {
range: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.range), integer: false }),
damage: new fields.SchemaField({
value: new fields.StringField({}),
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false }),
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false })
})
}),
difficulty: new fields.NumberField({ initial: 1, integer: true }),
damageThresholds: new fields.SchemaField({
minor: new fields.NumberField({ initial: 0, integer: true }),
major: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true })
}),
experiences: new fields.ArrayField(new fields.SchemaField({
experiences: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
value: new fields.NumberField({ integer: true, nullable: true, initial: null }),
})),
}
value: new fields.NumberField({ integer: true, nullable: true, initial: null })
})
)
};
}
get moves() {

View file

@ -5,28 +5,37 @@ export default class DhpAdversaryRoll extends foundry.abstract.TypeDataModel {
return {
roll: new fields.StringField({}),
total: new fields.NumberField({ integer: true }),
modifiers: new fields.ArrayField(new fields.SchemaField({
modifiers: new fields.ArrayField(
new fields.SchemaField({
value: new fields.NumberField({ integer: true }),
label: new fields.StringField({}),
title: new fields.StringField({}),
})),
diceResults: new fields.ArrayField(new fields.SchemaField({
title: new fields.StringField({})
})
),
diceResults: new fields.ArrayField(
new fields.SchemaField({
value: new fields.NumberField({ integer: true }),
discarded: new fields.BooleanField({ initial: false }),
})),
targets: new fields.ArrayField(new fields.SchemaField({
discarded: new fields.BooleanField({ initial: false })
})
),
targets: new fields.ArrayField(
new fields.SchemaField({
id: new fields.StringField({}),
name: new fields.StringField({}),
img: new fields.StringField({}),
difficulty: new fields.NumberField({ integer: true, nullable: true }),
evasion: new fields.NumberField({ integer: true }),
hit: new fields.BooleanField({ initial: false }),
})),
damage: new fields.SchemaField({
hit: new fields.BooleanField({ initial: false })
})
),
damage: new fields.SchemaField(
{
value: new fields.StringField({}),
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false }),
}, { nullable: true, initial: null })
}
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false })
},
{ nullable: true, initial: null }
)
};
}
prepareDerivedData() {

View file

@ -1,11 +1,11 @@
import featuresSchema from "./interface/featuresSchema.mjs";
import featuresSchema from './interface/featuresSchema.mjs';
export default class DhpAncestry extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
description: new fields.HTMLField({}),
abilities: featuresSchema(),
}
abilities: featuresSchema()
};
}
}

View file

@ -6,24 +6,22 @@ export default class DhpArmor extends foundry.abstract.TypeDataModel {
feature: new fields.StringField({
choices: SYSTEM.ITEM.armorFeatures,
integer: false,
blank: true,
blank: true
}),
marks: new fields.SchemaField({
max: new fields.NumberField({ initial: 6, integer: true }),
value: new fields.NumberField({ initial: 0, integer: true }),
value: new fields.NumberField({ initial: 0, integer: true })
}),
baseThresholds: new fields.SchemaField({
major: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true })
}),
description: new fields.HTMLField({}),
description: new fields.HTMLField({})
};
}
get featureInfo() {
return this.feature
? CONFIG.daggerheart.ITEM.armorFeatures[this.feature]
: null;
return this.feature ? CONFIG.daggerheart.ITEM.armorFeatures[this.feature] : null;
}
prepareDerivedData() {

View file

@ -1,52 +1,67 @@
import { getTier } from "../helpers/utils.mjs";
import DhpFeature from "./feature.mjs";
import { getTier } from '../helpers/utils.mjs';
import DhpFeature from './feature.mjs';
export default class DhpClass extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
domains: new fields.ArrayField(new fields.StringField({})),
classItems: new fields.ArrayField(new fields.SchemaField({
classItems: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
})),
uuid: new fields.StringField({})
})
),
damageThresholds: new fields.SchemaField({
minor: new fields.NumberField({ initial: 0, integer: true }),
major: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true })
}),
evasion: new fields.NumberField({ initial: 0, integer: true }),
features: new fields.ArrayField(new fields.SchemaField({
features: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
})),
subclasses: new fields.ArrayField(new fields.SchemaField({
uuid: new fields.StringField({})
})
),
subclasses: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
})),
uuid: new fields.StringField({})
})
),
inventory: new fields.SchemaField({
take: new fields.ArrayField(new fields.SchemaField({
take: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
})),
choiceA: new fields.ArrayField(new fields.SchemaField({
uuid: new fields.StringField({})
})
),
choiceA: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
})),
choiceB: new fields.ArrayField(new fields.SchemaField({
uuid: new fields.StringField({})
})
),
choiceB: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
})),
extra: new fields.SchemaField({
uuid: new fields.StringField({})
})
),
extra: new fields.SchemaField(
{
title: new fields.StringField({}),
description: new fields.StringField({})
}, { initial: null, nullable: true }),
},
{ initial: null, nullable: true }
)
}),
characterGuide: new fields.SchemaField({
suggestedTraits: new fields.SchemaField({
@ -55,36 +70,45 @@ export default class DhpClass extends foundry.abstract.TypeDataModel {
finesse: new fields.NumberField({ initial: 0, integer: true }),
instinct: new fields.NumberField({ initial: 0, integer: true }),
presence: new fields.NumberField({ initial: 0, integer: true }),
knowledge: new fields.NumberField({ initial: 0, integer: true }),
knowledge: new fields.NumberField({ initial: 0, integer: true })
}),
suggestedPrimaryWeapon: new fields.SchemaField({
suggestedPrimaryWeapon: new fields.SchemaField(
{
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
}, { initial: null, nullable: true }),
suggestedSecondaryWeapon: new fields.SchemaField({
uuid: new fields.StringField({})
},
{ initial: null, nullable: true }
),
suggestedSecondaryWeapon: new fields.SchemaField(
{
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
}, { initial: null, nullable: true }),
suggestedArmor: new fields.SchemaField({
uuid: new fields.StringField({})
},
{ initial: null, nullable: true }
),
suggestedArmor: new fields.SchemaField(
{
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
}, { initial: null, nullable: true }),
uuid: new fields.StringField({})
},
{ initial: null, nullable: true }
),
characterDescription: new fields.SchemaField({
clothes: new fields.StringField({}),
eyes: new fields.StringField({}),
body: new fields.StringField({}),
color: new fields.StringField({}),
attitude: new fields.StringField({}),
attitude: new fields.StringField({})
}),
backgroundQuestions: new fields.ArrayField(new fields.StringField({}), { initial: ['', '', ''] }),
connections: new fields.ArrayField(new fields.StringField({}), { initial: ['', '' ,''] }),
connections: new fields.ArrayField(new fields.StringField({}), { initial: ['', '', ''] })
}),
multiclass: new fields.NumberField({ initial: null, nullable: true, integer: true }),
description: new fields.HTMLField({}),
}
description: new fields.HTMLField({})
};
}
get multiclassTier() {

View file

@ -3,7 +3,7 @@ export default class DhpCombat extends foundry.abstract.TypeDataModel {
const fields = foundry.data.fields;
return {
actions: new fields.NumberField({ initial: 0, integer: true }),
activeCombatant: new fields.StringField({}),
}
activeCombatant: new fields.StringField({})
};
}
}

View file

@ -3,6 +3,6 @@ export default class DhpCombatant extends foundry.abstract.TypeDataModel {
const fields = foundry.data.fields;
return {
active: new fields.BooleanField({ initial: false })
}
};
}
}

View file

@ -1,11 +1,11 @@
import featuresSchema from "./interface/featuresSchema.mjs";
import featuresSchema from './interface/featuresSchema.mjs';
export default class DhpCommunity extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
description: new fields.HTMLField({}),
abilities: featuresSchema(),
}
abilities: featuresSchema()
};
}
}

View file

@ -4,7 +4,7 @@ export default class DhpConsumable extends foundry.abstract.TypeDataModel {
return {
description: new fields.HTMLField({}),
quantity: new fields.NumberField({ initial: 1, integer: true }),
consumeOnUse: new fields.BooleanField({ initial: false }),
}
consumeOnUse: new fields.BooleanField({ initial: false })
};
}
}

View file

@ -1,17 +1,23 @@
import DaggerheartAction from "./action.mjs";
import DaggerheartAction from './action.mjs';
export default class DhpDomainCard extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
domain: new fields.StringField({ choices: SYSTEM.DOMAIN.domains, integer: false }, { required: true, initial: [] }),
domain: new fields.StringField(
{ choices: SYSTEM.DOMAIN.domains, integer: false },
{ required: true, initial: [] }
),
level: new fields.NumberField({ initial: 1, integer: true }),
recallCost: new fields.NumberField({ initial: 0, integer: true }),
type: new fields.StringField({ choices: SYSTEM.DOMAIN.cardTypes, integer: false }, { required: true, initial: [] }),
type: new fields.StringField(
{ choices: SYSTEM.DOMAIN.cardTypes, integer: false },
{ required: true, initial: [] }
),
foundation: new fields.BooleanField({ initial: false }),
effect: new fields.HTMLField({}),
inVault: new fields.BooleanField({ initial: false }),
actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction)),
}
actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction))
};
}
}

View file

@ -1,55 +1,73 @@
const fields = foundry.data.fields;
const diceField = () => new fields.SchemaField({
const diceField = () =>
new fields.SchemaField({
dice: new fields.StringField({}),
value: new fields.NumberField({ integer: true}),
value: new fields.NumberField({ integer: true })
});
export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
static defineSchema() {
return {
roll: new fields.StringField({}),
modifiers: new fields.ArrayField(new fields.SchemaField({
modifiers: new fields.ArrayField(
new fields.SchemaField({
value: new fields.NumberField({ integer: true }),
label: new fields.StringField({}),
title: new fields.StringField({}),
})),
title: new fields.StringField({})
})
),
hope: diceField(),
fear: diceField(),
advantage: diceField(),
disadvantage: diceField(),
advantageSelected: new fields.NumberField({ initial: 0 }),
targets: new fields.ArrayField(new fields.SchemaField({
targets: new fields.ArrayField(
new fields.SchemaField({
id: new fields.StringField({}),
name: new fields.StringField({}),
img: new fields.StringField({}),
difficulty: new fields.NumberField({ integer: true, nullable: true }),
evasion: new fields.NumberField({ integer: true }),
hit: new fields.BooleanField({ initial: false }),
})),
hit: new fields.BooleanField({ initial: false })
})
),
damage: new fields.SchemaField({
value: new fields.StringField({}),
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false }),
bonusDamage: new fields.ArrayField(new fields.SchemaField({
bonusDamage: new fields.ArrayField(
new fields.SchemaField({
value: new fields.StringField({}),
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false }),
type: new fields.StringField({
choices: Object.keys(SYSTEM.GENERAL.damageTypes),
integer: false
}),
initiallySelected: new fields.BooleanField(),
appliesOn: new fields.StringField({ choices: Object.keys(SYSTEM.EFFECTS.applyLocations) }, { nullable: true, initial: null }),
appliesOn: new fields.StringField(
{ choices: Object.keys(SYSTEM.EFFECTS.applyLocations) },
{ nullable: true, initial: null }
),
description: new fields.StringField({}),
hopeIncrease: new fields.StringField({ nullable: true })
}), { nullable: true, initial: null })
}),
{ nullable: true, initial: null }
)
})
}
};
}
get total() {
const modifiers = this.modifiers.reduce((acc, x) => acc + x.value, 0);
const advantage = this.advantage.value ?? this.disadvantage.value ? -this.disadvantage.value : 0;
const advantage = (this.advantage.value ?? this.disadvantage.value) ? -this.disadvantage.value : 0;
return this.hope.value + this.fear.value + advantage + modifiers;
}
get totalLabel() {
const label = this.hope.value > this.fear.value ? "DAGGERHEART.General.Hope" : this.fear.value > this.hope.value ? "DAGGERHEART.General.Fear" : "DAGGERHEART.General.CriticalSuccess";
const label =
this.hope.value > this.fear.value
? 'DAGGERHEART.General.Hope'
: this.fear.value > this.hope.value
? 'DAGGERHEART.General.Fear'
: 'DAGGERHEART.General.CriticalSuccess';
return game.i18n.localize(label);
}

View file

@ -2,16 +2,18 @@ export default class DhpEnvironment extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
resources: new fields.SchemaField({
}),
resources: new fields.SchemaField({}),
tier: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.tiers), integer: false }),
type: new fields.StringField({ choices: Object.keys(SYSTEM.ACTOR.adversaryTypes), integer: false, initial: Object.keys(SYSTEM.ACTOR.adversaryTypes).find(x => x === 'standard') }),
type: new fields.StringField({
choices: Object.keys(SYSTEM.ACTOR.adversaryTypes),
integer: false,
initial: Object.keys(SYSTEM.ACTOR.adversaryTypes).find(x => x === 'standard')
}),
description: new fields.StringField({}),
toneAndFeel: new fields.StringField({}),
difficulty: new fields.NumberField({ initial: 1, integer: true }),
potentialAdversaries: new fields.StringField({}),
}
potentialAdversaries: new fields.StringField({})
};
}
get features() {

View file

@ -1,55 +1,83 @@
import { getTier } from "../helpers/utils.mjs";
import DaggerheartAction from "./action.mjs";
import { MappingField } from "./fields.mjs";
import DhpEffect from "./interface/effects.mjs";
import { getTier } from '../helpers/utils.mjs';
import DaggerheartAction from './action.mjs';
import { MappingField } from './fields.mjs';
import DhpEffect from './interface/effects.mjs';
export default class DhpFeature extends DhpEffect {
static defineSchema() {
const fields = foundry.data.fields;
return foundry.utils.mergeObject({}, {
return foundry.utils.mergeObject(
{},
{
type: new fields.StringField({ choices: SYSTEM.ITEM.featureTypes }),
actionType: new fields.StringField({ choices: SYSTEM.ITEM.actionTypes, initial: SYSTEM.ITEM.actionTypes.passive.id }),
actionType: new fields.StringField({
choices: SYSTEM.ITEM.actionTypes,
initial: SYSTEM.ITEM.actionTypes.passive.id
}),
featureType: new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.ITEM.valueTypes, initial: Object.keys(SYSTEM.ITEM.valueTypes).find(x => x === 'normal') }),
type: new fields.StringField({
choices: SYSTEM.ITEM.valueTypes,
initial: Object.keys(SYSTEM.ITEM.valueTypes).find(x => x === 'normal')
}),
data: new fields.SchemaField({
value: new fields.StringField({}),
property: new fields.StringField({ choices: SYSTEM.ACTOR.featureProperties, initial: Object.keys(SYSTEM.ACTOR.featureProperties).find(x => x === 'spellcastingTrait') }),
property: new fields.StringField({
choices: SYSTEM.ACTOR.featureProperties,
initial: Object.keys(SYSTEM.ACTOR.featureProperties).find(x => x === 'spellcastingTrait')
}),
max: new fields.NumberField({ initial: 1, integer: true }),
numbers: new MappingField(new fields.SchemaField({
numbers: new MappingField(
new fields.SchemaField({
value: new fields.NumberField({ integer: true }),
used: new fields.BooleanField({ initial: false }),
})),
used: new fields.BooleanField({ initial: false })
})
)
})
}),
}),
refreshData: new fields.SchemaField({
refreshData: new fields.SchemaField(
{
type: new fields.StringField({ choices: SYSTEM.GENERAL.refreshTypes }),
uses: new fields.NumberField({ initial: 1, integer: true }),
refreshed: new fields.BooleanField({ initial: true })
}, { nullable: true, initial: null }),
},
{ nullable: true, initial: null }
),
multiclass: new fields.NumberField({ initial: null, nullable: true, integer: true }),
disabled: new fields.BooleanField({ initial: false }),
description: new fields.HTMLField({}),
effects: new MappingField(new fields.SchemaField({
effects: new MappingField(
new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.EFFECTS.effectTypes }),
valueType: new fields.StringField({ choices: SYSTEM.EFFECTS.valueTypes }),
parseType: new fields.StringField({ choices: SYSTEM.EFFECTS.parseTypes }),
initiallySelected: new fields.BooleanField({ initial: true }),
options: new fields.ArrayField(new fields.SchemaField({
options: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
value: new fields.StringField({}),
}), { nullable: true, initial: null }),
value: new fields.StringField({})
}),
{ nullable: true, initial: null }
),
dataField: new fields.StringField({}),
appliesOn: new fields.StringField({ choices: SYSTEM.EFFECTS.applyLocations }, { nullable: true, initial: null }),
applyLocationChoices: new MappingField(new fields.StringField({}), { nullable: true, initial: null }),
appliesOn: new fields.StringField(
{ choices: SYSTEM.EFFECTS.applyLocations },
{ nullable: true, initial: null }
),
applyLocationChoices: new MappingField(new fields.StringField({}), {
nullable: true,
initial: null
}),
valueData: new fields.SchemaField({
value: new fields.StringField({}),
fromValue: new fields.StringField({ initial: null, nullable: true }),
type: new fields.StringField({ initial: null, nullable: true }),
hopeIncrease: new fields.StringField({ initial: null, nullable: true })
}),
})),
actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction)),
});
})
})
),
actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction))
}
);
}
get multiclassTier() {
@ -59,12 +87,13 @@ export default class DhpFeature extends DhpEffect {
async refresh() {
if (this.refreshData) {
if (this.featureType.type === SYSTEM.ITEM.valueTypes.dice.id) {
const update = { "system.refreshData.refreshed": true };
Object.keys(this.featureType.data.numbers).forEach(x => update[`system.featureType.data.numbers.-=${x}`] = null);
const update = { 'system.refreshData.refreshed': true };
Object.keys(this.featureType.data.numbers).forEach(
x => (update[`system.featureType.data.numbers.-=${x}`] = null)
);
await this.parent.update(update);
}
else {
await this.parent.update({ "system.refreshData.refreshed": true});
} else {
await this.parent.update({ 'system.refreshData.refreshed': true });
}
}
}

View file

@ -1,7 +1,7 @@
export class MappingField extends foundry.data.fields.ObjectField {
constructor(model, options) {
if (!(model instanceof foundry.data.fields.DataField)) {
throw new Error("MappingField must have a DataField as its contained element");
throw new Error('MappingField must have a DataField as its contained element');
}
super(options);
@ -27,7 +27,7 @@ export class MappingField extends foundry.data.fields.ObjectField {
/** @inheritdoc */
_cleanType(value, options) {
Object.entries(value).forEach(([k, v]) => value[k] = this.model.clean(v, options));
Object.entries(value).forEach(([k, v]) => (value[k] = this.model.clean(v, options)));
return value;
}
@ -60,7 +60,7 @@ export class MappingField extends foundry.data.fields.ObjectField {
/** @override */
_validateType(value, options = {}) {
if ( foundry.utils.getType(value) !== "Object" ) throw new Error("must be an Object");
if (foundry.utils.getType(value) !== 'Object') throw new Error('must be an Object');
const errors = this._validateValues(value, options);
if (!foundry.utils.isEmpty(errors)) throw new foundry.data.fields.ModelValidationError(errors);
}
@ -88,7 +88,7 @@ export class MappingField extends foundry.data.fields.ObjectField {
initialize(value, model, options = {}) {
if (!value) return value;
const obj = {};
const initialKeys = (this.initialKeys instanceof Array) ? this.initialKeys : Object.keys(this.initialKeys ?? {});
const initialKeys = this.initialKeys instanceof Array ? this.initialKeys : Object.keys(this.initialKeys ?? {});
const keys = this.initialKeysOnly ? initialKeys : Object.keys(value);
for (const key of keys) {
const data = value[key] ?? this._getInitialValueForKey(key, value);

View file

@ -1,30 +1,41 @@
import DaggerheartAction from "../action.mjs";
import { MappingField } from "../fields.mjs";
import DaggerheartAction from '../action.mjs';
import { MappingField } from '../fields.mjs';
export default class DhpEffects extends foundry.abstract.TypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
effects: new MappingField(new fields.SchemaField({
effects: new MappingField(
new fields.SchemaField({
type: new fields.StringField({ choices: Object.keys(SYSTEM.EFFECTS.effectTypes) }),
valueType: new fields.StringField({ choices: Object.keys(SYSTEM.EFFECTS.valueTypes) }),
parseType: new fields.StringField({ choices: Object.keys(SYSTEM.EFFECTS.parseTypes) }),
initiallySelected: new fields.BooleanField({ initial: true }),
options: new fields.ArrayField(new fields.SchemaField({
options: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
value: new fields.StringField({}),
}), { nullable: true, initial: null }),
value: new fields.StringField({})
}),
{ nullable: true, initial: null }
),
dataField: new fields.StringField({}),
appliesOn: new fields.StringField({ choices: Object.keys(SYSTEM.EFFECTS.applyLocations) }, { nullable: true, initial: null }),
applyLocationChoices: new MappingField(new fields.StringField({}), { nullable: true, initial: null }),
appliesOn: new fields.StringField(
{ choices: Object.keys(SYSTEM.EFFECTS.applyLocations) },
{ nullable: true, initial: null }
),
applyLocationChoices: new MappingField(new fields.StringField({}), {
nullable: true,
initial: null
}),
valueData: new fields.SchemaField({
value: new fields.StringField({}),
fromValue: new fields.StringField({ initial: null, nullable: true }),
type: new fields.StringField({ initial: null, nullable: true }),
hopeIncrease: new fields.StringField({ initial: null, nullable: true })
}),
})),
actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction)),
})
})
),
actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction))
// actions: new fields.SchemaField({
// damage: new fields.ArrayField(new fields.SchemaField({
// type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.extendedDamageTypes), initial: SYSTEM.GENERAL.extendedDamageTypes.physical.id }),
@ -36,7 +47,7 @@ export default class DhpEffects extends foundry.abstract.TypeDataModel {
// refreshed: new fields.BooleanField({ initial: true }),
// }),
// }),
}
};
}
get effectData() {

View file

@ -1,10 +1,13 @@
const fields = foundry.data.fields;
const featuresSchema = () => new fields.ArrayField(new fields.SchemaField({
const featuresSchema = () =>
new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
img: new fields.StringField({}),
uuid: new fields.StringField({}),
subclassLevel: new fields.StringField({}),
}))
subclassLevel: new fields.StringField({})
})
);
export default featuresSchema;

View file

@ -4,6 +4,6 @@ export default class DhpMiscellaneous extends foundry.abstract.TypeDataModel {
return {
description: new fields.HTMLField({}),
quantity: new fields.NumberField({ initial: 1, integer: true })
}
};
}
}

View file

@ -1,18 +1,19 @@
import { getPathValue, getTier } from "../helpers/utils.mjs";
import { MappingField } from "./fields.mjs";
import { getPathValue, getTier } from '../helpers/utils.mjs';
import { MappingField } from './fields.mjs';
const fields = foundry.data.fields;
const attributeField = () => new fields.SchemaField({
const attributeField = () =>
new fields.SchemaField({
data: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
base: new fields.NumberField({ initial: 0, integer: true }),
bonus: new fields.NumberField({ initial: 0, integer: true }),
actualValue: new fields.NumberField({ initial: 0, integer: true }),
overrideValue: new fields.NumberField({ initial: 0, integer: true }),
overrideValue: new fields.NumberField({ initial: 0, integer: true })
}),
levelMarks: new fields.ArrayField(new fields.NumberField({ nullable: true, initial: null, integer: true })),
levelMark: new fields.NumberField({ nullable: true, initial: null, integer: true }),
levelMark: new fields.NumberField({ nullable: true, initial: null, integer: true })
});
const levelUpTier = () => ({
@ -26,11 +27,13 @@ const levelUpTier = () => ({
severeDamageThreshold2: new MappingField(new fields.BooleanField()),
severeDamageThreshold3: new MappingField(new fields.BooleanField()),
severeDamageThreshold4: new MappingField(new fields.BooleanField()),
subclass: new MappingField(new fields.SchemaField({
subclass: new MappingField(
new fields.SchemaField({
multiclass: new fields.BooleanField(),
feature: new fields.StringField({}),
})),
multiclass: new MappingField(new fields.BooleanField()),
feature: new fields.StringField({})
})
),
multiclass: new MappingField(new fields.BooleanField())
});
// const weapon = () => new fields.SchemaField({
@ -53,26 +56,28 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
health: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
min: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 6, integer: true }),
max: new fields.NumberField({ initial: 6, integer: true })
}),
stress: new fields.SchemaField({
value: new fields.NumberField({ initial: 0, integer: true }),
min: new fields.NumberField({ initial: 0, integer: true }),
max: new fields.NumberField({ initial: 6, integer: true }),
max: new fields.NumberField({ initial: 6, integer: true })
}),
hope: new fields.SchemaField({
value: new fields.NumberField({ initial: -1, integer: true }), // FIXME. Logic is gte and needs -1 in PC/Hope. Change to 0
min: new fields.NumberField({ initial: 0, integer: true }),
}),
min: new fields.NumberField({ initial: 0, integer: true })
})
}),
bonuses: new fields.SchemaField({
damage: new fields.ArrayField(new fields.SchemaField({
damage: new fields.ArrayField(
new fields.SchemaField({
value: new fields.NumberField({ integer: true, initial: 0 }),
type: new fields.StringField({ nullable: true }),
initiallySelected: new fields.BooleanField(),
hopeIncrease: new fields.StringField({ initial: null, nullable: true }),
description: new fields.StringField({}),
})),
description: new fields.StringField({})
})
)
}),
attributes: new fields.SchemaField({
agility: attributeField(),
@ -80,77 +85,90 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
finesse: attributeField(),
instinct: attributeField(),
presence: attributeField(),
knowledge: attributeField(),
knowledge: attributeField()
}),
proficiency: new fields.SchemaField({
value: new fields.NumberField({ initial: 1, integer: true }),
min: new fields.NumberField({ initial: 1, integer: true }),
max: new fields.NumberField({ initial: 6, integer: true}),
max: new fields.NumberField({ initial: 6, integer: true })
}),
damageThresholds: new fields.SchemaField({
minor: new fields.NumberField({ initial: 0, integer: true }),
major: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true }),
severe: new fields.NumberField({ initial: 0, integer: true })
}),
evasion: new fields.NumberField({ initial: 0, integer: true }),
// armor: new fields.SchemaField({
// value: new fields.NumberField({ initial: 0, integer: true }),
// customValue: new fields.NumberField({ initial: null, nullable: true }),
// }),
experiences: new fields.ArrayField(new fields.SchemaField({
experiences: new fields.ArrayField(
new fields.SchemaField({
id: new fields.StringField({ required: true }),
level: new fields.NumberField({ required: true, integer: true }),
description: new fields.StringField({}),
value: new fields.NumberField({ integer: true, nullable: true, initial: null }),
}), {
value: new fields.NumberField({ integer: true, nullable: true, initial: null })
}),
{
initial: [
{ id: foundry.utils.randomID(), level: 1, description: '', value: 2 },
{ id: foundry.utils.randomID(), level: 1, description: '', value: 2 },
{ id: foundry.utils.randomID(), level: 1, description: '', value: 2 }
]
}),
}
),
gold: new fields.SchemaField({
coins: new fields.NumberField({ initial: 0, integer: true }),
handfulls: new fields.NumberField({ initial: 0, integer: true }),
bags: new fields.NumberField({ initial: 0, integer: true }),
chests: new fields.NumberField({ initial: 0, integer: true }),
chests: new fields.NumberField({ initial: 0, integer: true })
}),
pronouns: new fields.StringField({}),
domainData: new fields.SchemaField({
maxLoadout: new fields.NumberField({ initial: 2, integer: true }),
maxCards: new fields.NumberField({ initial: 2, integer: true }),
maxCards: new fields.NumberField({ initial: 2, integer: true })
}),
levelData: new fields.SchemaField({
currentLevel: new fields.NumberField({ initial: 1, integer: true }),
changedLevel: new fields.NumberField({ initial: 1, integer: true }),
levelups: new MappingField(new fields.SchemaField({
levelups: new MappingField(
new fields.SchemaField({
level: new fields.NumberField({ required: true, integer: true }),
tier1: new fields.SchemaField({
...levelUpTier()
}),
tier2: new fields.SchemaField({
tier2: new fields.SchemaField(
{
...levelUpTier()
}, { nullable: true, initial: null }),
tier3: new fields.SchemaField({
},
{ nullable: true, initial: null }
),
tier3: new fields.SchemaField(
{
...levelUpTier()
}, { nullable: true, initial: null }),
})),
},
{ nullable: true, initial: null }
)
})
)
}),
story: new fields.SchemaField({
background: new fields.HTMLField(),
appearance: new fields.HTMLField(),
connections: new fields.HTMLField(),
scars: new fields.ArrayField(new fields.SchemaField({
scars: new fields.ArrayField(
new fields.SchemaField({
name: new fields.StringField({}),
description: new fields.HTMLField(),
})),
description: new fields.HTMLField()
})
)
}),
description: new fields.StringField({}),
//Temporary until new FoundryVersion fix --> See Armor.Mjs DataPreparation
armorMarks: new fields.SchemaField({
max: new fields.NumberField({ initial: 6, integer: true }),
value: new fields.NumberField({ initial: 0, integer: true }),
}),
}
value: new fields.NumberField({ initial: 0, integer: true })
})
};
}
get canLevelUp() {
@ -187,17 +205,33 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
const multiclass = this.multiclassSubclass;
const subclassItems = this.parent.items.filter(x => x.type === 'feature' && x.system.type === 'subclass');
return {
subclass: !subclass ? {} : {
foundation: subclassItems.filter(x => subclass.system.foundationFeature.abilities.some(ability => ability.uuid === x.uuid)),
specialization: subclassItems.filter(x => subclass.system.specializationFeature.abilities.some(ability => ability.uuid === x.uuid)),
mastery: subclassItems.filter(x => subclass.system.masteryFeature.abilities.some(ability => ability.uuid === x.uuid)),
subclass: !subclass
? {}
: {
foundation: subclassItems.filter(x =>
subclass.system.foundationFeature.abilities.some(ability => ability.uuid === x.uuid)
),
specialization: subclassItems.filter(x =>
subclass.system.specializationFeature.abilities.some(ability => ability.uuid === x.uuid)
),
mastery: subclassItems.filter(x =>
subclass.system.masteryFeature.abilities.some(ability => ability.uuid === x.uuid)
)
},
multiclassSubclass: !multiclass ? {} : {
foundation: subclassItems.filter(x => multiclass.system.foundationFeature.abilities.some(ability => ability.uuid === x.uuid)),
specialization: subclassItems.filter(x => multiclass.system.specializationFeature.abilities.some(ability => ability.uuid === x.uuid)),
mastery: subclassItems.filter(x => multiclass.system.masteryFeature.abilities.some(ability => ability.uuid === x.uuid)),
}
multiclassSubclass: !multiclass
? {}
: {
foundation: subclassItems.filter(x =>
multiclass.system.foundationFeature.abilities.some(ability => ability.uuid === x.uuid)
),
specialization: subclassItems.filter(x =>
multiclass.system.specializationFeature.abilities.some(ability => ability.uuid === x.uuid)
),
mastery: subclassItems.filter(x =>
multiclass.system.masteryFeature.abilities.some(ability => ability.uuid === x.uuid)
)
}
};
}
get community() {
@ -205,17 +239,21 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
}
get classFeatures() {
return this.parent.items.filter(x => x.type === 'feature' && x.system.type === SYSTEM.ITEM.featureTypes.class.id && !x.system.multiclass);
return this.parent.items.filter(
x => x.type === 'feature' && x.system.type === SYSTEM.ITEM.featureTypes.class.id && !x.system.multiclass
);
}
get multiclassFeatures() {
return this.parent.items.filter(x => x.type === 'feature' && x.system.type === SYSTEM.ITEM.featureTypes.class.id && x.system.multiclass);
return this.parent.items.filter(
x => x.type === 'feature' && x.system.type === SYSTEM.ITEM.featureTypes.class.id && x.system.multiclass
);
}
get domains() {
const classDomains = this.class ? this.class.system.domains : [];
const multiclassDomains = this.multiclass ? this.multiclass.system.domains : [];
return [...classDomains, ...multiclassDomains]
return [...classDomains, ...multiclassDomains];
}
get domainCards() {
@ -235,8 +273,12 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
}
get activeWeapons() {
const primaryWeapon = this.parent.items.find(x => x.type === 'weapon' && x.system.active && !x.system.secondary);
const secondaryWeapon = this.parent.items.find(x => x.type === 'weapon' && x.system.active && x.system.secondary);
const primaryWeapon = this.parent.items.find(
x => x.type === 'weapon' && x.system.active && !x.system.secondary
);
const secondaryWeapon = this.parent.items.find(
x => x.type === 'weapon' && x.system.active && x.system.secondary
);
return {
primary: this.#weaponData(primaryWeapon),
secondary: this.#weaponData(secondaryWeapon),
@ -246,10 +288,12 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
get inventoryWeapons() {
const inventoryWeaponFirst = this.parent.items.find(x => x.type === 'weapon' && x.system.inventoryWeapon === 1);
const inventoryWeaponSecond = this.parent.items.find(x => x.type === 'weapon' && x.system.inventoryWeapon === 2);
const inventoryWeaponSecond = this.parent.items.find(
x => x.type === 'weapon' && x.system.inventoryWeapon === 2
);
return {
first: this.#weaponData(inventoryWeaponFirst),
second: this.#weaponData(inventoryWeaponSecond),
second: this.#weaponData(inventoryWeaponSecond)
};
}
@ -296,28 +340,33 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
}
get refreshableFeatures() {
return this.parent.items.reduce((acc, x) => {
return this.parent.items.reduce(
(acc, x) => {
if (x.type === 'feature' && x.system.refreshData.type) {
acc[x.system.refreshData.type].push(x);
}
return acc;
}, { shortRest: [], longRest: [] });
},
{ shortRest: [], longRest: [] }
);
}
#weaponData(weapon) {
return weapon ? {
return weapon
? {
name: weapon.name,
trait: CONFIG.daggerheart.ACTOR.abilities[weapon.system.trait].name, //Should not be done in data?
range: CONFIG.daggerheart.GENERAL.range[weapon.system.range],
damage: {
value: weapon.system.damage.value,
type: CONFIG.daggerheart.GENERAL.damageTypes[weapon.system.damage.type],
type: CONFIG.daggerheart.GENERAL.damageTypes[weapon.system.damage.type]
},
feature: CONFIG.daggerheart.ITEM.weaponFeatures[weapon.system.feature],
img: weapon.img,
uuid: weapon.uuid
} : null
}
: null;
}
prepareDerivedData() {
@ -333,7 +382,9 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
const actualValue = attribute.data.base + attribute.levelMarks.length + attribute.data.bonus;
attribute.data.actualValue = actualValue;
attribute.data.value = attribute.data.overrideValue ? attribute.data.overrideValue : attribute.data.actualValue;
attribute.data.value = attribute.data.overrideValue
? attribute.data.overrideValue
: attribute.data.actualValue;
}
this.evasion = this.class?.system?.evasion ?? 0;
@ -345,9 +396,17 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
}
applyLevels() {
let healthBonus = 0, stressBonus = 0, proficiencyBonus = 0, evasionBonus = 0, armorBonus = 0, minorThresholdBonus = 0, majorThresholdBonus = 0, severeThresholdBonus = 0;
let healthBonus = 0,
stressBonus = 0,
proficiencyBonus = 0,
evasionBonus = 0,
armorBonus = 0,
minorThresholdBonus = 0,
majorThresholdBonus = 0,
severeThresholdBonus = 0;
let experienceBonuses = {};
let advancementFirst = null, advancementSecond = null;
let advancementFirst = null,
advancementSecond = null;
for (var level in this.levelData.levelups) {
var levelData = this.levelData.levelups[level];
for (var tier in levelData) {
@ -356,18 +415,30 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
healthBonus += Object.keys(tierData.hitPointSlots).length;
stressBonus += Object.keys(tierData.stressSlots).length;
proficiencyBonus += Object.keys(tierData.proficiency).length;
advancementFirst = Object.keys(tierData.subclass).length > 0 && (level >= 5 && level <= 7) ? { ...tierData.subclass[0], tier: getTier(Number.parseInt(level), true) } : advancementFirst;
advancementSecond = Object.keys(tierData.subclass).length > 0 && (level >= 8 && level <= 10) ? { ...tierData.subclass[0], tier: getTier(Number.parseInt(level), true) } : advancementSecond;
advancementFirst =
Object.keys(tierData.subclass).length > 0 && level >= 5 && level <= 7
? { ...tierData.subclass[0], tier: getTier(Number.parseInt(level), true) }
: advancementFirst;
advancementSecond =
Object.keys(tierData.subclass).length > 0 && level >= 8 && level <= 10
? { ...tierData.subclass[0], tier: getTier(Number.parseInt(level), true) }
: advancementSecond;
for (var index in Object.keys(tierData.experiences)) {
for (var experienceKey in tierData.experiences[index]) {
var experience = tierData.experiences[index][experienceKey];
experienceBonuses[experience] = experienceBonuses[experience] ? experienceBonuses[experience]+1 : 1;
experienceBonuses[experience] = experienceBonuses[experience]
? experienceBonuses[experience] + 1
: 1;
}
}
evasionBonus += Object.keys(tierData.armorOrEvasionSlot).filter(x => tierData.armorOrEvasionSlot[x] === 'evasion').length;
armorBonus += Object.keys(tierData.armorOrEvasionSlot).filter(x => tierData.armorOrEvasionSlot[x] === 'armor').length;
evasionBonus += Object.keys(tierData.armorOrEvasionSlot).filter(
x => tierData.armorOrEvasionSlot[x] === 'evasion'
).length;
armorBonus += Object.keys(tierData.armorOrEvasionSlot).filter(
x => tierData.armorOrEvasionSlot[x] === 'armor'
).length;
majorThresholdBonus += Object.keys(tierData.majorDamageThreshold2).length * 2;
severeThresholdBonus += Object.keys(tierData.severeDamageThreshold2).length * 2;
@ -383,7 +454,7 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
this.evasion += evasionBonus;
this.armorMarks = {
max: this.armor ? this.armor.system.marks.max + armorBonus : 0,
value: this.armor ? this.armor.system.marks.value : 0,
value: this.armor ? this.armor.system.marks.value : 0
};
this.damageThresholds.minor += minorThresholdBonus;
this.damageThresholds.major += majorThresholdBonus;
@ -396,26 +467,27 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
if (advancementFirst.multiclass) {
this.multiclassSubclass.system[`${advancementFirst.feature}Feature`].unlocked = true;
this.multiclassSubclass.system[`${advancementFirst.feature}Feature`].tier = advancementFirst.tier;
subclassFeatures.multiclassSubclass[advancementFirst.feature].forEach(x => x.system.disabled = false);
subclassFeatures.multiclassSubclass[advancementFirst.feature].forEach(x => (x.system.disabled = false));
} else {
this.subclass.system[`${advancementFirst.feature}Feature`].unlocked = true;
this.subclass.system[`${advancementFirst.feature}Feature`].tier = advancementFirst.tier;
subclassFeatures.subclass[advancementFirst.feature].forEach(x => x.system.disabled = false);
subclassFeatures.subclass[advancementFirst.feature].forEach(x => (x.system.disabled = false));
}
}
if (advancementSecond) {
if (advancementSecond.multiclass) {
this.multiclassSubclass.system[`${advancementSecond.feature}Feature`].unlocked = true;
this.multiclassSubclass.system[`${advancementSecond.feature}Feature`].tier = advancementSecond.tier;
subclassFeatures.multiclassSubclass[advancementSecond.feature].forEach(x => x.system.disabled = false);
subclassFeatures.multiclassSubclass[advancementSecond.feature].forEach(
x => (x.system.disabled = false)
);
} else {
this.subclass.system[`${advancementSecond.feature}Feature`].unlocked = true;
this.subclass.system[`${advancementSecond.feature}Feature`].tier = advancementSecond.tier;
subclassFeatures.subclass[advancementSecond.feature].forEach(x => x.system.disabled = false);
subclassFeatures.subclass[advancementSecond.feature].forEach(x => (x.system.disabled = false));
}
}
//General progression
for (var i = 0; i < this.levelData.currentLevel; i++) {
const tier = getTier(i + 1);
@ -459,7 +531,7 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
description: effect.name,
hopeIncrease: effect.value.valueData.hopeIncrease,
initiallySelected: effect.value.initiallySelected,
appliesOn: effect.value.appliesOn,
appliesOn: effect.value.appliesOn
});
}
}
@ -470,16 +542,9 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
const twoHanded =
primary?.system?.burden === 'twoHanded' ||
secondary?.system?.burden === 'twoHanded' ||
(
primary?.system?.burden === 'oneHanded' &&
secondary?.system?.burden === 'oneHanded'
);
(primary?.system?.burden === 'oneHanded' && secondary?.system?.burden === 'oneHanded');
const oneHanded =
!twoHanded &&
(
primary?.system?.burden === 'oneHanded' ||
secondary?.system?.burden === 'oneHanded'
);
!twoHanded && (primary?.system?.burden === 'oneHanded' || secondary?.system?.burden === 'oneHanded');
return twoHanded ? 'twoHanded' : oneHanded ? 'oneHanded' : null;
}

View file

@ -1,5 +1,5 @@
import { getTier } from "../helpers/utils.mjs";
import featuresSchema from "./interface/featuresSchema.mjs";
import { getTier } from '../helpers/utils.mjs';
import featuresSchema from './interface/featuresSchema.mjs';
import DaggerheartFeature from './feature.mjs';
export default class DhpSubclass extends foundry.abstract.TypeDataModel {
@ -7,25 +7,30 @@ export default class DhpSubclass extends foundry.abstract.TypeDataModel {
const fields = foundry.data.fields;
return {
description: new fields.HTMLField({}),
spellcastingTrait: new fields.StringField({ choices: SYSTEM.ACTOR.abilities, integer: false, nullable: true, initial: null }),
spellcastingTrait: new fields.StringField({
choices: SYSTEM.ACTOR.abilities,
integer: false,
nullable: true,
initial: null
}),
foundationFeature: new fields.SchemaField({
description: new fields.HTMLField({}),
abilities: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartFeature)),
abilities: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartFeature))
}),
specializationFeature: new fields.SchemaField({
unlocked: new fields.BooleanField({ initial: false }),
tier: new fields.NumberField({ initial: null, nullable: true, integer: true }),
description: new fields.HTMLField({}),
abilities: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartFeature)),
abilities: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartFeature))
}),
masteryFeature: new fields.SchemaField({
unlocked: new fields.BooleanField({ initial: false }),
tier: new fields.NumberField({ initial: null, nullable: true, integer: true }),
description: new fields.HTMLField({}),
abilities: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartFeature)),
abilities: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartFeature))
}),
multiclass: new fields.NumberField({ initial: null, nullable: true, integer: true }),
}
multiclass: new fields.NumberField({ initial: null, nullable: true, integer: true })
};
}
get multiclassTier() {

View file

@ -9,13 +9,13 @@ export default class DhpWeapon extends foundry.abstract.TypeDataModel {
range: new fields.StringField({ choices: SYSTEM.GENERAL.range, integer: false }),
damage: new fields.SchemaField({
value: new fields.StringField({}),
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 }),
feature: new fields.StringField({ choices: SYSTEM.ITEM.weaponFeatures, integer: false, blank: true }),
quantity: new fields.NumberField({ initial: 1, integer: true }),
description: new fields.HTMLField({}),
}
description: new fields.HTMLField({})
};
}
prepareDerivedData() {
@ -31,7 +31,10 @@ export default class DhpWeapon extends foundry.abstract.TypeDataModel {
for (var effect of effectType) {
switch (key) {
case SYSTEM.EFFECTS.effectTypes.reach.id:
if(SYSTEM.GENERAL.range[this.range].distance < SYSTEM.GENERAL.range[effect.valueData.value].distance){
if (
SYSTEM.GENERAL.range[this.range].distance <
SYSTEM.GENERAL.range[effect.valueData.value].distance
) {
this.range = effect.valueData.value;
}

View file

@ -5,9 +5,9 @@ export default class SelectDialog extends Dialog {
this.data = {
title: data.title,
buttons: data.buttons,
content: renderTemplate("systems/daggerheart/templates/dialog/item-select.hbs", {
content: renderTemplate('systems/daggerheart/templates/dialog/item-select.hbs', {
items: data.choices
}),
})
};
this.actor = data.actor;
@ -19,7 +19,7 @@ export default class SelectDialog extends Dialog {
async getData(options = {}) {
let buttons = Object.keys(this.data.buttons).reduce((obj, key) => {
let b = this.data.buttons[key];
b.cssClass = (this.data.default === key ? [key, "default", "bright"] : [key]).join(" ");
b.cssClass = (this.data.default === key ? [key, 'default', 'bright'] : [key]).join(' ');
if (b.condition !== false) obj[key] = b;
return obj;
}, {});
@ -37,7 +37,7 @@ export default class SelectDialog extends Dialog {
$(html).find('.item-button').click(this.selectChoice);
}
selectChoice = async (event) => {
selectChoice = async event => {
if (this.validate) {
if (!this.validate(event.currentTarget.dataset.validateProp)) {
return;
@ -53,7 +53,7 @@ export default class SelectDialog extends Dialog {
} else {
$(event.currentTarget).closest('.window-content').find('.confirm')[0].disabled = true;
}
}
};
/**
*
@ -63,11 +63,11 @@ export default class SelectDialog extends Dialog {
*/
static async selectItem(data) {
return this.wait({
title: data.title ?? "Selection",
title: data.title ?? 'Selection',
buttons: {
no: {
icon: '<i class="fas fa-times"></i>',
label: game.i18n.localize("DAGGERHEART.General.Cancel"),
label: game.i18n.localize('DAGGERHEART.General.Cancel'),
callback: _ => {
if (data.cancelMessage) {
ChatMessage.create({ content: data.cancelMessage });
@ -77,13 +77,13 @@ export default class SelectDialog extends Dialog {
},
confirm: {
icon: '<i class="fas fa-check"></i>',
label: game.i18n.localize("DAGGERHEART.General.OK"),
label: game.i18n.localize('DAGGERHEART.General.OK'),
callback: html => {
const buttons = $(html).find('button.checked');
return buttons.map(key => Number.parseInt(buttons[key].dataset.index)).toArray();
},
disabled: true
},
}
},
choices: data.choices,
actor: data.actor,

View file

@ -1,7 +1,7 @@
import DamageSelectionDialog from "../applications/damageSelectionDialog.mjs";
import NpcRollSelectionDialog from "../applications/npcRollSelectionDialog.mjs";
import RollSelectionDialog from "../applications/rollSelectionDialog.mjs";
import { GMUpdateEvent, socketEvent } from "../helpers/socket.mjs";
import DamageSelectionDialog from '../applications/damageSelectionDialog.mjs';
import NpcRollSelectionDialog from '../applications/npcRollSelectionDialog.mjs';
import RollSelectionDialog from '../applications/rollSelectionDialog.mjs';
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
export default class DhpActor extends Actor {
_preCreate(data, changes, user) {
@ -18,7 +18,10 @@ export default class DhpActor extends Actor {
async _preUpdate(changed, options, user) {
//Level Down
if(changed.system?.levelData?.changedLevel && this.system.levelData.currentLevel > changed.system.levelData.changedLevel){
if (
changed.system?.levelData?.changedLevel &&
this.system.levelData.currentLevel > changed.system.levelData.changedLevel
) {
changed.system.levelData.currentLevel = changed.system.levelData.changedLevel;
changed.system.levelData.levelups = Object.keys(this.system.levelData.levelups).reduce((acc, x) => {
if (x > changed.system.levelData.currentLevel) {
@ -29,14 +32,23 @@ export default class DhpActor extends Actor {
}, {});
changed.system.attributes = Object.keys(this.system.attributes).reduce((acc, key) => {
acc[key] = { levelMarks: this.system.attributes[key].levelMarks.filter(x => x <= changed.system.levelData.currentLevel) };
acc[key] = {
levelMarks: this.system.attributes[key].levelMarks.filter(
x => x <= changed.system.levelData.currentLevel
)
};
return acc;
}, {});
changed.system.experiences = this.system.experiences.filter(x => x.level <= changed.system.levelData.currentLevel);
changed.system.experiences = this.system.experiences.filter(
x => x.level <= changed.system.levelData.currentLevel
);
if(this.system.multiclass && this.system.multiclass.system.multiclass > changed.system.levelData.changedLevel){
if (
this.system.multiclass &&
this.system.multiclass.system.multiclass > changed.system.levelData.changedLevel
) {
const multiclassFeatures = this.items.filter(x => x.system.multiclass);
for (var feature of multiclassFeatures) {
await feature.delete();
@ -50,8 +62,7 @@ export default class DhpActor extends Actor {
async diceRoll(modifier, shiftKey) {
if (this.type === 'pc') {
return await this.dualityRoll(modifier, shiftKey);
}
else {
} else {
return await this.npcRoll(modifier, shiftKey);
}
}
@ -64,7 +75,7 @@ export default class DhpActor extends Actor {
{
value: Number.parseInt(modifier.value),
label: modifier.value >= 0 ? `+${modifier.value}` : `-${modifier.value}`,
title: modifier.title,
title: modifier.title
}
];
if (!shiftKey) {
@ -75,10 +86,18 @@ export default class DhpActor extends Actor {
nrDice = result.nrDice;
advantage = result.advantage;
result.experiences.forEach(x => modifiers.push({ value: x.value, label: x.value >= 0 ? `+${x.value}` : `-${x.value}`, title: x.description }))
result.experiences.forEach(x =>
modifiers.push({
value: x.value,
label: x.value >= 0 ? `+${x.value}` : `-${x.value}`,
title: x.description
})
);
}
const roll = new Roll(`${nrDice}d20${advantage === true ? 'kh' : advantage === false ? 'kl': ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`);
const roll = new Roll(
`${nrDice}d20${advantage === true ? 'kh' : advantage === false ? 'kl' : ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`
);
let rollResult = await roll.evaluate();
const diceResults = rollResult.dice.flatMap(x => x.results.flatMap(result => ({ value: result.result })));
@ -86,85 +105,107 @@ export default class DhpActor extends Actor {
}
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 = [
{
value: modifier.value ? Number.parseInt(modifier.value) : 0,
label: modifier.value >= 0 ? `+${modifier.value}` : `-${modifier.value}`,
title: modifier.title,
title: modifier.title
}
];
if (!shiftKey) {
const dialogClosed = new Promise((resolve, _) => {
new RollSelectionDialog(this.system.experiences, bonusDamage, this.system.resources.hope.value, resolve).render(true);
new RollSelectionDialog(
this.system.experiences,
bonusDamage,
this.system.resources.hope.value,
resolve
).render(true);
});
const result = await dialogClosed;
hopeDice = result.hope, fearDice = result.fear, advantageDice = result.advantage, disadvantageDice = result.disadvantage;
result.experiences.forEach(x => modifiers.push({ value: x.value, label: x.value >= 0 ? `+${x.value}` : `-${x.value}`, title: x.description }))
(hopeDice = result.hope),
(fearDice = result.fear),
(advantageDice = result.advantage),
(disadvantageDice = result.disadvantage);
result.experiences.forEach(x =>
modifiers.push({
value: x.value,
label: x.value >= 0 ? `+${x.value}` : `-${x.value}`,
title: x.description
})
);
bonusDamageString = result.bonusDamage;
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
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();
rollResult.dice[0].options.appearance = {
colorset:"inspired",
foreground: "#FFFFFF",
background: "#008080",
outline: "#000000",
edge: "#806400",
texture: "bloodmoon",
material: "metal",
font: "Arial Black",
system: "standard"
colorset: 'inspired',
foreground: '#FFFFFF',
background: '#008080',
outline: '#000000',
edge: '#806400',
texture: 'bloodmoon',
material: 'metal',
font: 'Arial Black',
system: 'standard'
};
if (advantageDice || disadvantageDice) {
rollResult.dice[1].options.appearance = {
colorset:"inspired",
foreground: disadvantageDice ? "#b30000" : "#FFFFFF",
background: "#008080",
outline: disadvantageDice ? "#000000" : "#000000",
edge: "#806400",
texture: "bloodmoon",
material: "metal",
font: "Arial Black",
system: "standard"
colorset: 'inspired',
foreground: disadvantageDice ? '#b30000' : '#FFFFFF',
background: '#008080',
outline: disadvantageDice ? '#000000' : '#000000',
edge: '#806400',
texture: 'bloodmoon',
material: 'metal',
font: 'Arial Black',
system: 'standard'
};
rollResult.dice[2].options.appearance = {
colorset:"bloodmoon",
foreground: "#000000",
background: "#430070",
outline: "#b30000",
edge: "#000000",
texture: "bloodmoon",
material: "metal",
font: "Arial Black",
system: "standard"
colorset: 'bloodmoon',
foreground: '#000000',
background: '#430070',
outline: '#b30000',
edge: '#000000',
texture: 'bloodmoon',
material: 'metal',
font: 'Arial Black',
system: 'standard'
};
}
else {
} else {
rollResult.dice[1].options.appearance = {
colorset:"bloodmoon",
foreground: "#000000",
background: "#430070",
outline: "#b30000",
edge: "#000000",
texture: "bloodmoon",
material: "metal",
font: "Arial Black",
system: "standard"
colorset: 'bloodmoon',
foreground: '#000000',
background: '#430070',
outline: '#b30000',
edge: '#000000',
texture: 'bloodmoon',
material: 'metal',
font: 'Arial Black',
system: 'standard'
};
}
const hope = rollResult.dice[0].results[0].result;
const advantage = advantageDice ? rollResult.dice[1].results[0].result : null;
const disadvantage = disadvantageDice ? rollResult.dice[1].results[0].result : null;
const fear = advantage || disadvantage ? rollResult.dice[2].results[0].result : rollResult.dice[1].results[0].result;
const fear =
advantage || disadvantage ? rollResult.dice[2].results[0].result : rollResult.dice[1].results[0].result;
if (disadvantage) {
rollResult = { ...rollResult, total: rollResult.total - Math.max(hope, disadvantage) };
@ -175,17 +216,33 @@ export default class DhpActor extends Actor {
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
if (automateHope && hope > fear) {
await this.update({ "system.resources.hope.value": Math.min(this.system.resources.hope.value+1, this.system.resources.hope.max) });
await this.update({
'system.resources.hope.value': Math.min(
this.system.resources.hope.value + 1,
this.system.resources.hope.max
)
});
}
if (automateHope && hope === fear) {
await this.update({ "system.resources": {
"hope.value": Math.min(this.system.resources.hope.value+1, this.system.resources.hope.max),
"stress.value": Math.max(this.system.resources.stress.value-1, 0),
}});
await this.update({
'system.resources': {
'hope.value': Math.min(this.system.resources.hope.value + 1, this.system.resources.hope.max),
'stress.value': Math.max(this.system.resources.stress.value - 1, 0)
}
});
}
return { roll, rollResult, hope: { dice: hopeDice, value: hope }, fear: { dice: fearDice, value: fear }, advantage: { dice: advantageDice, value: advantage }, disadvantage: { dice: disadvantageDice, value: disadvantage }, modifiers: modifiers, bonusDamageString };
return {
roll,
rollResult,
hope: { dice: hopeDice, value: hope },
fear: { dice: fearDice, value: fear },
advantage: { dice: advantageDice, value: advantage },
disadvantage: { dice: disadvantageDice, value: disadvantage },
modifiers: modifiers,
bonusDamageString
};
}
async damageRoll(damage, shiftKey) {
@ -193,7 +250,9 @@ export default class DhpActor extends Actor {
let bonusDamage = damage.bonusDamage?.filter(x => x.initiallySelected) ?? [];
if (!shiftKey) {
const dialogClosed = new Promise((resolve, _) => {
new DamageSelectionDialog(rollString, bonusDamage, this.system.resources.hope.value, resolve).render(true);
new DamageSelectionDialog(rollString, bonusDamage, this.system.resources.hope.value, resolve).render(
true
);
});
const result = await dialogClosed;
bonusDamage = result.bonusDamage;
@ -201,7 +260,9 @@ export default class DhpActor extends Actor {
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
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
});
}
}
@ -214,20 +275,17 @@ export default class DhpActor extends Actor {
const term = rollResult.terms[i];
if (term.faces) {
dice.push({ type: `d${term.faces}`, value: term.total });
}
else if (term.operator){
}
else if(term.number){
} else if (term.operator) {
} else if (term.number) {
const operator = i === 0 ? '' : rollResult.terms[i - 1].operator;
modifiers.push(`${operator}${term.number}`);
}
}
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
content: await renderTemplate("systems/daggerheart/templates/chat/damage-roll.hbs", {
content: await renderTemplate('systems/daggerheart/templates/chat/damage-roll.hbs', {
roll: rollString,
total: rollResult.total,
dice: dice,
@ -241,12 +299,20 @@ export default class DhpActor extends Actor {
async takeDamage(damage, type) {
const hpDamage =
damage >= this.system.damageThresholds.severe ? 3 :
damage >= this.system.damageThresholds.major ? 2 :
damage >= this.system.damageThresholds.minor ? 1 :
0;
damage >= this.system.damageThresholds.severe
? 3
: damage >= this.system.damageThresholds.major
? 2
: damage >= this.system.damageThresholds.minor
? 1
: 0;
const update = { "system.resources.health.value": Math.min(this.system.resources.health.value+hpDamage, this.system.resources.health.max) };
const update = {
'system.resources.health.value': Math.min(
this.system.resources.health.value + hpDamage,
this.system.resources.health.max
)
};
if (game.user.isGM) {
await this.update(update);
@ -256,7 +322,7 @@ export default class DhpActor extends Actor {
data: {
action: GMUpdateEvent.UpdateDocument,
uuid: this.uuid,
update: update,
update: update
}
});
}
@ -266,10 +332,10 @@ export default class DhpActor extends Actor {
let update = {};
switch (type) {
case SYSTEM.GENERAL.healingTypes.health.id:
update = { "system.resources.health.value": Math.max(this.system.resources.health.value - healing, 0) };
update = { 'system.resources.health.value': Math.max(this.system.resources.health.value - healing, 0) };
break;
case SYSTEM.GENERAL.healingTypes.stress.id:
update = { "system.resources.stress.value": Math.max(this.system.resources.stress.value - healing, 0) };
update = { 'system.resources.stress.value': Math.max(this.system.resources.stress.value - healing, 0) };
break;
}
@ -281,14 +347,14 @@ export default class DhpActor extends Actor {
data: {
action: GMUpdateEvent.UpdateDocument,
uuid: this.uuid,
update: update,
update: update
}
});
}
}
async emulateItemDrop(data) {
const event = new DragEvent("drop", { altKey: game.keyboard.isModifierActive("Alt") });
const event = new DragEvent('drop', { altKey: game.keyboard.isModifierActive('Alt') });
return this.sheet._onDropItem(event, { data: data });
}
@ -297,7 +363,7 @@ export default class DhpActor extends Actor {
const userTargets = Array.from(game.user.targets);
const otherTarget = action.target.type === SYSTEM.ACTIONS.targetTypes.other.id;
if (otherTarget && userTargets.length === 0) {
ui.notifications.error(game.i18n.localize("DAGGERHEART.Notification.Error.ActionRequiresTarget"));
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.ActionRequiresTarget'));
return;
}
@ -315,14 +381,14 @@ export default class DhpActor extends Actor {
roll = await new Roll(`1${action.damage.value}`).evaluate();
}
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
content: await renderTemplate("systems/daggerheart/templates/chat/damage-roll.hbs", {
content: await renderTemplate('systems/daggerheart/templates/chat/damage-roll.hbs', {
roll: roll.formula,
total: roll.result,
type: action.damage.type,
}),
type: action.damage.type
})
});
cls.create(msg.toObject());
@ -334,14 +400,14 @@ export default class DhpActor extends Actor {
roll = await new Roll(`1${action.healing.value}`).evaluate();
}
const cls = getDocumentClass("ChatMessage");
const cls = getDocumentClass('ChatMessage');
const msg = new cls({
user: game.user.id,
content: await renderTemplate("systems/daggerheart/templates/chat/healing-roll.hbs", {
content: await renderTemplate('systems/daggerheart/templates/chat/healing-roll.hbs', {
roll: roll.formula,
total: roll.result,
type: action.healing.type,
}),
type: action.healing.type
})
});
cls.create(msg.toObject());

View file

@ -1,4 +1,4 @@
import { GMUpdateEvent, socketEvent } from "../helpers/socket.mjs";
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
export default class DhpCombat extends Combat {
_sortCombatants(a, b) {
@ -13,20 +13,23 @@ export default class DhpCombat extends Combat {
}
async useActionToken(combatantId) {
const automateActionPoints = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.ActionPoints);
const automateActionPoints = await game.settings.get(
SYSTEM.id,
SYSTEM.SETTINGS.gameSettings.Automation.ActionPoints
);
if (game.user.isGM) {
if (this.system.actions < 1) return;
const update = automateActionPoints ?
{ "system.activeCombatant": combatantId, "system.actions": Math.max(this.system.actions-1, 0) } :
{ "system.activeCombatant": combatantId };
const update = automateActionPoints
? { 'system.activeCombatant': combatantId, 'system.actions': Math.max(this.system.actions - 1, 0) }
: { 'system.activeCombatant': combatantId };
await this.update(update);
} else {
const update = automateActionPoints ?
{ "system.activeCombatant": combatantId, "system.actions": this.system.actions+1} :
{ "system.activeCombatant": combatantId };
const update = automateActionPoints
? { 'system.activeCombatant': combatantId, 'system.actions': this.system.actions + 1 }
: { 'system.activeCombatant': combatantId };
await game.socket.emit(`system.${SYSTEM.id}`, {
action: socketEvent.GMUpdate,

View file

@ -30,7 +30,7 @@ export default class DhpItem extends Item {
}
const folders = collection?._formatFolderSelectOptions() ?? [];
const label = game.i18n.localize(this.metadata.label);
const title = game.i18n.format("DOCUMENT.Create", {type: label});
const title = game.i18n.format('DOCUMENT.Create', { type: label });
const typeObjects = types.reduce((obj, t) => {
const label = CONFIG[documentName]?.typeLabels?.[t] ?? t;
obj[t] = { value: t, label: game.i18n.has(label) ? game.i18n.localize(label) : t };
@ -38,15 +38,22 @@ export default class DhpItem extends Item {
}, {});
// Render the document creation form
const html = await renderTemplate("systems/daggerheart/templates/sidebar/documentCreate.hbs", {
const html = await renderTemplate('systems/daggerheart/templates/sidebar/documentCreate.hbs', {
folders,
name: data.name || game.i18n.format("DOCUMENT.New", {type: label}),
name: data.name || game.i18n.format('DOCUMENT.New', { type: label }),
folder: data.folder,
hasFolders: folders.length >= 1,
type: data.type || CONFIG[documentName]?.defaultType || typeObjects.armor,
types: {
Items: [typeObjects.armor, typeObjects.weapon, typeObjects.consumable, typeObjects.miscellaneous],
Character: [typeObjects.class, typeObjects.subclass, typeObjects.ancestry, typeObjects.community, typeObjects.feature, typeObjects.domainCard],
Character: [
typeObjects.class,
typeObjects.subclass,
typeObjects.ancestry,
typeObjects.community,
typeObjects.feature,
typeObjects.domainCard
]
},
hasTypes: types.length > 1
});
@ -57,7 +64,7 @@ export default class DhpItem extends Item {
content: html,
label: title,
callback: html => {
const form = html[0].querySelector("form");
const form = html[0].querySelector('form');
const fd = new FormDataExtended(form);
foundry.utils.mergeObject(data, fd.object, { inplace: true });
if (!data.folder) delete data.folder;

View file

@ -1,4 +1,4 @@
import { getWidthOfText } from "./utils.mjs";
import { getWidthOfText } from './utils.mjs';
export default class RegisterHandlebarsHelpers {
static registerHelpers() {
@ -11,9 +11,9 @@ export default class RegisterHandlebarsHelpers {
objectSelector: this.objectSelector,
includes: this.includes,
simpleEditor: this.simpleEditor,
debug: this.debug,
debug: this.debug
});
};
}
static looseEq(a, b) {
return a == b;
@ -21,8 +21,7 @@ export default class RegisterHandlebarsHelpers {
static times(nr, block) {
var accum = '';
for(var i = 0; i < nr; ++i)
accum += block.fn(i);
for (var i = 0; i < nr; ++i) accum += block.fn(i);
return accum;
}
@ -52,16 +51,19 @@ export default class RegisterHandlebarsHelpers {
const nrButtons = Math.max($(buttons).length - 1, 1);
const iconWidth = 26;
const texts = values.reduce((acc, x, index) => {
const texts = values
.reduce((acc, x, index) => {
if (x) {
acc.push(`<span class="object-select-item" data-action="viewObject" data-value="${ids[index]}">${x}</span>`);
acc.push(
`<span class="object-select-item" data-action="viewObject" data-value="${ids[index]}">${x}</span>`
);
}
return acc;
}, []).join(' ');
}, [])
.join(' ');
const html =
`<div ${style ? 'style="'+style+'"' : ''}">
const html = `<div ${style ? 'style="' + style + '"' : ''}">
<div class="object-select-display iconbar">
<span class="object-select-title">${title}</span>
<div class="object-select-text" style="padding-left: ${titleLength + margins}px; padding-right: ${nrButtons * iconWidth}px;">
@ -77,11 +79,10 @@ export default class RegisterHandlebarsHelpers {
static rangePicker(options) {
let { name, value, min, max, step } = options.hash;
name = name || "range";
value = value ?? "";
if ( Number.isNaN(value) ) value = "";
const html =
`<input type="range" name="${name}" value="${value}" min="${min}" max="${max}" step="${step}"/>
name = name || 'range';
value = value ?? '';
if (Number.isNaN(value)) value = '';
const html = `<input type="range" name="${name}" value="${value}" min="${min}" max="${max}" step="${step}"/>
<span class="range-value">${value}</span>`;
return new Handlebars.SafeString(html);
}
@ -91,10 +92,17 @@ export default class RegisterHandlebarsHelpers {
}
static simpleEditor(content, options) {
const { target, editable=true, button, engine="tinymce", collaborate=false, class: cssClass } = options.hash;
const {
target,
editable = true,
button,
engine = 'tinymce',
collaborate = false,
class: cssClass
} = options.hash;
const config = { name: target, value: content, button, collaborate, editable, engine };
const element = foundry.applications.fields.createEditorInput(config);
if ( cssClass ) element.querySelector(".editor-content").classList.add(cssClass);
if (cssClass) element.querySelector('.editor-content').classList.add(cssClass);
return new Handlebars.SafeString(element.outerHTML);
}

View file

@ -10,11 +10,11 @@ export function handleSocketEvent({action=null, data={}}={}) {
}
export const socketEvent = {
GMUpdate: "DhpGMUpdate",
DhpFearUpdate: "DhpFearUpdate",
GMUpdate: 'DhpGMUpdate',
DhpFearUpdate: 'DhpFearUpdate'
};
export const GMUpdateEvent = {
UpdateDocument: "DhpGMUpdateDocument",
UpdateFear: "DhpUpdateFear"
UpdateDocument: 'DhpGMUpdateDocument',
UpdateFear: 'DhpUpdateFear'
};

View file

@ -1,4 +1,4 @@
export const loadCompendiumOptions = async (compendiums) => {
export const loadCompendiumOptions = async compendiums => {
const compendiumValues = [];
for (var compendium of compendiums) {
@ -9,7 +9,7 @@ export const loadCompendiumOptions = async (compendiums) => {
return compendiumValues;
};
const getCompendiumOptions = async (compendium) => {
const getCompendiumOptions = async compendium => {
const compendiumPack = await game.packs.get(compendium);
const values = [];
@ -39,15 +39,14 @@ export const getWidthOfText = (txt, fontsize, allCaps, bold) => {
getWidthOfText.ctx = getWidthOfText.c.getContext('2d');
}
var fontspec = `${bold ? 'bold' : ''} ${fontsize}px` + ' ' + 'Signika, sans-serif';
if(getWidthOfText.ctx.font !== fontspec)
getWidthOfText.ctx.font = fontspec;
if (getWidthOfText.ctx.font !== fontspec) getWidthOfText.ctx.font = fontspec;
return getWidthOfText.ctx.measureText(text).width;
}
};
export const padArray = (arr, len, fill) => {
return arr.concat(Array(len).fill(fill)).slice(0, len);
}
};
export const getTier = (level, asNr) => {
switch (Math.floor((level + 1) / 3)) {
@ -60,11 +59,11 @@ export const getTier = (level, asNr) => {
default:
return asNr ? 0 : 'tier0';
}
}
};
export const capitalize = (string) => {
export const capitalize = string => {
return string.charAt(0).toUpperCase() + string.slice(1);
}
};
export const getPathValue = (path, entity, numeric) => {
const pathValue = foundry.utils.getProperty(entity, path);
@ -74,9 +73,12 @@ export const getPathValue = (path, entity, numeric) => {
};
export const generateId = (title, length) => {
const id = title.split(" ").map((w, i) => {
const p = w.slugify({replacement: "", strict: true});
const id = title
.split(' ')
.map((w, i) => {
const p = w.slugify({ replacement: '', strict: true });
return i ? p.titleCase() : p;
}).join("");
return Number.isNumeric(length) ? id.slice(0, length).padEnd(length, "0") : id;
}
})
.join('');
return Number.isNumeric(length) ? id.slice(0, length).padEnd(length, '0') : id;
};

View file

@ -9,21 +9,31 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
minimizedSheets: [],
config: undefined,
targets: undefined
}
};
this.setupHooks();
}
addChatListeners = async (app, html, data) => {
html.querySelectorAll('.roll-damage-button').forEach(element => element.addEventListener('click', event => this.onRollDamage(event, data.message)));
html.querySelectorAll('.target-container').forEach(element => element.addEventListener('hover', hover(this.hoverTarget, this.unhoverTarget))); // ????
html.querySelectorAll('.roll-damage-button').forEach(element =>
element.addEventListener('click', event => this.onRollDamage(event, data.message))
);
html.querySelectorAll('.target-container').forEach(element =>
element.addEventListener('hover', hover(this.hoverTarget, this.unhoverTarget))
); // ????
// html.find('.target-container').mouseout(this.unhoverTarget);
html.querySelectorAll('.damage-button').forEach(element => element.addEventListener('click', this.onDamage));
html.querySelectorAll('.healing-button').forEach(element => element.addEventListener('click', this.onHealing));
html.querySelectorAll('.target-indicator').forEach(element => element.addEventListener('click', this.onToggleTargets));
html.querySelectorAll('.target-indicator').forEach(element =>
element.addEventListener('click', this.onToggleTargets)
);
html.querySelectorAll('.advantage').forEach(element => element.hover(this.hoverAdvantage)); // ??
html.querySelectorAll('.advantage').forEach(element => element.addEventListener('click', event => this.selectAdvantage.bind(this)(event, data.message)));
html.querySelectorAll('.ability-use-button').forEach(element => element.addEventListener('click', this.abilityUseButton.bind(this)(event, data.message)));
}
html.querySelectorAll('.advantage').forEach(element =>
element.addEventListener('click', event => this.selectAdvantage.bind(this)(event, data.message))
);
html.querySelectorAll('.ability-use-button').forEach(element =>
element.addEventListener('click', this.abilityUseButton.bind(this)(event, data.message))
);
};
setupHooks() {
Hooks.on('renderChatMessageHTML', this.addChatListeners.bind());
@ -40,47 +50,49 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
await game.user.character.damageRoll(message.system.damage, event.shiftKey);
};
hoverTarget = (event) => {
hoverTarget = event => {
event.stopPropagation();
const token = canvas.tokens.get(event.currentTarget.dataset.token);
if (!token.controlled) token._onHoverIn(event, { hoverOutOthers: true });
}
};
unhoverTarget = (event) => {
unhoverTarget = event => {
const token = canvas.tokens.get(event.currentTarget.dataset.token);
if (!token.controlled) token._onHoverOut(event);
};
onDamage = async (event) => {
onDamage = async event => {
event.stopPropagation();
const damage = Number.parseInt(event.currentTarget.dataset.value);
const targets = Array.from(game.user.targets);
if(targets.length === 0) ui.notifications.info(game.i18n.localize("DAGGERHEART.Notification.Info.NoTargetsSelected"));
if (targets.length === 0)
ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.NoTargetsSelected'));
for (var target of targets) {
await target.actor.takeDamage(damage, event.currentTarget.dataset.type);
}
};
onHealing = async (event) => {
onHealing = async event => {
event.stopPropagation();
const healing = Number.parseInt(event.currentTarget.dataset.value);
const targets = Array.from(game.user.targets);
if(targets.length === 0) ui.notifications.info(game.i18n.localize("DAGGERHEART.Notification.Info.NoTargetsSelected"));
if (targets.length === 0)
ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.NoTargetsSelected'));
for (var target of targets) {
await target.actor.takeHealing(healing, event.currentTarget.dataset.type);
}
}
};
onToggleTargets = async (event) => {
onToggleTargets = async event => {
event.stopPropagation();
$($(event.currentTarget).parent()).find('.target-container').toggleClass('hidden');
};
hoverAdvantage = (event) => {
hoverAdvantage = event => {
$(event.currentTarget).siblings('.advantage').toggleClass('unused');
};
@ -92,12 +104,12 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
$(event.currentTarget).siblings('.advantage').off('click');
$(event.currentTarget).off('click');
}
};
abilityUseButton = async (event, message) => {
event.stopPropagation();
const action = message.system.actions[Number.parseInt(event.currentTarget.dataset.index)];
await game.user.character.useAction(action);
}
};
}

View file

@ -1,4 +1,4 @@
import { GMUpdateEvent, socketEvent } from "../helpers/socket.mjs";
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
constructor(data, context) {
@ -13,11 +13,11 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
activateListeners(html) {
super.activateListeners(html);
html.on("click", ".token-action-tokens .use-action-token", this.useActionToken.bind(this));
html.on("click", ".encounter-gm-resources .trade-actions", this.tradeActions.bind(this));
html.on("click", ".encounter-gm-resources .trade-fear", this.tradeFear.bind(this));
html.on("click", ".encounter-gm-resources .icon-button.up", this.increaseResource.bind(this));
html.on("click", ".encounter-gm-resources .icon-button.down", this.decreaseResource.bind(this));
html.on('click', '.token-action-tokens .use-action-token', this.useActionToken.bind(this));
html.on('click', '.encounter-gm-resources .trade-actions', this.tradeActions.bind(this));
html.on('click', '.encounter-gm-resources .trade-fear', this.tradeFear.bind(this));
html.on('click', '.encounter-gm-resources .icon-button.up', this.increaseResource.bind(this));
html.on('click', '.encounter-gm-resources .icon-button.down', this.decreaseResource.bind(this));
}
async useActionToken(event) {
@ -36,9 +36,9 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
await game.socket.emit(`system.${SYSTEM.id}`, {
action: socketEvent.GMUpdate,
data: { action: GMUpdateEvent.UpdateFear, update: value },
data: { action: GMUpdateEvent.UpdateFear, update: value }
});
await game.combat.update({ "system.actions": game.combat.system.actions-2 });
await game.combat.update({ 'system.actions': game.combat.system.actions - 2 });
}
}
@ -51,15 +51,15 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
await game.socket.emit(`system.${SYSTEM.id}`, {
action: socketEvent.GMUpdate,
data: { action: GMUpdateEvent.UpdateFear, update: value },
data: { action: GMUpdateEvent.UpdateFear, update: value }
});
await game.combat.update({ "system.actions": game.combat.system.actions+2 });
await game.combat.update({ 'system.actions': game.combat.system.actions + 2 });
}
}
async increaseResource(event) {
if (event.currentTarget.dataset.type === 'action') {
await game.combat.update({ "system.actions": game.combat.system.actions+1 });
await game.combat.update({ 'system.actions': game.combat.system.actions + 1 });
}
const currentFear = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
@ -68,7 +68,7 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
await game.socket.emit(`system.${SYSTEM.id}`, {
action: socketEvent.GMUpdate,
data: { action: GMUpdateEvent.UpdateFear, update: value },
data: { action: GMUpdateEvent.UpdateFear, update: value }
});
}
@ -77,7 +77,7 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
async decreaseResource(event) {
if (event.currentTarget.dataset.type === 'action' && game.combat.system.actions - 1 >= 0) {
await game.combat.update({ "system.actions": game.combat.system.actions-1 });
await game.combat.update({ 'system.actions': game.combat.system.actions - 1 });
}
const currentFear = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
@ -86,7 +86,7 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
await game.socket.emit(`system.${SYSTEM.id}`, {
action: socketEvent.GMUpdate,
data: { action: GMUpdateEvent.UpdateFear, update: value },
data: { action: GMUpdateEvent.UpdateFear, update: value }
});
}
@ -103,7 +103,7 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
const currentIdx = combats.findIndex(c => c === combat);
const previousId = currentIdx > 0 ? combats[currentIdx - 1].id : null;
const nextId = currentIdx < combats.length - 1 ? combats[currentIdx + 1].id : null;
const settings = game.settings.get("core", Combat.CONFIG_SETTING);
const settings = game.settings.get('core', Combat.CONFIG_SETTING);
// Prepare rendering data
context = foundry.utils.mergeObject(context, {
@ -121,7 +121,7 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
linked: combat?.scene !== null,
labels: {}
});
context.labels.scope = game.i18n.localize(`COMBAT.${context.linked ? "Linked" : "Unlinked"}`);
context.labels.scope = game.i18n.localize(`COMBAT.${context.linked ? 'Linked' : 'Unlinked'}`);
if (!hasCombat) return context;
// Format information about each combatant in the encounter
@ -131,7 +131,8 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
if (!combatant.visible) continue;
// Prepare turn data
const resource = combatant.permission >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER ? combatant.resource : null;
const resource =
combatant.permission >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER ? combatant.resource : null;
const turn = {
id: combatant.id,
name: combatant.name,
@ -144,16 +145,14 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
hasRolled: combatant.initiative !== null,
hasResource: resource !== null,
resource: resource,
canPing: (combatant.sceneId === canvas.scene?.id) && game.user.hasPermission("PING_CANVAS"),
canPing: combatant.sceneId === canvas.scene?.id && game.user.hasPermission('PING_CANVAS'),
playerCharacter: game.user?.character?.id === combatant.actor.id,
ownedByPlayer: combatant.hasPlayerOwner,
ownedByPlayer: combatant.hasPlayerOwner
};
if ( (turn.initiative !== null) && !Number.isInteger(turn.initiative) ) hasDecimals = true;
turn.css = [
turn.active ? "active" : "",
turn.hidden ? "hidden" : "",
turn.defeated ? "defeated" : ""
].join(" ").trim();
if (turn.initiative !== null && !Number.isInteger(turn.initiative)) hasDecimals = true;
turn.css = [turn.active ? 'active' : '', turn.hidden ? 'hidden' : '', turn.defeated ? 'defeated' : '']
.join(' ')
.trim();
// Actor and Token status effects
turn.effects = new Set();
@ -184,13 +183,13 @@ export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.
turn: combat.turn,
turns: turns,
control: combat.combatant?.players?.includes(game.user),
fear: fear,
fear: fear
});
}
onFearUpdate = async () => {
this.render(true);
}
};
async close(options) {
Hooks.off(socketEvent.DhpFearUpdate, this.onFearUpdate);

View file

@ -1,4 +1,4 @@
import { GMUpdateEvent, socketEvent } from "../helpers/socket.mjs";
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
export default class DhpPlayers extends foundry.applications.ui.Players {
constructor(data, context) {
@ -21,14 +21,14 @@ export default class DhpPlayers extends foundry.applications.ui.Players {
activateListeners(html) {
// Toggle online/offline
html.find(".players-mode").click(this._onToggleOfflinePlayers.bind(this));
html.find(".fear-control.up").click(async event => await this.updateFear(event, 1));
html.find(".fear-control.down").click(async event => await this.updateFear(event, -1));
html.find('.players-mode').click(this._onToggleOfflinePlayers.bind(this));
html.find('.fear-control.up').click(async event => await this.updateFear(event, 1));
html.find('.fear-control.down').click(async event => await this.updateFear(event, -1));
// Context menu
const contextOptions = this._getUserContextOptions();
Hooks.call("getUserContextOptions", html, contextOptions);
new ContextMenu(html, ".player", contextOptions);
Hooks.call('getUserContextOptions', html, contextOptions);
new ContextMenu(html, '.player', contextOptions);
}
async updateFear(_, change) {
@ -37,13 +37,13 @@ export default class DhpPlayers extends foundry.applications.ui.Players {
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
await game.socket.emit(`system.${SYSTEM.id}`, {
action: socketEvent.GMUpdate,
data: { action: GMUpdateEvent.UpdateFear, update: value },
data: { action: GMUpdateEvent.UpdateFear, update: value }
});
}
onFearUpdate = async () => {
this.render(true);
}
};
async close(options) {
Hooks.off(socketEvent.DhpFearUpdate, this.onFearUpdate);

View file

@ -11,19 +11,19 @@ export default class DhpRuler extends foundry.canvas.interaction.Ruler {
#getRangeLabel(distance, settings) {
if (distance <= settings.melee) {
return game.i18n.localize("DAGGERHEART.Range.Melee.Name");
return game.i18n.localize('DAGGERHEART.Range.Melee.Name');
}
if (distance <= settings.veryClose) {
return game.i18n.localize("DAGGERHEART.Range.VeryClose.Name");
return game.i18n.localize('DAGGERHEART.Range.VeryClose.Name');
}
if (distance <= settings.close) {
return game.i18n.localize("DAGGERHEART.Range.Close.Name");
return game.i18n.localize('DAGGERHEART.Range.Close.Name');
}
if (distance <= settings.far) {
return game.i18n.localize("DAGGERHEART.Range.Far.Name");
return game.i18n.localize('DAGGERHEART.Range.Far.Name');
}
if (distance <= settings.veryFar) {
return game.i18n.localize("DAGGERHEART.Range.VeryFar.Name");
return game.i18n.localize('DAGGERHEART.Range.VeryFar.Name');
}
}
}

1278
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -16,7 +16,13 @@
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"concurrently": "^8.2.2",
"husky": "^9.1.5",
"lint-staged": "^15.2.10",
"postcss": "^8.4.32",
"prettier": "^3.5.3",
"rollup-plugin-postcss": "^4.0.2"
},
"lint-staged": {
"**/*": "prettier --write --ignore-unknown"
}
}

View file

@ -1,6 +1,6 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: []
}
};
module.exports = config
module.exports = config;

View file

@ -7,7 +7,7 @@ export default {
output: {
file: 'build/daggerheart.js',
format: 'cjs',
sourcemap: true,
sourcemap: true
},
plugins: [
postcss({
@ -22,8 +22,8 @@ export default {
}),
commonjs({
include: /node_modules/,
requireReturnsDefault: 'auto',
requireReturnsDefault: 'auto'
}),
resolve()
],
}
]
};

View file

@ -4,10 +4,7 @@
"_id": "yKicceU4LesCgKwF",
"img": "systems/daggerheart/assets/icons/classes/bard.png",
"system": {
"domains": [
"grace",
"codex"
],
"domains": ["grace", "codex"],
"classItems": [],
"damageThresholds": {
"minor": 0,
@ -67,16 +64,8 @@
"color": "",
"attitude": ""
},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -33,16 +33,8 @@
"suggestedSecondaryWeapon": null,
"suggestedArmor": null,
"characterDescription": {},
"backgroundQuestions": [
"",
"",
""
],
"connections": [
"",
"",
""
]
"backgroundQuestions": ["", "", ""],
"connections": ["", "", ""]
},
"multiclass": null,
"description": ""

View file

@ -1,12 +1,15 @@
form.daggerheart.views.downtime { // Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto'
form.daggerheart.views.downtime {
// Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto'
height: auto !important;
}
div.daggerheart.views.death-move { // Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto'
div.daggerheart.views.death-move {
// Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto'
height: auto !important;
}
div.daggerheart.views.multiclass { // Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto'
div.daggerheart.views.multiclass {
// Shouldn't be needed, but DEFAULT_OPTIONS doesn't accept Height: 'auto'
height: auto !important;
}
@ -153,7 +156,8 @@ div.daggerheart.views.multiclass { // Shouldn't be needed, but DEFAULT_OPTIONS d
margin-right: 8px;
cursor: pointer;
&:hover, &.selected {
&:hover,
&.selected {
filter: drop-shadow(0 0 6px gold);
}
}
@ -199,7 +203,8 @@ div.daggerheart.views.multiclass { // Shouldn't be needed, but DEFAULT_OPTIONS d
}
.roll-dialog-container {
.disadvantage, .advantage {
.disadvantage,
.advantage {
border: 2px solid @secondaryAccent;
border-radius: 6px;
display: flex;
@ -391,11 +396,13 @@ div.daggerheart.views.multiclass { // Shouldn't be needed, but DEFAULT_OPTIONS d
font-size: 24px;
cursor: pointer;
&.selected:not(.disabled), &:hover:not(.disabled) {
&.selected:not(.disabled),
&:hover:not(.disabled) {
filter: drop-shadow(0 0 3px gold);
}
&.inactive, &.disabled {
&.inactive,
&.disabled {
cursor: initial;
opacity: 0.4;
}

File diff suppressed because it is too large Load diff

View file

@ -1,14 +1,14 @@
@import "./variables/variables.less";
@import "./class.less";
@import "./pc.less";
@import "./ui.less";
@import "./chat.less";
@import "./item.less";
@import "./application.less";
@import "./sheets//sheets.less";
@import "./components.less";
@import "./dialog.less";
@import "../node_modules/@yaireo/tagify/dist/tagify.css";
@import './variables/variables.less';
@import './class.less';
@import './pc.less';
@import './ui.less';
@import './chat.less';
@import './item.less';
@import './application.less';
@import './sheets//sheets.less';
@import './components.less';
@import './dialog.less';
@import '../node_modules/@yaireo/tagify/dist/tagify.css';
#logo {
content: url(../assets/DaggerheartLogo.webp);
@ -52,7 +52,7 @@
}
/****/
img[data-edit="img"] {
img[data-edit='img'] {
min-width: 64px;
min-height: 64px;
}
@ -84,7 +84,6 @@
opacity: 0.6;
}
&:hover:not(.disabled) {
cursor: pointer;
filter: drop-shadow(0 0 3px @mainShadow);

View file

@ -53,7 +53,7 @@
font-weight: bold;
}
input[type="checkbox"] {
input[type='checkbox'] {
margin: 0;
}
}

View file

@ -147,7 +147,8 @@
font-weight: bold;
font-size: 20px;
text-align: center;
&:not(:hover), &:not(:focus) {
&:not(:hover),
&:not(:focus) {
border: none;
}
}
@ -315,7 +316,8 @@
}
}
& i.selected, &:hover i.selected {
& i.selected,
&:hover i.selected {
color: green;
opacity: 1;
}
@ -411,7 +413,8 @@
font-weight: bold;
font-size: 30px;
text-align: center;
&:not(:hover), &:not(:focus) {
&:not(:hover),
&:not(:focus) {
border: none;
}
}
@ -606,7 +609,7 @@
.disabled-experience {
border: @thinBorder solid @borderTertiary;
background: rgba(0, 0, 0, 0.20);
background: rgba(0, 0, 0, 0.2);
}
}
.gold-section {
@ -644,7 +647,8 @@
gap: @tinyMargin;
}
.gold-row, .gold-column {
.gold-row,
.gold-column {
img {
min-width: 14px;
min-height: 14px;
@ -654,7 +658,8 @@
&:hover {
cursor: pointer;
filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%) contrast(103%) drop-shadow(0 0 3px @mainShadow);
filter: invert(0%) sepia(100%) saturate(0%) hue-rotate(21deg) brightness(17%)
contrast(103%) drop-shadow(0 0 3px @mainShadow);
}
}
@ -663,7 +668,8 @@
filter: drop-shadow(0 0 3px @mainShadow);
}
img:not(.owned), i:not(.owned) {
img:not(.owned),
i:not(.owned) {
opacity: 0.4;
}
}
@ -752,7 +758,7 @@
&.used::after {
position: absolute;
content: "/";
content: '/';
color: @borderTertiary;
font-weight: 700;
font-size: 1.7em;
@ -925,7 +931,8 @@
}
}
.inventory-armor-section, .inventory-weapon-section {
.inventory-armor-section,
.inventory-weapon-section {
width: 100%;
margin-bottom: @fullMargin;
text-transform: uppercase;

View file

@ -66,7 +66,7 @@
cursor: pointer;
&:hover {
filter: drop-shadow(0 0 3px red),
filter: drop-shadow(0 0 3px red);
}
}
}
@ -161,7 +161,7 @@
cursor: pointer;
&:hover {
filter: drop-shadow(0 0 3px red),
filter: drop-shadow(0 0 3px red);
}
}
}
@ -219,7 +219,7 @@
.moves-name {
font-weight: bold;
text-decoration: none;;
text-decoration: none;
}
.move-description {
@ -230,13 +230,12 @@
}
.moves-edit-container {
i {
margin-left: 4px;
cursor: pointer;
&:hover {
filter: drop-shadow(0 0 3px red),
filter: drop-shadow(0 0 3px red);
}
}
}

View file

@ -2,5 +2,4 @@
.editor {
height: 200px;
}
}

View file

@ -1,6 +1,6 @@
@import "./heritage.less";
@import "./class.less";
@import "./adversary.less";
@import './heritage.less';
@import './class.less';
@import './adversary.less';
.daggerheart.sheet {
.title-container {
@ -117,7 +117,7 @@
position: relative;
width: calc(100% - 2px);
background: rgba(0, 0, 0, 0.05);
height: var(--form-field-height);;
height: var(--form-field-height);
display: flex;
border: 1px solid rgb(122, 121, 113);
border-radius: 3px;
@ -179,7 +179,6 @@
border: 0;
i {
}
}
}

View file

@ -63,7 +63,6 @@
opacity: 0.6;
}
&:hover:not(.disabled) {
cursor: pointer;
filter: drop-shadow(0 0 3px @mainShadow);

View file

@ -1,2 +1,2 @@
@import "./colors.less";
@import "./values.less";
@import './colors.less';
@import './values.less';

View file

@ -35,9 +35,7 @@
}
],
"scripts": ["build/daggerheart.js"],
"styles": [
"styles/daggerheart.css"
],
"styles": ["styles/daggerheart.css"],
"packs": [
{
"name": "classes",
@ -348,13 +346,30 @@
"name": "Character Options",
"sorting": "m",
"color": "#000000",
"packs": ["classes", "class-features", "subclasses", "ancestries", "communities", "community-features"],
"packs": [
"classes",
"class-features",
"subclasses",
"ancestries",
"communities",
"community-features"
],
"folders": [
{
"name": "Domains",
"sorting": "m",
"color": "#000000",
"packs": ["arcana-domain", "blade-domain", "bone-domain", "codex-domain", "grace-domain", "midnight-domain", "sage-domain", "splendor-domain", "valor-domain"]
"packs": [
"arcana-domain",
"blade-domain",
"bone-domain",
"codex-domain",
"grace-domain",
"midnight-domain",
"sage-domain",
"splendor-domain",
"valor-domain"
]
}
]
},

View file

@ -7,7 +7,19 @@
"environment": {}
},
"Item": {
"types": ["ancestry", "community", "class", "subclass", "feature", "domainCard", "miscellaneous", "consumable", "weapon", "armor", "test"],
"types": [
"ancestry",
"community",
"class",
"subclass",
"feature",
"domainCard",
"miscellaneous",
"consumable",
"weapon",
"armor",
"test"
],
"ancestry": {},
"community": {},
"class": {},

View file

@ -1,16 +1,12 @@
import { compilePack } from "@foundryvtt/foundryvtt-cli";
import { promises as fs } from "fs";
import { compilePack } from '@foundryvtt/foundryvtt-cli';
import { promises as fs } from 'fs';
const MODULE_ID = process.cwd();
const yaml = false;
const packs = await fs.readdir("./src/packs");
const packs = await fs.readdir('./src/packs');
for (const pack of packs) {
if (pack === ".gitattributes") continue;
console.log("Packing " + pack);
await compilePack(
`${MODULE_ID}/src/packs/${pack}`,
`${MODULE_ID}/packs/${pack}`,
{ yaml },
);
if (pack === '.gitattributes') continue;
console.log('Packing ' + pack);
await compilePack(`${MODULE_ID}/src/packs/${pack}`, `${MODULE_ID}/packs/${pack}`, { yaml });
}

Some files were not shown because too many files have changed in this diff Show more