mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 11:41:08 +01:00
Improved Character datamodel
This commit is contained in:
parent
746e0f239a
commit
213a07b64c
20 changed files with 175 additions and 381 deletions
|
|
@ -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 DhpClassSheet } from './sheets/items/class.mjs';
|
||||
export { default as DhpSubclass } from './sheets/items/subclass.mjs';
|
||||
|
|
|
|||
|
|
@ -149,7 +149,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
const experienceIncreaseValues = experienceIncreases
|
||||
.filter(exp => exp.data.length > 0)
|
||||
.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 = {
|
||||
values: experienceIncreaseValues,
|
||||
|
|
@ -328,10 +331,12 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
break;
|
||||
case 'experience':
|
||||
if (!advancement[choiceKey]) advancement[choiceKey] = [];
|
||||
const data = checkbox.data.map(
|
||||
data =>
|
||||
this.actor.system.experiences.find(x => x.id === data)?.description ?? ''
|
||||
);
|
||||
const data = checkbox.data.map(data => {
|
||||
const experience = Object.keys(this.actor.system.experiences).find(
|
||||
x => x === data
|
||||
);
|
||||
return this.actor.system.experiences[experience]?.description ?? '';
|
||||
});
|
||||
advancement[choiceKey].push({ data: data, value: checkbox.value });
|
||||
break;
|
||||
}
|
||||
|
|
@ -354,8 +359,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
new: this.actor.system.resources.stress.max + (advancement.stress ?? 0)
|
||||
},
|
||||
evasion: {
|
||||
old: this.actor.system.evasion.value,
|
||||
new: this.actor.system.evasion.value + (advancement.evasion ?? 0)
|
||||
old: this.actor.system.evasion,
|
||||
new: this.actor.system.evasion + (advancement.evasion ?? 0)
|
||||
}
|
||||
},
|
||||
traits:
|
||||
|
|
@ -421,8 +426,9 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
if (experienceIncreaseTagify) {
|
||||
tagifyElement(
|
||||
experienceIncreaseTagify,
|
||||
this.actor.system.experiences.reduce((acc, experience) => {
|
||||
acc[experience.id] = { label: experience.description };
|
||||
Object.keys(this.actor.system.experiences).reduce((acc, id) => {
|
||||
const experience = this.actor.system.experiences[id];
|
||||
acc[id] = { label: experience.description };
|
||||
|
||||
return acc;
|
||||
}, {}),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
|
||||
export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(experiences, bonusDamage, hopeResource, resolve, isNpc) {
|
||||
constructor(experiences, hopeResource, resolve) {
|
||||
super({}, {});
|
||||
|
||||
this.experiences = experiences;
|
||||
|
|
@ -17,23 +17,13 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
|||
fear: ['d12'],
|
||||
advantage: 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
|
||||
};
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
id: 'roll-selection', //Having an id causes a new instance to overwrite previous.
|
||||
id: 'roll-selection',
|
||||
classes: ['daggerheart', 'views', 'roll-selection'],
|
||||
position: {
|
||||
width: 400,
|
||||
|
|
@ -41,8 +31,6 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
|||
},
|
||||
actions: {
|
||||
selectExperience: this.selectExperience,
|
||||
decreaseHopeUse: this.decreaseHopeUse,
|
||||
increaseHopeUse: this.increaseHopeUse,
|
||||
setAdvantage: this.setAdvantage,
|
||||
setDisadvantage: this.setDisadvantage,
|
||||
finish: this.finish
|
||||
|
|
@ -76,9 +64,8 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
|||
context.disadvantage = this.data.disadvantage;
|
||||
context.experiences = this.experiences.map(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.hopeUsed = this.getHopeUsed();
|
||||
|
||||
|
|
@ -86,15 +73,7 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
|||
}
|
||||
|
||||
static updateSelection(event, _, formData) {
|
||||
const { bonusDamage, ...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;
|
||||
}
|
||||
}
|
||||
const { ...rest } = foundry.utils.expandObject(formData.object);
|
||||
|
||||
this.data = foundry.utils.mergeObject(this.data, rest);
|
||||
this.render();
|
||||
|
|
@ -104,35 +83,12 @@ 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, button.dataset.key];
|
||||
}
|
||||
|
||||
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() {
|
||||
this.data.advantage = this.data.advantage ? null : 'd6';
|
||||
this.data.disadvantage = null;
|
||||
|
|
@ -149,11 +105,10 @@ 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}`), '')
|
||||
experiences: this.selectedExperiences.map(x => ({ id: x, ...this.experiences[x] }))
|
||||
});
|
||||
this.close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
name: x.actor.name,
|
||||
img: x.actor.img,
|
||||
difficulty: x.actor.system.difficulty,
|
||||
evasion: x.actor.system.evasion.value
|
||||
evasion: x.actor.system.evasion
|
||||
}));
|
||||
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import DhlevelUp from '../levelup.mjs';
|
|||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
const { TextEditor } = foundry.applications.ux;
|
||||
export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||
export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
|
||||
|
|
@ -248,7 +248,8 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
ancestry: ancestry[0],
|
||||
community: community[0],
|
||||
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 => ({
|
||||
...x,
|
||||
uuid: x.uuid,
|
||||
sendToLoadoutDisabled:
|
||||
this.document.system.domainCards.loadout.length >= this.document.system.domainData.maxLoadout
|
||||
sendToLoadoutDisabled: this.document.system.domainCards.loadout.length >= 5
|
||||
}))
|
||||
};
|
||||
|
||||
|
|
@ -584,26 +584,21 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const weapon = await fromUuid(button.dataset.weapon);
|
||||
const damage = {
|
||||
value: `${this.document.system.proficiency.value}${weapon.system.damage.value}`,
|
||||
type: weapon.system.damage.type,
|
||||
bonusDamage: this.document.system.bonuses.damage
|
||||
type: weapon.system.damage.type
|
||||
};
|
||||
const modifier = this.document.system.traits[weapon.system.trait].value;
|
||||
|
||||
const { roll, hope, fear, advantage, disadvantage, modifiers, bonusDamageString } =
|
||||
await this.document.dualityRoll(
|
||||
{ title: game.i18n.localize(abilities[weapon.system.trait].label), value: modifier },
|
||||
event.shiftKey,
|
||||
damage.bonusDamage
|
||||
);
|
||||
|
||||
damage.value = damage.value.concat(bonusDamageString);
|
||||
const { roll, hope, fear, advantage, disadvantage, modifiers } = await this.document.dualityRoll(
|
||||
{ title: game.i18n.localize(abilities[weapon.system.trait].label), 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.value
|
||||
evasion: x.actor.system.evasion
|
||||
}));
|
||||
|
||||
const systemData = {
|
||||
|
|
@ -659,7 +654,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
|
||||
static async moveDomainCard(_, button) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -860,15 +855,13 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
}
|
||||
|
||||
async experienceDescriptionChange(event) {
|
||||
const newExperiences = [...this.document.system.experiences];
|
||||
newExperiences[event.currentTarget.dataset.index].description = event.currentTarget.value;
|
||||
await this.document.update({ 'system.experiences': newExperiences });
|
||||
const path = `system.experiences.${event.currentTarget.dataset.experience}.description`;
|
||||
await this.document.update({ [path]: event.currentTarget.value });
|
||||
}
|
||||
|
||||
async experienceValueChange(event) {
|
||||
const newExperiences = [...this.document.system.experiences];
|
||||
newExperiences[event.currentTarget.dataset.index].value = event.currentTarget.value;
|
||||
await this.document.update({ 'system.experiences': newExperiences });
|
||||
const path = `system.experiences.${event.currentTarget.dataset.index}.value`;
|
||||
await this.document.update({ [path]: event.currentTarget.value });
|
||||
}
|
||||
|
||||
static setStoryEditor(_, button) {
|
||||
|
|
@ -1080,18 +1073,12 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const itemObject = await fromUuid(item.uuid);
|
||||
switch (target) {
|
||||
case 'weapon-section':
|
||||
if (
|
||||
itemObject.system.secondary &&
|
||||
this.document.system.equippedWeapons.burden === 'twoHanded'
|
||||
) {
|
||||
if (itemObject.system.secondary && this.document.system.getWeaponBurden === 'twoHanded') {
|
||||
ui.notifications.info(
|
||||
game.i18n.localize('DAGGERHEART.Notification.Info.SecondaryEquipWhileTwohanded')
|
||||
);
|
||||
return;
|
||||
} else if (
|
||||
itemObject.system.burden === 'twoHanded' &&
|
||||
this.document.system.equippedWeapons.secondary
|
||||
) {
|
||||
} else if (itemObject.system.burden === 'twoHanded' && this.document.system.secondaryWeapon) {
|
||||
ui.notifications.info(
|
||||
game.i18n.localize('DAGGERHEART.Notification.Info.TwohandedEquipWhileSecondary')
|
||||
);
|
||||
|
|
@ -1154,7 +1141,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
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'));
|
||||
return;
|
||||
}
|
||||
|
|
@ -1164,7 +1151,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -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 DhSubclass } from './item/subclass.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 { LevelOptionType } from './levelTier.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
const attributeField = () =>
|
||||
new fields.SchemaField({
|
||||
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||
base: new fields.NumberField({ initial: 0, integer: true }),
|
||||
tierMarked: new fields.BooleanField({ required: true, initial: false })
|
||||
new foundry.data.fields.SchemaField({
|
||||
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
||||
tierMarked: new foundry.data.fields.BooleanField({ initial: false })
|
||||
});
|
||||
|
||||
const resourceField = max =>
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ initial: 0, integer: true }),
|
||||
bonus: new fields.NumberField({ initial: 0, integer: true }),
|
||||
min: new fields.NumberField({ initial: 0, integer: true }),
|
||||
baseMax: new fields.NumberField({ initial: max, integer: true })
|
||||
new foundry.data.fields.SchemaField({
|
||||
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
||||
max: new foundry.data.fields.NumberField({ initial: max, integer: true })
|
||||
});
|
||||
|
||||
export default class DhpPC extends foundry.abstract.TypeDataModel {
|
||||
export default class DhCharacter extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
resources: new fields.SchemaField({
|
||||
hitPoints: resourceField(6),
|
||||
stress: resourceField(6),
|
||||
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 })
|
||||
})
|
||||
}),
|
||||
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({})
|
||||
})
|
||||
)
|
||||
hope: resourceField(6)
|
||||
}),
|
||||
traits: new fields.SchemaField({
|
||||
agility: attributeField(),
|
||||
|
|
@ -49,24 +32,18 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
|||
presence: attributeField(),
|
||||
knowledge: attributeField()
|
||||
}),
|
||||
proficiency: new fields.SchemaField({
|
||||
base: new fields.NumberField({ required: true, initial: 1, integer: true }),
|
||||
bonus: new fields.NumberField({ required: true, initial: 0, integer: true })
|
||||
}),
|
||||
evasion: new fields.SchemaField({
|
||||
bonus: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
experiences: new fields.ArrayField(
|
||||
proficiency: new fields.NumberField({ initial: 1, integer: true }),
|
||||
evasion: new fields.NumberField({ initial: 0, integer: true }),
|
||||
experiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({ required: true }),
|
||||
description: new fields.StringField({}),
|
||||
value: new fields.NumberField({ integer: true, nullable: true, initial: null })
|
||||
}),
|
||||
{
|
||||
initial: [
|
||||
{ id: foundry.utils.randomID(), description: '', value: 2 },
|
||||
{ id: foundry.utils.randomID(), description: '', value: 2 }
|
||||
]
|
||||
initial: {
|
||||
[foundry.utils.randomID()]: { description: '', value: 2 },
|
||||
[foundry.utils.randomID()]: { description: '', value: 2 }
|
||||
}
|
||||
}
|
||||
),
|
||||
gold: new fields.SchemaField({
|
||||
|
|
@ -76,27 +53,14 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
|||
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 })
|
||||
}),
|
||||
story: new fields.SchemaField({
|
||||
background: new fields.HTMLField(),
|
||||
appearance: new fields.HTMLField(),
|
||||
connections: 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 })
|
||||
}),
|
||||
scars: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
name: new fields.StringField({}),
|
||||
description: new fields.HTMLField()
|
||||
})
|
||||
),
|
||||
story: new fields.HTMLField(),
|
||||
description: new fields.HTMLField(),
|
||||
class: new fields.SchemaField({
|
||||
value: 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() {
|
||||
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);
|
||||
}
|
||||
|
||||
get equippedWeapons() {
|
||||
const primaryWeapon = this.parent.items.find(
|
||||
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)
|
||||
};
|
||||
get primaryWeapon() {
|
||||
return this.parent.items.find(x => x.type === 'weapon' && x.system.equipped && !x.system.secondary);
|
||||
}
|
||||
|
||||
static async unequipBeforeEquip(itemToEquip) {
|
||||
const equippedWeapons = this.equippedWeapons;
|
||||
|
||||
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 secondaryWeapon() {
|
||||
return this.parent.items.find(x => x.type === 'weapon' && x.system.equipped && x.system.secondary);
|
||||
}
|
||||
|
||||
get effects() {
|
||||
return this.parent.items.reduce((acc, item) => {
|
||||
const effects = item.system.effectData;
|
||||
if (effects && !item.system.disabled) {
|
||||
for (var key in effects) {
|
||||
const effect = effects[key];
|
||||
for (var effectEntry of effect) {
|
||||
if (!acc[key]) acc[key] = [];
|
||||
acc[key].push({ name: item.name, value: effectEntry });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
get getWeaponBurden() {
|
||||
return this.primaryWeapon?.system?.burden === burden.twoHanded.value ||
|
||||
(this.primaryWeapon && this.secondaryWeapon)
|
||||
? burden.twoHanded.value
|
||||
: this.primaryWeapon || this.secondaryWeapon
|
||||
? burden.oneHanded.value
|
||||
: null;
|
||||
}
|
||||
|
||||
get refreshableFeatures() {
|
||||
|
|
@ -263,43 +187,32 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
|||
);
|
||||
}
|
||||
|
||||
//Should not be done in data?
|
||||
//TODO: REMOVE THIS
|
||||
#weaponData(weapon) {
|
||||
return weapon
|
||||
? {
|
||||
id: weapon.id,
|
||||
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;
|
||||
}
|
||||
static async unequipBeforeEquip(itemToEquip) {
|
||||
const primary = this.primaryWeapon,
|
||||
secondary = this.secondaryWeapon;
|
||||
if (itemToEquip.system.secondary) {
|
||||
if (primary && primary.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
||||
await primary.update({ 'system.equipped': false });
|
||||
}
|
||||
|
||||
prepareBaseData() {
|
||||
this.resources.hitPoints.max = this.resources.hitPoints.baseMax + this.resources.hitPoints.bonus;
|
||||
this.resources.stress.max = this.resources.stress.baseMax + this.resources.stress.bonus;
|
||||
this.evasion.value = (this.class?.system?.evasion ?? 0) + this.evasion.bonus;
|
||||
this.proficiency.value = this.proficiency.base + this.proficiency.bonus;
|
||||
if (secondary) {
|
||||
await secondary.update({ 'system.equipped': false });
|
||||
}
|
||||
} else {
|
||||
if (secondary && itemToEquip.system.burden === SYSTEM.GENERAL.burden.twoHanded.value) {
|
||||
await secondary.update({ 'system.equipped': false });
|
||||
}
|
||||
|
||||
for (var attributeKey in this.traits) {
|
||||
const attribute = this.traits[attributeKey];
|
||||
attribute.value = attribute.base + attribute.bonus;
|
||||
if (primary) {
|
||||
await primary.update({ 'system.equipped': false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
this.resources.hope.max = 6 - this.story.scars.length;
|
||||
if (this.resources.hope.value >= this.resources.hope.max) {
|
||||
this.resources.hope.value = Math.max(this.resources.hope.max - 1, 0);
|
||||
prepareBaseData() {
|
||||
for (var attributeKey in this.traits) {
|
||||
const attribute = this.traits[attributeKey];
|
||||
/* Levleup handling */
|
||||
}
|
||||
|
||||
const armor = this.armor;
|
||||
|
|
@ -311,57 +224,18 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
|
|||
? armor.system.baseThresholds.severe + this.levelData.level.current
|
||||
: this.levelData.level.current * 2
|
||||
};
|
||||
|
||||
this.applyEffects();
|
||||
}
|
||||
|
||||
applyEffects() {
|
||||
const effects = this.effects;
|
||||
for (var key in effects) {
|
||||
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;
|
||||
prepareDerivedData() {
|
||||
this.resources.hope.max -= Object.keys(this.scars).length;
|
||||
this.resources.hope.value = Math.min(this.resources.hope.value, this.resources.hope.max);
|
||||
}
|
||||
}
|
||||
|
||||
class DhPCLevelData extends foundry.abstract.DataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
level: new fields.SchemaField({
|
||||
current: new fields.NumberField({ required: true, integer: true, initial: 1 }),
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
export default class DhVariantRules extends foundry.abstract.DataModel {
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.Settings.VariantRules'];
|
||||
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
actionTokens: new fields.SchemaField({
|
||||
enabled: new fields.BooleanField({ required: true, initial: false }),
|
||||
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 };
|
||||
}
|
||||
|
||||
async dualityRoll(modifier, shiftKey, bonusDamage = []) {
|
||||
async dualityRoll(modifier, shiftKey) {
|
||||
let hopeDice = 'd12',
|
||||
fearDice = 'd12',
|
||||
advantageDice = null,
|
||||
disadvantageDice = null,
|
||||
bonusDamageString = '';
|
||||
disadvantageDice = null;
|
||||
|
||||
const modifiers =
|
||||
modifier.value !== null
|
||||
|
|
@ -195,12 +194,9 @@ export default class DhpActor extends Actor {
|
|||
: [];
|
||||
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, this.system.resources.hope.value, resolve).render(
|
||||
true
|
||||
);
|
||||
});
|
||||
const result = await dialogClosed;
|
||||
(hopeDice = result.hope),
|
||||
|
|
@ -214,7 +210,6 @@ export default class DhpActor extends Actor {
|
|||
title: x.description
|
||||
})
|
||||
);
|
||||
bonusDamageString = result.bonusDamage;
|
||||
|
||||
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 },
|
||||
advantage: { dice: advantageDice, value: advantage },
|
||||
disadvantage: { dice: disadvantageDice, value: disadvantage },
|
||||
modifiers: modifiers,
|
||||
bonusDamageString
|
||||
modifiers: modifiers
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export default class RegisterHandlebarsHelpers {
|
|||
includes: this.includes,
|
||||
debug: this.debug,
|
||||
signedNumber: this.signedNumber,
|
||||
length: this.length,
|
||||
switch: this.switch,
|
||||
case: this.case
|
||||
});
|
||||
|
|
@ -82,6 +83,10 @@ export default class RegisterHandlebarsHelpers {
|
|||
return number >= 0 ? `+${number}` : number;
|
||||
}
|
||||
|
||||
static length(obj) {
|
||||
return Object.keys(obj).length;
|
||||
}
|
||||
|
||||
static switch(value, options) {
|
||||
this.switch_value = value;
|
||||
this.switch_break = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue