mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-15 21:21:08 +01:00
Improved Character datamodel
This commit is contained in:
parent
746e0f239a
commit
213a07b64c
20 changed files with 175 additions and 381 deletions
|
|
@ -54,12 +54,12 @@ Hooks.once('init', () => {
|
||||||
|
|
||||||
CONFIG.Actor.documentClass = documents.DhpActor;
|
CONFIG.Actor.documentClass = documents.DhpActor;
|
||||||
CONFIG.Actor.dataModels = {
|
CONFIG.Actor.dataModels = {
|
||||||
pc: models.DhpPC,
|
pc: models.DhCharacter,
|
||||||
adversary: models.DhpAdversary,
|
adversary: models.DhpAdversary,
|
||||||
environment: models.DhpEnvironment
|
environment: models.DhpEnvironment
|
||||||
};
|
};
|
||||||
Actors.unregisterSheet('core', foundry.appv1.sheets.ActorSheet);
|
Actors.unregisterSheet('core', foundry.appv1.sheets.ActorSheet);
|
||||||
Actors.registerSheet(SYSTEM.id, applications.DhpPCSheet, { types: ['pc'], makeDefault: true });
|
Actors.registerSheet(SYSTEM.id, applications.DhCharacterSheet, { types: ['pc'], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM.id, applications.DhpAdversarySheet, { types: ['adversary'], makeDefault: true });
|
Actors.registerSheet(SYSTEM.id, applications.DhpAdversarySheet, { types: ['adversary'], makeDefault: true });
|
||||||
Actors.registerSheet(SYSTEM.id, applications.DhpEnvironment, { types: ['environment'], makeDefault: true });
|
Actors.registerSheet(SYSTEM.id, applications.DhpEnvironment, { types: ['environment'], makeDefault: true });
|
||||||
|
|
||||||
|
|
|
||||||
10
lang/en.json
10
lang/en.json
|
|
@ -110,8 +110,14 @@
|
||||||
},
|
},
|
||||||
"VariantRules": {
|
"VariantRules": {
|
||||||
"ActionTokens": {
|
"ActionTokens": {
|
||||||
"Name": "Action Tokens",
|
"label": "Action Tokens",
|
||||||
"Hint": "Give each player action tokens to use in combat"
|
"hint": "Give each player action tokens to use in combat"
|
||||||
|
},
|
||||||
|
"FIELDS": {
|
||||||
|
"useCoins": {
|
||||||
|
"label": "Use Coins",
|
||||||
|
"hint": "test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DualityRollColor": {
|
"DualityRollColor": {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as DhpPCSheet } from './sheets/pc.mjs';
|
export { default as DhCharacterSheet } from './sheets/character.mjs';
|
||||||
export { default as DhpAdversarySheet } from './sheets/adversary.mjs';
|
export { default as DhpAdversarySheet } from './sheets/adversary.mjs';
|
||||||
export { default as DhpClassSheet } from './sheets/items/class.mjs';
|
export { default as DhpClassSheet } from './sheets/items/class.mjs';
|
||||||
export { default as DhpSubclass } from './sheets/items/subclass.mjs';
|
export { default as DhpSubclass } from './sheets/items/subclass.mjs';
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
const experienceIncreaseValues = experienceIncreases
|
const experienceIncreaseValues = experienceIncreases
|
||||||
.filter(exp => exp.data.length > 0)
|
.filter(exp => exp.data.length > 0)
|
||||||
.flatMap(exp =>
|
.flatMap(exp =>
|
||||||
exp.data.map(data => this.actor.system.experiences.find(x => x.id === data).description)
|
exp.data.map(data => {
|
||||||
|
const experience = Object.keys(this.actor.system.experiences).find(x => x === data);
|
||||||
|
return this.actor.system.experiences[experience].description;
|
||||||
|
})
|
||||||
);
|
);
|
||||||
context.experienceIncreases = {
|
context.experienceIncreases = {
|
||||||
values: experienceIncreaseValues,
|
values: experienceIncreaseValues,
|
||||||
|
|
@ -328,10 +331,12 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
break;
|
break;
|
||||||
case 'experience':
|
case 'experience':
|
||||||
if (!advancement[choiceKey]) advancement[choiceKey] = [];
|
if (!advancement[choiceKey]) advancement[choiceKey] = [];
|
||||||
const data = checkbox.data.map(
|
const data = checkbox.data.map(data => {
|
||||||
data =>
|
const experience = Object.keys(this.actor.system.experiences).find(
|
||||||
this.actor.system.experiences.find(x => x.id === data)?.description ?? ''
|
x => x === data
|
||||||
);
|
);
|
||||||
|
return this.actor.system.experiences[experience]?.description ?? '';
|
||||||
|
});
|
||||||
advancement[choiceKey].push({ data: data, value: checkbox.value });
|
advancement[choiceKey].push({ data: data, value: checkbox.value });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -354,8 +359,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
new: this.actor.system.resources.stress.max + (advancement.stress ?? 0)
|
new: this.actor.system.resources.stress.max + (advancement.stress ?? 0)
|
||||||
},
|
},
|
||||||
evasion: {
|
evasion: {
|
||||||
old: this.actor.system.evasion.value,
|
old: this.actor.system.evasion,
|
||||||
new: this.actor.system.evasion.value + (advancement.evasion ?? 0)
|
new: this.actor.system.evasion + (advancement.evasion ?? 0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
traits:
|
traits:
|
||||||
|
|
@ -421,8 +426,9 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
if (experienceIncreaseTagify) {
|
if (experienceIncreaseTagify) {
|
||||||
tagifyElement(
|
tagifyElement(
|
||||||
experienceIncreaseTagify,
|
experienceIncreaseTagify,
|
||||||
this.actor.system.experiences.reduce((acc, experience) => {
|
Object.keys(this.actor.system.experiences).reduce((acc, id) => {
|
||||||
acc[experience.id] = { label: experience.description };
|
const experience = this.actor.system.experiences[id];
|
||||||
|
acc[id] = { label: experience.description };
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {}),
|
}, {}),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
|
|
||||||
export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(experiences, bonusDamage, hopeResource, resolve, isNpc) {
|
constructor(experiences, hopeResource, resolve) {
|
||||||
super({}, {});
|
super({}, {});
|
||||||
|
|
||||||
this.experiences = experiences;
|
this.experiences = experiences;
|
||||||
|
|
@ -17,23 +17,13 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
fear: ['d12'],
|
fear: ['d12'],
|
||||||
advantage: null,
|
advantage: null,
|
||||||
disadvantage: null,
|
disadvantage: null,
|
||||||
bonusDamage: bonusDamage.reduce((acc, x) => {
|
|
||||||
if (x.appliesOn === SYSTEM.EFFECTS.applyLocations.attackRoll.id) {
|
|
||||||
acc.push({
|
|
||||||
...x,
|
|
||||||
hopeUses: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, []),
|
|
||||||
hopeResource: hopeResource
|
hopeResource: hopeResource
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
id: 'roll-selection', //Having an id causes a new instance to overwrite previous.
|
id: 'roll-selection',
|
||||||
classes: ['daggerheart', 'views', 'roll-selection'],
|
classes: ['daggerheart', 'views', 'roll-selection'],
|
||||||
position: {
|
position: {
|
||||||
width: 400,
|
width: 400,
|
||||||
|
|
@ -41,8 +31,6 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
selectExperience: this.selectExperience,
|
selectExperience: this.selectExperience,
|
||||||
decreaseHopeUse: this.decreaseHopeUse,
|
|
||||||
increaseHopeUse: this.increaseHopeUse,
|
|
||||||
setAdvantage: this.setAdvantage,
|
setAdvantage: this.setAdvantage,
|
||||||
setDisadvantage: this.setDisadvantage,
|
setDisadvantage: this.setDisadvantage,
|
||||||
finish: this.finish
|
finish: this.finish
|
||||||
|
|
@ -76,9 +64,8 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
context.disadvantage = this.data.disadvantage;
|
context.disadvantage = this.data.disadvantage;
|
||||||
context.experiences = this.experiences.map(x => ({
|
context.experiences = this.experiences.map(x => ({
|
||||||
...x,
|
...x,
|
||||||
selected: this.selectedExperiences.find(selected => selected.id === x.id)
|
selected: this.selectedExperiences.includes(x.id)
|
||||||
}));
|
}));
|
||||||
context.bonusDamage = this.data.bonusDamage;
|
|
||||||
context.hopeResource = this.data.hopeResource + 1;
|
context.hopeResource = this.data.hopeResource + 1;
|
||||||
context.hopeUsed = this.getHopeUsed();
|
context.hopeUsed = this.getHopeUsed();
|
||||||
|
|
||||||
|
|
@ -86,15 +73,7 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
}
|
}
|
||||||
|
|
||||||
static updateSelection(event, _, formData) {
|
static updateSelection(event, _, formData) {
|
||||||
const { bonusDamage, ...rest } = foundry.utils.expandObject(formData.object);
|
const { ...rest } = foundry.utils.expandObject(formData.object);
|
||||||
|
|
||||||
for (var index in bonusDamage) {
|
|
||||||
this.data.bonusDamage[index].initiallySelected = bonusDamage[index].initiallySelected;
|
|
||||||
if (bonusDamage[index].hopeUses) {
|
|
||||||
const value = Number.parseInt(bonusDamage[index].hopeUses);
|
|
||||||
if (!Number.isNaN(value)) this.data.bonusDamage[index].hopeUses = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.data = foundry.utils.mergeObject(this.data, rest);
|
this.data = foundry.utils.mergeObject(this.data, rest);
|
||||||
this.render();
|
this.render();
|
||||||
|
|
@ -104,35 +83,12 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
if (this.selectedExperiences.find(x => x.id === button.dataset.key)) {
|
if (this.selectedExperiences.find(x => x.id === button.dataset.key)) {
|
||||||
this.selectedExperiences = this.selectedExperiences.filter(x => x.id !== button.dataset.key);
|
this.selectedExperiences = this.selectedExperiences.filter(x => x.id !== button.dataset.key);
|
||||||
} else {
|
} else {
|
||||||
this.selectedExperiences = [
|
this.selectedExperiences = [...this.selectedExperiences, button.dataset.key];
|
||||||
...this.selectedExperiences,
|
|
||||||
this.experiences.find(x => x.id === button.dataset.key)
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
getHopeUsed() {
|
|
||||||
return this.data.bonusDamage.reduce((acc, x) => acc + x.hopeUses, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static decreaseHopeUse(_, button) {
|
|
||||||
const index = Number.parseInt(button.dataset.index);
|
|
||||||
if (this.data.bonusDamage[index].hopeUses - 1 >= 0) {
|
|
||||||
this.data.bonusDamage[index].hopeUses -= 1;
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static increaseHopeUse(_, button) {
|
|
||||||
const index = Number.parseInt(button.dataset.index);
|
|
||||||
if (this.data.bonusDamage[index].hopeUses <= this.data.hopeResource + 1) {
|
|
||||||
this.data.bonusDamage[index].hopeUses += 1;
|
|
||||||
this.render(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static setAdvantage() {
|
static setAdvantage() {
|
||||||
this.data.advantage = this.data.advantage ? null : 'd6';
|
this.data.advantage = this.data.advantage ? null : 'd6';
|
||||||
this.data.disadvantage = null;
|
this.data.disadvantage = null;
|
||||||
|
|
@ -149,11 +105,10 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
|
|
||||||
static async finish() {
|
static async finish() {
|
||||||
const { diceOptions, ...rest } = this.data;
|
const { diceOptions, ...rest } = this.data;
|
||||||
|
|
||||||
this.resolve({
|
this.resolve({
|
||||||
...rest,
|
...rest,
|
||||||
experiences: this.selectedExperiences,
|
experiences: this.selectedExperiences.map(x => ({ id: x, ...this.experiences[x] }))
|
||||||
hopeUsed: this.getHopeUsed(),
|
|
||||||
bonusDamage: this.data.bonusDamage.reduce((acc, x) => acc.concat(` + ${1 + x.hopeUses}${x.value}`), '')
|
|
||||||
});
|
});
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -362,7 +362,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
name: x.actor.name,
|
name: x.actor.name,
|
||||||
img: x.actor.img,
|
img: x.actor.img,
|
||||||
difficulty: x.actor.system.difficulty,
|
difficulty: x.actor.system.difficulty,
|
||||||
evasion: x.actor.system.evasion.value
|
evasion: x.actor.system.evasion
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const cls = getDocumentClass('ChatMessage');
|
const cls = getDocumentClass('ChatMessage');
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import DhlevelUp from '../levelup.mjs';
|
||||||
|
|
||||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||||
const { TextEditor } = foundry.applications.ux;
|
const { TextEditor } = foundry.applications.ux;
|
||||||
export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super(options);
|
super(options);
|
||||||
|
|
||||||
|
|
@ -248,7 +248,8 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
ancestry: ancestry[0],
|
ancestry: ancestry[0],
|
||||||
community: community[0],
|
community: community[0],
|
||||||
advancement: {
|
advancement: {
|
||||||
...this.mapAdvancementFeatures(this.document, SYSTEM)
|
// Removed until we have features again
|
||||||
|
// ...this.mapAdvancementFeatures(this.document, SYSTEM)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -265,8 +266,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
vault: vault.map(x => ({
|
vault: vault.map(x => ({
|
||||||
...x,
|
...x,
|
||||||
uuid: x.uuid,
|
uuid: x.uuid,
|
||||||
sendToLoadoutDisabled:
|
sendToLoadoutDisabled: this.document.system.domainCards.loadout.length >= 5
|
||||||
this.document.system.domainCards.loadout.length >= this.document.system.domainData.maxLoadout
|
|
||||||
}))
|
}))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -584,26 +584,21 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
const weapon = await fromUuid(button.dataset.weapon);
|
const weapon = await fromUuid(button.dataset.weapon);
|
||||||
const damage = {
|
const damage = {
|
||||||
value: `${this.document.system.proficiency.value}${weapon.system.damage.value}`,
|
value: `${this.document.system.proficiency.value}${weapon.system.damage.value}`,
|
||||||
type: weapon.system.damage.type,
|
type: weapon.system.damage.type
|
||||||
bonusDamage: this.document.system.bonuses.damage
|
|
||||||
};
|
};
|
||||||
const modifier = this.document.system.traits[weapon.system.trait].value;
|
const modifier = this.document.system.traits[weapon.system.trait].value;
|
||||||
|
|
||||||
const { roll, hope, fear, advantage, disadvantage, modifiers, bonusDamageString } =
|
const { roll, hope, fear, advantage, disadvantage, modifiers } = await this.document.dualityRoll(
|
||||||
await this.document.dualityRoll(
|
{ title: game.i18n.localize(abilities[weapon.system.trait].label), value: modifier },
|
||||||
{ title: game.i18n.localize(abilities[weapon.system.trait].label), value: modifier },
|
event.shiftKey
|
||||||
event.shiftKey,
|
);
|
||||||
damage.bonusDamage
|
|
||||||
);
|
|
||||||
|
|
||||||
damage.value = damage.value.concat(bonusDamageString);
|
|
||||||
|
|
||||||
const targets = Array.from(game.user.targets).map(x => ({
|
const targets = Array.from(game.user.targets).map(x => ({
|
||||||
id: x.id,
|
id: x.id,
|
||||||
name: x.actor.name,
|
name: x.actor.name,
|
||||||
img: x.actor.img,
|
img: x.actor.img,
|
||||||
difficulty: x.actor.system.difficulty,
|
difficulty: x.actor.system.difficulty,
|
||||||
evasion: x.actor.system.evasion.value
|
evasion: x.actor.system.evasion
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const systemData = {
|
const systemData = {
|
||||||
|
|
@ -659,7 +654,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
|
|
||||||
static async moveDomainCard(_, button) {
|
static async moveDomainCard(_, button) {
|
||||||
const toVault = button.dataset.action === 'sendToVault';
|
const toVault = button.dataset.action === 'sendToVault';
|
||||||
if (!toVault && this.document.system.domainCards.loadout.length >= this.document.system.domainData.maxLoadout) {
|
if (!toVault && this.document.system.domainCards.loadout.length >= 5) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -860,15 +855,13 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async experienceDescriptionChange(event) {
|
async experienceDescriptionChange(event) {
|
||||||
const newExperiences = [...this.document.system.experiences];
|
const path = `system.experiences.${event.currentTarget.dataset.experience}.description`;
|
||||||
newExperiences[event.currentTarget.dataset.index].description = event.currentTarget.value;
|
await this.document.update({ [path]: event.currentTarget.value });
|
||||||
await this.document.update({ 'system.experiences': newExperiences });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async experienceValueChange(event) {
|
async experienceValueChange(event) {
|
||||||
const newExperiences = [...this.document.system.experiences];
|
const path = `system.experiences.${event.currentTarget.dataset.index}.value`;
|
||||||
newExperiences[event.currentTarget.dataset.index].value = event.currentTarget.value;
|
await this.document.update({ [path]: event.currentTarget.value });
|
||||||
await this.document.update({ 'system.experiences': newExperiences });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static setStoryEditor(_, button) {
|
static setStoryEditor(_, button) {
|
||||||
|
|
@ -1080,18 +1073,12 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
const itemObject = await fromUuid(item.uuid);
|
const itemObject = await fromUuid(item.uuid);
|
||||||
switch (target) {
|
switch (target) {
|
||||||
case 'weapon-section':
|
case 'weapon-section':
|
||||||
if (
|
if (itemObject.system.secondary && this.document.system.getWeaponBurden === 'twoHanded') {
|
||||||
itemObject.system.secondary &&
|
|
||||||
this.document.system.equippedWeapons.burden === 'twoHanded'
|
|
||||||
) {
|
|
||||||
ui.notifications.info(
|
ui.notifications.info(
|
||||||
game.i18n.localize('DAGGERHEART.Notification.Info.SecondaryEquipWhileTwohanded')
|
game.i18n.localize('DAGGERHEART.Notification.Info.SecondaryEquipWhileTwohanded')
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else if (
|
} else if (itemObject.system.burden === 'twoHanded' && this.document.system.secondaryWeapon) {
|
||||||
itemObject.system.burden === 'twoHanded' &&
|
|
||||||
this.document.system.equippedWeapons.secondary
|
|
||||||
) {
|
|
||||||
ui.notifications.info(
|
ui.notifications.info(
|
||||||
game.i18n.localize('DAGGERHEART.Notification.Info.TwohandedEquipWhileSecondary')
|
game.i18n.localize('DAGGERHEART.Notification.Info.TwohandedEquipWhileSecondary')
|
||||||
);
|
);
|
||||||
|
|
@ -1154,7 +1141,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.document.system.domainCards.total.length === this.document.system.domainData.maxCards) {
|
if (this.document.system.domainCards.total.length === 5) {
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.MaxLoadoutReached'));
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.MaxLoadoutReached'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1164,7 +1151,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.document.system.domainCards.loadout.length >= this.document.system.domainData.maxLoadout) {
|
if (this.document.system.domainCards.loadout.length >= 5) {
|
||||||
itemData.system.inVault = true;
|
itemData.system.inVault = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export { default as DhpPC } from './pc.mjs';
|
export { default as DhCharacter } from './character.mjs';
|
||||||
export { default as DhClass } from './item/class.mjs';
|
export { default as DhClass } from './item/class.mjs';
|
||||||
export { default as DhSubclass } from './item/subclass.mjs';
|
export { default as DhSubclass } from './item/subclass.mjs';
|
||||||
export { default as DhCombat } from './combat.mjs';
|
export { default as DhCombat } from './combat.mjs';
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,28 @@
|
||||||
import { getPathValue } from '../helpers/utils.mjs';
|
import { burden } from '../config/generalConfig.mjs';
|
||||||
import ForeignDocumentUUIDField from './fields/foreignDocumentUUIDField.mjs';
|
import ForeignDocumentUUIDField from './fields/foreignDocumentUUIDField.mjs';
|
||||||
import { LevelOptionType } from './levelTier.mjs';
|
import { LevelOptionType } from './levelTier.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
|
||||||
|
|
||||||
const attributeField = () =>
|
const attributeField = () =>
|
||||||
new fields.SchemaField({
|
new foundry.data.fields.SchemaField({
|
||||||
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
||||||
base: new fields.NumberField({ initial: 0, integer: true }),
|
tierMarked: new foundry.data.fields.BooleanField({ initial: false })
|
||||||
tierMarked: new fields.BooleanField({ required: true, initial: false })
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const resourceField = max =>
|
const resourceField = max =>
|
||||||
new fields.SchemaField({
|
new foundry.data.fields.SchemaField({
|
||||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
||||||
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
max: new foundry.data.fields.NumberField({ initial: max, integer: true })
|
||||||
min: new fields.NumberField({ initial: 0, integer: true }),
|
|
||||||
baseMax: new fields.NumberField({ initial: max, integer: true })
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default class DhpPC extends foundry.abstract.TypeDataModel {
|
export default class DhCharacter extends foundry.abstract.TypeDataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
resources: new fields.SchemaField({
|
resources: new fields.SchemaField({
|
||||||
hitPoints: resourceField(6),
|
hitPoints: resourceField(6),
|
||||||
stress: resourceField(6),
|
stress: resourceField(6),
|
||||||
hope: new fields.SchemaField({
|
hope: resourceField(6)
|
||||||
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 })
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
bonuses: 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({})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
traits: new fields.SchemaField({
|
traits: new fields.SchemaField({
|
||||||
agility: attributeField(),
|
agility: attributeField(),
|
||||||
|
|
@ -49,24 +32,18 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
||||||
presence: attributeField(),
|
presence: attributeField(),
|
||||||
knowledge: attributeField()
|
knowledge: attributeField()
|
||||||
}),
|
}),
|
||||||
proficiency: new fields.SchemaField({
|
proficiency: new fields.NumberField({ initial: 1, integer: true }),
|
||||||
base: new fields.NumberField({ required: true, initial: 1, integer: true }),
|
evasion: new fields.NumberField({ initial: 0, integer: true }),
|
||||||
bonus: new fields.NumberField({ required: true, initial: 0, integer: true })
|
experiences: new fields.TypedObjectField(
|
||||||
}),
|
|
||||||
evasion: new fields.SchemaField({
|
|
||||||
bonus: new fields.NumberField({ initial: 0, integer: true })
|
|
||||||
}),
|
|
||||||
experiences: new fields.ArrayField(
|
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
id: new fields.StringField({ required: true }),
|
|
||||||
description: new fields.StringField({}),
|
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: [
|
initial: {
|
||||||
{ id: foundry.utils.randomID(), description: '', value: 2 },
|
[foundry.utils.randomID()]: { description: '', value: 2 },
|
||||||
{ id: foundry.utils.randomID(), description: '', value: 2 }
|
[foundry.utils.randomID()]: { description: '', value: 2 }
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
gold: new fields.SchemaField({
|
gold: new fields.SchemaField({
|
||||||
|
|
@ -76,27 +53,14 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
||||||
chests: new fields.NumberField({ initial: 0, integer: true })
|
chests: new fields.NumberField({ initial: 0, integer: true })
|
||||||
}),
|
}),
|
||||||
pronouns: new fields.StringField({}),
|
pronouns: new fields.StringField({}),
|
||||||
domainData: new fields.SchemaField({
|
scars: new fields.TypedObjectField(
|
||||||
maxLoadout: new fields.NumberField({ initial: 2, integer: true }),
|
new fields.SchemaField({
|
||||||
maxCards: new fields.NumberField({ initial: 2, integer: true })
|
name: new fields.StringField({}),
|
||||||
}),
|
description: new fields.HTMLField()
|
||||||
story: new fields.SchemaField({
|
})
|
||||||
background: new fields.HTMLField(),
|
),
|
||||||
appearance: new fields.HTMLField(),
|
story: new fields.HTMLField(),
|
||||||
connections: new fields.HTMLField(),
|
description: new fields.HTMLField(),
|
||||||
scars: new fields.ArrayField(
|
|
||||||
new fields.SchemaField({
|
|
||||||
name: new fields.StringField({}),
|
|
||||||
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 })
|
|
||||||
}),
|
|
||||||
class: new fields.SchemaField({
|
class: new fields.SchemaField({
|
||||||
value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }),
|
value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }),
|
||||||
subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true })
|
subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true })
|
||||||
|
|
@ -109,10 +73,6 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get tier() {
|
|
||||||
return this.#getTier(this.levelData.currentLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
get ancestry() {
|
get ancestry() {
|
||||||
return this.parent.items.find(x => x.type === 'ancestry') ?? null;
|
return this.parent.items.find(x => x.type === 'ancestry') ?? null;
|
||||||
}
|
}
|
||||||
|
|
@ -197,57 +157,21 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
||||||
return this.parent.items.find(x => x.type === 'armor' && x.system.equipped);
|
return this.parent.items.find(x => x.type === 'armor' && x.system.equipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
get equippedWeapons() {
|
get primaryWeapon() {
|
||||||
const primaryWeapon = this.parent.items.find(
|
return this.parent.items.find(x => x.type === 'weapon' && x.system.equipped && !x.system.secondary);
|
||||||
x => x.type === 'weapon' && x.system.equipped && !x.system.secondary
|
|
||||||
);
|
|
||||||
const secondaryWeapon = this.parent.items.find(
|
|
||||||
x => x.type === 'weapon' && x.system.equipped && x.system.secondary
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
primary: this.#weaponData(primaryWeapon),
|
|
||||||
secondary: this.#weaponData(secondaryWeapon),
|
|
||||||
burden: this.getBurden(primaryWeapon, secondaryWeapon)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async unequipBeforeEquip(itemToEquip) {
|
get secondaryWeapon() {
|
||||||
const equippedWeapons = this.equippedWeapons;
|
return this.parent.items.find(x => x.type === 'weapon' && x.system.equipped && x.system.secondary);
|
||||||
|
|
||||||
if (itemToEquip.system.secondary) {
|
|
||||||
if (equippedWeapons.primary && equippedWeapons.primary.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
|
||||||
await this.parent.items.get(equippedWeapons.primary.id).update({ 'system.equipped': false });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (equippedWeapons.secondary) {
|
|
||||||
await this.parent.items.get(equippedWeapons.secondary.id).update({ 'system.equipped': false });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (equippedWeapons.secondary && itemToEquip.system.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
|
||||||
await this.parent.items.get(equippedWeapons.secondary.id).update({ 'system.equipped': false });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (equippedWeapons.primary) {
|
|
||||||
await this.parent.items.get(equippedWeapons.primary.id).update({ 'system.equipped': false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get effects() {
|
get getWeaponBurden() {
|
||||||
return this.parent.items.reduce((acc, item) => {
|
return this.primaryWeapon?.system?.burden === burden.twoHanded.value ||
|
||||||
const effects = item.system.effectData;
|
(this.primaryWeapon && this.secondaryWeapon)
|
||||||
if (effects && !item.system.disabled) {
|
? burden.twoHanded.value
|
||||||
for (var key in effects) {
|
: this.primaryWeapon || this.secondaryWeapon
|
||||||
const effect = effects[key];
|
? burden.oneHanded.value
|
||||||
for (var effectEntry of effect) {
|
: null;
|
||||||
if (!acc[key]) acc[key] = [];
|
|
||||||
acc[key].push({ name: item.name, value: effectEntry });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get refreshableFeatures() {
|
get refreshableFeatures() {
|
||||||
|
|
@ -263,43 +187,32 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Should not be done in data?
|
static async unequipBeforeEquip(itemToEquip) {
|
||||||
//TODO: REMOVE THIS
|
const primary = this.primaryWeapon,
|
||||||
#weaponData(weapon) {
|
secondary = this.secondaryWeapon;
|
||||||
return weapon
|
if (itemToEquip.system.secondary) {
|
||||||
? {
|
if (primary && primary.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
||||||
id: weapon.id,
|
await primary.update({ 'system.equipped': false });
|
||||||
name: weapon.name,
|
}
|
||||||
trait: game.i18n.localize(CONFIG.daggerheart.ACTOR.abilities[weapon.system.trait].label),
|
|
||||||
range: CONFIG.daggerheart.GENERAL.range[weapon.system.range],
|
|
||||||
damage: {
|
|
||||||
value: weapon.system.damage.value,
|
|
||||||
type: CONFIG.daggerheart.GENERAL.damageTypes[weapon.system.damage.type]
|
|
||||||
},
|
|
||||||
burden: weapon.system.burden,
|
|
||||||
feature: CONFIG.daggerheart.ITEM.weaponFeatures[weapon.system.feature],
|
|
||||||
img: weapon.img,
|
|
||||||
uuid: weapon.uuid
|
|
||||||
}
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareBaseData() {
|
if (secondary) {
|
||||||
this.resources.hitPoints.max = this.resources.hitPoints.baseMax + this.resources.hitPoints.bonus;
|
await secondary.update({ 'system.equipped': false });
|
||||||
this.resources.stress.max = this.resources.stress.baseMax + this.resources.stress.bonus;
|
}
|
||||||
this.evasion.value = (this.class?.system?.evasion ?? 0) + this.evasion.bonus;
|
} else {
|
||||||
this.proficiency.value = this.proficiency.base + this.proficiency.bonus;
|
if (secondary && itemToEquip.system.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
||||||
|
await secondary.update({ 'system.equipped': false });
|
||||||
|
}
|
||||||
|
|
||||||
for (var attributeKey in this.traits) {
|
if (primary) {
|
||||||
const attribute = this.traits[attributeKey];
|
await primary.update({ 'system.equipped': false });
|
||||||
attribute.value = attribute.base + attribute.bonus;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareDerivedData() {
|
prepareBaseData() {
|
||||||
this.resources.hope.max = 6 - this.story.scars.length;
|
for (var attributeKey in this.traits) {
|
||||||
if (this.resources.hope.value >= this.resources.hope.max) {
|
const attribute = this.traits[attributeKey];
|
||||||
this.resources.hope.value = Math.max(this.resources.hope.max - 1, 0);
|
/* Levleup handling */
|
||||||
}
|
}
|
||||||
|
|
||||||
const armor = this.armor;
|
const armor = this.armor;
|
||||||
|
|
@ -311,57 +224,18 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
||||||
? armor.system.baseThresholds.severe + this.levelData.level.current
|
? armor.system.baseThresholds.severe + this.levelData.level.current
|
||||||
: this.levelData.level.current * 2
|
: this.levelData.level.current * 2
|
||||||
};
|
};
|
||||||
|
|
||||||
this.applyEffects();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applyEffects() {
|
prepareDerivedData() {
|
||||||
const effects = this.effects;
|
this.resources.hope.max -= Object.keys(this.scars).length;
|
||||||
for (var key in effects) {
|
this.resources.hope.value = Math.min(this.resources.hope.value, this.resources.hope.max);
|
||||||
const effectType = effects[key];
|
|
||||||
for (var effect of effectType) {
|
|
||||||
switch (key) {
|
|
||||||
case SYSTEM.EFFECTS.effectTypes.health.id:
|
|
||||||
this.resources.hitPoints.bonus += effect.value.valueData.value;
|
|
||||||
break;
|
|
||||||
case SYSTEM.EFFECTS.effectTypes.stress.id:
|
|
||||||
this.resources.stress.bonus += effect.value.valueData.value;
|
|
||||||
break;
|
|
||||||
case SYSTEM.EFFECTS.effectTypes.damage.id:
|
|
||||||
this.bonuses.damage.push({
|
|
||||||
value: getPathValue(effect.value.valueData.value, this),
|
|
||||||
type: 'physical',
|
|
||||||
description: effect.name,
|
|
||||||
hopeIncrease: effect.value.valueData.hopeIncrease,
|
|
||||||
initiallySelected: effect.value.initiallySelected,
|
|
||||||
appliesOn: effect.value.appliesOn
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getBurden(primary, secondary) {
|
|
||||||
const twoHanded =
|
|
||||||
primary?.system?.burden === 'twoHanded' ||
|
|
||||||
secondary?.system?.burden === 'twoHanded' ||
|
|
||||||
(primary?.system?.burden === 'oneHanded' && secondary?.system?.burden === 'oneHanded');
|
|
||||||
const oneHanded =
|
|
||||||
!twoHanded && (primary?.system?.burden === 'oneHanded' || secondary?.system?.burden === 'oneHanded');
|
|
||||||
|
|
||||||
return twoHanded ? 'twoHanded' : oneHanded ? 'oneHanded' : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#getTier(level) {
|
|
||||||
if (level >= 8) return 3;
|
|
||||||
else if (level >= 5) return 2;
|
|
||||||
else if (level >= 2) return 1;
|
|
||||||
else return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DhPCLevelData extends foundry.abstract.DataModel {
|
class DhPCLevelData extends foundry.abstract.DataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
level: new fields.SchemaField({
|
level: new fields.SchemaField({
|
||||||
current: new fields.NumberField({ required: true, integer: true, initial: 1 }),
|
current: new fields.NumberField({ required: true, integer: true, initial: 1 }),
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
export default class DhVariantRules extends foundry.abstract.DataModel {
|
export default class DhVariantRules extends foundry.abstract.DataModel {
|
||||||
|
static LOCALIZATION_PREFIXES = ['DAGGERHEART.Settings.VariantRules'];
|
||||||
|
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
return {
|
||||||
actionTokens: new fields.SchemaField({
|
actionTokens: new fields.SchemaField({
|
||||||
enabled: new fields.BooleanField({ required: true, initial: false }),
|
enabled: new fields.BooleanField({ required: true, initial: false }),
|
||||||
tokens: new fields.NumberField({ required: true, integer: true, initial: 3 })
|
tokens: new fields.NumberField({ required: true, integer: true, initial: 3 })
|
||||||
})
|
}),
|
||||||
|
useCoins: new fields.BooleanField({ initial: false })
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -173,12 +173,11 @@ export default class DhpActor extends Actor {
|
||||||
return { roll, dice: dice[0], modifiers, advantageState: advantage === true ? 1 : advantage === false ? 2 : 0 };
|
return { roll, dice: dice[0], modifiers, advantageState: advantage === true ? 1 : advantage === false ? 2 : 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
async dualityRoll(modifier, shiftKey, bonusDamage = []) {
|
async dualityRoll(modifier, shiftKey) {
|
||||||
let hopeDice = 'd12',
|
let hopeDice = 'd12',
|
||||||
fearDice = 'd12',
|
fearDice = 'd12',
|
||||||
advantageDice = null,
|
advantageDice = null,
|
||||||
disadvantageDice = null,
|
disadvantageDice = null;
|
||||||
bonusDamageString = '';
|
|
||||||
|
|
||||||
const modifiers =
|
const modifiers =
|
||||||
modifier.value !== null
|
modifier.value !== null
|
||||||
|
|
@ -195,12 +194,9 @@ export default class DhpActor extends Actor {
|
||||||
: [];
|
: [];
|
||||||
if (!shiftKey) {
|
if (!shiftKey) {
|
||||||
const dialogClosed = new Promise((resolve, _) => {
|
const dialogClosed = new Promise((resolve, _) => {
|
||||||
new RollSelectionDialog(
|
new RollSelectionDialog(this.system.experiences, this.system.resources.hope.value, resolve).render(
|
||||||
this.system.experiences,
|
true
|
||||||
bonusDamage,
|
);
|
||||||
this.system.resources.hope.value,
|
|
||||||
resolve
|
|
||||||
).render(true);
|
|
||||||
});
|
});
|
||||||
const result = await dialogClosed;
|
const result = await dialogClosed;
|
||||||
(hopeDice = result.hope),
|
(hopeDice = result.hope),
|
||||||
|
|
@ -214,7 +210,6 @@ export default class DhpActor extends Actor {
|
||||||
title: x.description
|
title: x.description
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
bonusDamageString = result.bonusDamage;
|
|
||||||
|
|
||||||
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
|
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
|
||||||
|
|
||||||
|
|
@ -268,8 +263,7 @@ export default class DhpActor extends Actor {
|
||||||
fear: { dice: fearDice, value: fear },
|
fear: { dice: fearDice, value: fear },
|
||||||
advantage: { dice: advantageDice, value: advantage },
|
advantage: { dice: advantageDice, value: advantage },
|
||||||
disadvantage: { dice: disadvantageDice, value: disadvantage },
|
disadvantage: { dice: disadvantageDice, value: disadvantage },
|
||||||
modifiers: modifiers,
|
modifiers: modifiers
|
||||||
bonusDamageString
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export default class RegisterHandlebarsHelpers {
|
||||||
includes: this.includes,
|
includes: this.includes,
|
||||||
debug: this.debug,
|
debug: this.debug,
|
||||||
signedNumber: this.signedNumber,
|
signedNumber: this.signedNumber,
|
||||||
|
length: this.length,
|
||||||
switch: this.switch,
|
switch: this.switch,
|
||||||
case: this.case
|
case: this.case
|
||||||
});
|
});
|
||||||
|
|
@ -82,6 +83,10 @@ export default class RegisterHandlebarsHelpers {
|
||||||
return number >= 0 ? `+${number}` : number;
|
return number >= 0 ? `+${number}` : number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static length(obj) {
|
||||||
|
return Object.keys(obj).length;
|
||||||
|
}
|
||||||
|
|
||||||
static switch(value, options) {
|
static switch(value, options) {
|
||||||
this.switch_value = value;
|
this.switch_value = value;
|
||||||
this.switch_break = false;
|
this.switch_break = false;
|
||||||
|
|
|
||||||
16
system.json
16
system.json
|
|
@ -163,10 +163,7 @@
|
||||||
"name": "Daggerheart",
|
"name": "Daggerheart",
|
||||||
"sorting": "m",
|
"sorting": "m",
|
||||||
"color": "#08718c",
|
"color": "#08718c",
|
||||||
"packs": [
|
"packs": ["adversaries", "environments"],
|
||||||
"adversaries",
|
|
||||||
"environments"
|
|
||||||
],
|
|
||||||
"folders": [
|
"folders": [
|
||||||
{
|
{
|
||||||
"name": "Character Options",
|
"name": "Character Options",
|
||||||
|
|
@ -186,12 +183,7 @@
|
||||||
"name": "Items",
|
"name": "Items",
|
||||||
"sorting": "m",
|
"sorting": "m",
|
||||||
"color": "#000000",
|
"color": "#000000",
|
||||||
"packs": [
|
"packs": ["weapons", "armors", "consumables", "general-items"]
|
||||||
"weapons",
|
|
||||||
"armors",
|
|
||||||
"consumables",
|
|
||||||
"general-items"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +203,9 @@
|
||||||
},
|
},
|
||||||
"documentTypes": {
|
"documentTypes": {
|
||||||
"Actor": {
|
"Actor": {
|
||||||
"pc": {},
|
"character": {
|
||||||
|
"htmlFields": ["story", "description", "scars.*.description"]
|
||||||
|
},
|
||||||
"adversary": {},
|
"adversary": {},
|
||||||
"environment": {}
|
"environment": {}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{formGroup settingFields.schema.fields.useCoins value=settingFields._source.useCoins localize=true }}
|
||||||
|
|
||||||
<footer class="form-footer">
|
<footer class="form-footer">
|
||||||
<button data-action="reset">
|
<button data-action="reset">
|
||||||
<i class="fa-solid fa-arrow-rotate-left"></i>
|
<i class="fa-solid fa-arrow-rotate-left"></i>
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="attribute-image">
|
<div class="attribute-image">
|
||||||
{{#if ../editAttributes}}
|
{{#if ../editAttributes}}
|
||||||
<select class="attribute-value{{#if (lt attribute.base 0)}} negative{{/if}}{{#if (and (not attribute.base) (not ../abilityScoresFinished))}} unselected{{/if}}" data-attribute="{{key}}">
|
<select class="attribute-value{{#if (lt attribute.value 0)}} negative{{/if}}{{#if (and (not attribute.value) (not ../abilityScoresFinished))}} unselected{{/if}}" data-attribute="{{key}}">
|
||||||
{{#if (not (eq attribute.base 0))}}<option value="">{{attribute.base}}</option>{{/if}}
|
{{#if (not (eq attribute.value 0))}}<option value="">{{attribute.value}}</option>{{/if}}
|
||||||
{{#each ../abilityScoreArray as |option|}}
|
{{#each ../abilityScoreArray as |option|}}
|
||||||
<option value="{{option.value}}"{{#if (eq option.value attribute.base)}} selected="selected"{{/if}}>{{option.name}}</option>
|
<option value="{{option.value}}">{{option.name}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="defense-row">
|
<div class="defense-row">
|
||||||
<div class="defense-section">
|
<div class="defense-section">
|
||||||
<div class="defense-container">
|
<div class="defense-container">
|
||||||
<div class="defense-value">{{document.system.evasion.value}}</div>
|
<div class="defense-value">{{document.system.evasion}}</div>
|
||||||
<img src="systems/daggerheart/assets/AttributeShield.svg" />
|
<img src="systems/daggerheart/assets/AttributeShield.svg" />
|
||||||
<div class="defense-banner">{{localize "DAGGERHEART.Sheets.PC.Defense.Evasion"}}</div>
|
<div class="defense-banner">{{localize "DAGGERHEART.Sheets.PC.Defense.Evasion"}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -16,16 +16,18 @@
|
||||||
<img src="systems/daggerheart/assets/AttributeShield.svg" />
|
<img src="systems/daggerheart/assets/AttributeShield.svg" />
|
||||||
<div class="defense-banner">{{localize "DAGGERHEART.Sheets.PC.Defense.Armor"}}</div>
|
<div class="defense-banner">{{localize "DAGGERHEART.Sheets.PC.Defense.Armor"}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="armor-marks">
|
{{#if document.system.armor.system.marks}}
|
||||||
{{#times (subtract 12 document.system.armorMarks.max)}}
|
<div class="armor-marks">
|
||||||
<input class="mark disabled-mark" type="checkbox" disabled />
|
{{#times (subtract 12 document.system.armor.system.marks.max)}}
|
||||||
{{/times}}
|
<input class="mark disabled-mark" type="checkbox" disabled />
|
||||||
{{#times document.system.armorMarks.max}}
|
{{/times}}
|
||||||
{{#with (add this 1)}}
|
{{#times document.system.armor.system.marks.max}}
|
||||||
<input class="mark" type="checkbox" data-action="toggleMarks" data-value="{{this}}" {{ checked (gte ../../document.system.armor.system.marks.value this) }} />
|
{{#with (add this 1)}}
|
||||||
{{/with}}
|
<input class="mark" type="checkbox" data-action="toggleMarks" data-value="{{this}}" {{ checked (gte ../../document.system.armor.system.marks.value this) }} />
|
||||||
{{/times}}
|
{{/with}}
|
||||||
</div>
|
{{/times}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
<fieldset class="left-main-container experience-container">
|
<fieldset class="left-main-container experience-container">
|
||||||
<legend class="legend">{{localize "DAGGERHEART.Sheets.PC.Experience.Title"}}</legend>
|
<legend class="legend">{{localize "DAGGERHEART.Sheets.PC.Experience.Title"}}</legend>
|
||||||
{{#each document.system.experiences as |experience index|}}
|
{{#each document.system.experiences as |experience id|}}
|
||||||
<div class="experience-row">
|
<div class="experience-row">
|
||||||
<input class="experience-description" data-index={{index}} value="{{experience.description}}" type="text" />
|
<input class="experience-description" data-experience={{id}} value="{{experience.description}}" type="text" />
|
||||||
<div class="experience-value">{{experience.value}}</div>
|
<div class="experience-value">{{experience.value}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{#times (subtract 5 document.system.experiences.length)}}
|
{{#times (subtract 5 (length document.system.experiences))}}
|
||||||
<div class="experience-row">
|
<div class="experience-row">
|
||||||
<input type="text" class="disabled-experience" disabled />
|
<input type="text" class="disabled-experience" disabled />
|
||||||
<div class="experience-value empty"></div>
|
<div class="experience-value empty"></div>
|
||||||
|
|
|
||||||
|
|
@ -11,39 +11,39 @@
|
||||||
<div class="proficiency-container-visual-element"></div>
|
<div class="proficiency-container-visual-element"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="weapons-burden">
|
<div class="weapons-burden">
|
||||||
<i class="fa-solid fa-hand weapons-burden-icon left {{#if (or (eq weapons.burden "oneHanded") (eq weapons.burden "twoHanded"))}}active{{/if}}"></i>
|
<i class="fa-solid fa-hand weapons-burden-icon left {{#if (or (eq weaponBurden "oneHanded") (eq weaponBurden "twoHanded"))}}active{{/if}}"></i>
|
||||||
<i class="fa-solid fa-hand weapons-burden-icon right {{#if (eq weapons.burden "twoHanded")}}active{{/if}}"></i>
|
<i class="fa-solid fa-hand weapons-burden-icon right {{#if (eq weaponBurden "twoHanded")}}active{{/if}}"></i>
|
||||||
</div>
|
</div>
|
||||||
</legend>
|
</legend>
|
||||||
|
|
||||||
<div class="active-item-container">
|
<div class="active-item-container">
|
||||||
<h2 class="weapons-label-row">
|
<h2 class="weapons-label-row">
|
||||||
{{localize "DAGGERHEART.Sheets.PC.Weapons.PrimaryTitle"}}
|
{{localize "DAGGERHEART.Sheets.PC.Weapons.PrimaryTitle"}}
|
||||||
{{#if weapons.primary}}
|
{{#if primaryWeapon}}
|
||||||
<img class="damage-roll" data-action="attackRoll" data-weapon="{{weapons.primary.uuid}}" src="icons/svg/d12-grey.svg" />
|
<img class="damage-roll" data-action="attackRoll" data-weapon="{{primaryWeapon.uuid}}" src="icons/svg/d12-grey.svg" />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
<input value="{{weapons.primary.name}}" type="text" />
|
<input value="{{primaryWeapon.name}}" type="text" />
|
||||||
<input value="{{localize weapons.primary.trait}}" type="text" />
|
<input value="{{localize primaryWeapon.trait}}" type="text" />
|
||||||
<input value="{{localize weapons.primary.range.label}}" type="text" />
|
<input value="{{localize primaryWeapon.range.label}}" type="text" />
|
||||||
<input value="{{weapons.primary.damage.value}} {{#if weapons.primary}}({{localize weapons.primary.damage.type.abbreviation}}){{/if}}" type="text" />
|
<input value="{{primaryWeapon.damage.value}} {{#if primaryWeapon}}({{localize primaryWeapon.damage.type.abbreviation}}){{/if}}" type="text" />
|
||||||
</div>
|
</div>
|
||||||
<input value="{{localize weapons.primary.feature.label}} {{#if weapons.primary.feature}}({{localize weapons.primary.feature.description}}){{/if}}" type="text" />
|
<input value="{{localize primaryWeapon.feature.label}} {{#if primaryWeapon.feature}}({{localize primaryWeapon.feature.description}}){{/if}}" type="text" />
|
||||||
</div>
|
</div>
|
||||||
<div class="active-item-container">
|
<div class="active-item-container">
|
||||||
<h2 class="weapons-label-row">
|
<h2 class="weapons-label-row">
|
||||||
{{localize "DAGGERHEART.Sheets.PC.Weapons.SecondaryTitle"}}
|
{{localize "DAGGERHEART.Sheets.PC.Weapons.SecondaryTitle"}}
|
||||||
{{#if weapons.secondary}}
|
{{#if secondaryWeapon}}
|
||||||
<img class="damage-roll" data-action="damageRoll" data-value="{{weapons.secondary.damage.value}}" src="icons/svg/d12-grey.svg" />
|
<img class="damage-roll" data-action="damageRoll" data-value="{{secondaryWeapon.damage.value}}" src="icons/svg/d12-grey.svg" />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
<input value="{{weapons.secondary.name}}" type="text" />
|
<input value="{{secondaryWeapon.name}}" type="text" />
|
||||||
<input value="{{localize weapons.secondary.trait}}" type="text" />
|
<input value="{{localize secondaryWeapon.trait}}" type="text" />
|
||||||
<input value="{{localize weapons.secondary.range.label}}" type="text" />
|
<input value="{{localize secondaryWeapon.range.label}}" type="text" />
|
||||||
<input value="{{weapons.secondary.damage.label}} {{#if weapons.secondary}}({{localize weapons.secondary.damage.type.abbreviation}}){{/if}}" type="text" />
|
<input value="{{secondaryWeapon.damage.label}} {{#if secondaryWeapon}}({{localize secondaryWeapon.damage.type.abbreviation}}){{/if}}" type="text" />
|
||||||
</div>
|
</div>
|
||||||
<input value="{{localize weapons.secondary.feature.name}} {{#if weapons.secondary.feature}}({{localize weapons.secondary.feature.description}}){{/if}}" style="text-overflow: ellipsis;" type="text" />
|
<input value="{{localize secondaryWeapon.feature.name}} {{#if secondaryWeapon.feature}}({{localize secondaryWeapon.feature.description}}){{/if}}" style="text-overflow: ellipsis;" type="text" />
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="body-section flex3">
|
<div class="body-section flex3">
|
||||||
{{> "systems/daggerheart/templates/sheets/parts/attributes.hbs" }}
|
{{> "systems/daggerheart/templates/sheets/parts/attributes.hbs" }}
|
||||||
{{> "systems/daggerheart/templates/sheets/parts/weapons.hbs" weapons=document.system.equippedWeapons proficiency=document.system.proficiency.value }}
|
{{> "systems/daggerheart/templates/sheets/parts/weapons.hbs" primaryWeapon=document.system.primaryWeapon secondaryWeapon=document.system.secondaryWeapon weaponBurden=document.system.getWeaponBurden proficiency=document.system.proficiency.value }}
|
||||||
{{> "systems/daggerheart/templates/sheets/parts/armor.hbs" armor=document.system.armor }}
|
{{> "systems/daggerheart/templates/sheets/parts/armor.hbs" armor=document.system.armor }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -15,22 +15,6 @@
|
||||||
<button class="disadvantage flex1 {{#if this.advantage}}selected{{/if}}" data-action="setAdvantage">Advantage</button>
|
<button class="disadvantage flex1 {{#if this.advantage}}selected{{/if}}" data-action="setAdvantage">Advantage</button>
|
||||||
<button class="disadvantage flex1 {{#if this.disadvantage}}selected{{/if}}" data-action="setDisadvantage">Disadvantage</button>
|
<button class="disadvantage flex1 {{#if this.disadvantage}}selected{{/if}}" data-action="setDisadvantage">Disadvantage</button>
|
||||||
</div>
|
</div>
|
||||||
{{!-- <div class="form-group">
|
|
||||||
<label>Advantage</label>
|
|
||||||
<div class="form-fields">
|
|
||||||
<select name="advantage" {{#if this.disadvantage}}disabled{{/if}}>
|
|
||||||
{{selectOptions this.diceOptions selected=this.advantage valueAttr="value" labelAttr="name" localize=true blank=""}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Disadvantage</label>
|
|
||||||
<div class="form-fields">
|
|
||||||
<select name="disadvantage" {{#if this.advantage}}disabled{{/if}}>
|
|
||||||
{{selectOptions this.diceOptions selected=this.disadvantage valueAttr="value" labelAttr="name" localize=true blank=""}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div> --}}
|
|
||||||
{{#if (not this.isNpc)}}
|
{{#if (not this.isNpc)}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Hope</label>
|
<label>Hope</label>
|
||||||
|
|
@ -49,24 +33,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#each this.bonusDamage as |damage index|}}
|
|
||||||
<div class="form-group">
|
|
||||||
<label><strong>{{damage.description}}</strong></label>
|
|
||||||
<div class="form-fields">
|
|
||||||
<label>Enabled</label>
|
|
||||||
<input style="align-self: baseline;" type="checkbox" name="bonusDamage.{{index}}.initiallySelected" {{checked damage.initiallySelected}} />
|
|
||||||
{{#if (and damage.initiallySelected damage.hopeIncrease)}}
|
|
||||||
|
|
||||||
<label>Hope</label>
|
|
||||||
<div class="hope-container">
|
|
||||||
<i data-action="decreaseHopeUse" data-index="{{index}}" class="fa-solid fa-caret-left icon-button {{#if (eq damage.hopeUses 0)}}disabled{{/if}}"></i>
|
|
||||||
<div>{{damage.hopeUses}}</div>
|
|
||||||
<i data-action="increaseHopeUse" data-index="{{index}}" class="fa-solid fa-caret-right icon-button {{#if (eq ../hopeUsed ../hopeResource)}}disabled{{/if}}"></i>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
<button data-action="finish">Roll</button>
|
<button data-action="finish">Roll</button>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue