Set up DhLevelTier datamodel

This commit is contained in:
WBHarry 2025-05-27 13:43:45 +02:00
parent 63274d67ce
commit 0e0507fe6f
8 changed files with 462 additions and 110 deletions

View file

@ -301,39 +301,43 @@
} }
}, },
"LevelUp": { "LevelUp": {
"Tier1": { "Options": {
"Label": "Level 2-4", "trait": "Gain a +1 bonus to two unmarked character traits and mark them.",
"InfoLabel": "At Level 2, take an additional Experience.", "hitPoint": "Permanently gain one Hit Point slot.",
"Pretext": "When you level up, record it on your character sheet, then choose two available options from the list below and mark them.", "stress": "Permanently gain one Stress slot.",
"Posttext": "Then increase your Severe Damage Threshold by +2 and choose a new Domain Deck card at your Level or lower." "experience": "Permanently gain a +1 bonus to two experiences.",
"domainCard": "Choose an additional domain card of your level or lower from a domain you have access to (up to level {maxLevel})",
"evasion": "Permanently gain a +1 bonus to your Evasion.",
"subclass": "Take an upgraded subclass card. Then cross out the multiclass option for this tier.",
"proficiency": "Increase your Proficiency by +1.",
"multiclass": "Multiclass: Choose an additional class for your character, then cross out an unused “Take an upgraded subclass card” and the other multiclass option on this sheet."
}, },
"Tier2": { "Tier2": {
"Label": "Level 5-7", "Label": "Levels 2-4",
"InfoLabel": "At Level 5, take an additional Experience and clear all marks on Character Traits.", "InfoLabel": "At Level 2, gain an additional Experience at +2 and gain a +1 bonus to your Proficiency.",
"Pretext": "When you level up, record it on your character sheet, then choose two from the list below or any unmarked from the previous tier.", "Pretext": "Choose two options from the list below",
"Posttext": "Then, increase your Damage Thresholds: Major by +1 and Severe by +3. Then choose a new Domain Deck card at your Level or lower. If your loadout is full, you may choose a card to swap." "Posttext": "Take an additional domain card of your level or lower from a domain you have access to."
}, },
"Tier3": { "Tier3": {
"Label": "Level 8-10", "Label": "Levels 5-7",
"InfoLabel": "At Level 5, take an additional Experience and clear all marks on Character Traits.",
"Pretext": "When you level up, record it on your character sheet, then choose two from the list below or any unmarked from the previous tier.",
"Posttext": "Take an additional domain card of your level or lower from a domain you have access to."
},
"Tier4": {
"Label": "Levels 8-10",
"InfoLabel": "At Level 8, take an additional Experience and clear all marks on Character Traits.", "InfoLabel": "At Level 8, take an additional Experience and clear all marks on Character Traits.",
"Pretext": "When you level up, record it on your character sheet, then choose two from the list below or any unmarked from the previous tier.", "Pretext": "When you level up, record it on your character sheet, then choose two from the list below or any unmarked from the previous tier.",
"Posttext": "Then, increase your Damage Thresholds: Minor by +1, Major by +2, and Severe by +4. Then choose a new Domain Deck card at your Level or lower. If your loadout is full, you may choose a card to swap." "Posttext": "Take an additional domain card of your level or lower from a domain you have access to."
}, },
"ChoiceDescriptions": { "ChoiceDescriptions": {
"Attributes": "Increase two unmarked Character Traits by +1 and mark them.", "Attributes": "Gain a +1 bonus to two unmarked character traits and mark them.",
"HitPointSlots": "Permanently add one Hit Point Slot.", "HitPointSlots": "Permanently gain one Hit Point slot.",
"StressSlots": "Permanently add one Stress Slot.", "StressSlots": "Permanently gain one Stress slot.",
"Experiences": "Increase two Experiences by +1.", "Experiences": "Permanently gain a +1 bonus to two experiences.",
"Proficiency": "Increase your Proficiency by +1", "DomainCard": "Choose an additional domain card of your level or lower from a domain you have access to (up to level {maxLevel})",
"ArmorOrEvasionSlot": "Permanently add one Armor Slot or take +1 to your Evasion.", "Evasion": "Permanently gain a +1 bonus to your Evasion.",
"MajorDamageThreshold2": "Increase your Major Damage Threshold by +2.", "Proficiency": "Increase your Proficiency by +1.",
"SevereDamageThreshold2": "Increase your Severe Damage Threshold by +2.",
"MinorDamageThreshold2": "Increase your Minor Damage Threshold by +2.",
"SevereDamageThreshold3": "Increase your Severe Damage Threshold by +3.",
"Major2OrSevere4DamageThreshold": "Increase your Major Damage Threshold by +2 or Severe Damage Threshold by +4",
"Minor1OrMajor1DamageThreshold": "Increase your Minor or Major Damage Threshold by +1.",
"SevereDamageThreshold4": "Increase your Severe Damage Threshold by +4.",
"MajorDamageThreshold1": "Increase your Major Damage Threshold by +1.",
"Subclass": "Take an upgraded subclass card. Then cross out the multiclass option for this tier.", "Subclass": "Take an upgraded subclass card. Then cross out the multiclass option for this tier.",
"Multiclass": "Multiclass: Choose an additional class for your character, then cross out an unused “Take an upgraded subclass card” and the other multiclass option on this sheet." "Multiclass": "Multiclass: Choose an additional class for your character, then cross out an unused “Take an upgraded subclass card” and the other multiclass option on this sheet."
} }

View file

@ -1,4 +1,5 @@
import { DualityRollColor } from '../config/settingsConfig.mjs'; import { DualityRollColor } from '../config/settingsConfig.mjs';
import { defaultLevelTiers, DhLevelTiers } from '../data/levelTier.mjs';
class DhpAutomationSettings extends FormApplication { class DhpAutomationSettings extends FormApplication {
constructor(object = {}, options = {}) { constructor(object = {}, options = {}) {
@ -225,6 +226,23 @@ export const registerDHPSettings = () => {
default: DualityRollColor.colorful.value default: DualityRollColor.colorful.value
}); });
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.DualityRollColor, {
name: game.i18n.localize('DAGGERHEART.Settings.DualityRollColor.Name'),
hint: game.i18n.localize('DAGGERHEART.Settings.DualityRollColor.Hint'),
scope: 'world',
config: true,
type: Number,
choices: Object.values(DualityRollColor),
default: DualityRollColor.colorful.value
});
game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers, {
scope: 'world',
config: false,
type: DhLevelTiers,
default: defaultLevelTiers
});
game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Automation.Name, { game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Automation.Name, {
name: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'), name: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'),
label: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Label'), label: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Label'),

View file

@ -214,9 +214,9 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
} }
: {}; : {};
context.attributes = Object.keys(this.document.system.attributes).reduce((acc, key) => { context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => {
acc[key] = { acc[key] = {
...this.document.system.attributes[key], ...this.document.system.traits[key],
name: game.i18n.localize(SYSTEM.ACTOR.abilities[key].name), name: game.i18n.localize(SYSTEM.ACTOR.abilities[key].name),
verbs: SYSTEM.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x)) verbs: SYSTEM.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x))
}; };
@ -478,7 +478,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
} }
async attributeChange(event) { async attributeChange(event) {
const path = `system.attributes.${event.currentTarget.dataset.attribute}.data.base`; const path = `system.traits.${event.currentTarget.dataset.attribute}.data.base`;
await this.document.update({ [path]: event.currentTarget.value }); await this.document.update({ [path]: event.currentTarget.value });
} }
@ -524,14 +524,14 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
} }
static async toggleAttributeMark(_, button) { static async toggleAttributeMark(_, button) {
const attribute = this.document.system.attributes[button.dataset.attribute]; const attribute = this.document.system.traits[button.dataset.attribute];
const newMark = this.document.system.availableAttributeMarks const newMark = this.document.system.availableAttributeMarks
.filter(x => x > Math.max.apply(null, this.document.system.attributes[button.dataset.attribute].levelMarks)) .filter(x => x > Math.max.apply(null, this.document.system.traits[button.dataset.attribute].levelMarks))
.sort((a, b) => (a > b ? 1 : -1))[0]; .sort((a, b) => (a > b ? 1 : -1))[0];
if (attribute.levelMark || !newMark) return; if (attribute.levelMark || !newMark) return;
const path = `system.attributes.${button.dataset.attribute}.levelMarks`; const path = `system.traits.${button.dataset.attribute}.levelMarks`;
await this.document.update({ [path]: [...attribute.levelMarks, newMark] }); await this.document.update({ [path]: [...attribute.levelMarks, newMark] });
} }
@ -569,7 +569,7 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
type: weapon.system.damage.type, type: weapon.system.damage.type,
bonusDamage: this.document.system.bonuses.damage bonusDamage: this.document.system.bonuses.damage
}; };
const modifier = this.document.system.attributes[weapon.system.trait].data.value; const modifier = this.document.system.traits[weapon.system.trait].data.value;
const { roll, hope, fear, advantage, disadvantage, modifiers, bonusDamageString } = const { roll, hope, fear, advantage, disadvantage, modifiers, bonusDamageString } =
await this.document.dualityRoll( await this.document.dualityRoll(

View file

@ -52,31 +52,31 @@ export const abilities = {
export const featureProperties = { export const featureProperties = {
agility: { agility: {
name: 'DAGGERHEART.Abilities.Agility.Name', name: 'DAGGERHEART.Abilities.Agility.Name',
path: actor => actor.system.attributes.agility.data.value path: actor => actor.system.traits.agility.data.value
}, },
strength: { strength: {
name: 'DAGGERHEART.Abilities.Strength.Name', name: 'DAGGERHEART.Abilities.Strength.Name',
path: actor => actor.system.attributes.strength.data.value path: actor => actor.system.traits.strength.data.value
}, },
finesse: { finesse: {
name: 'DAGGERHEART.Abilities.Finesse.Name', name: 'DAGGERHEART.Abilities.Finesse.Name',
path: actor => actor.system.attributes.finesse.data.value path: actor => actor.system.traits.finesse.data.value
}, },
instinct: { instinct: {
name: 'DAGGERHEART.Abilities.Instinct.Name', name: 'DAGGERHEART.Abilities.Instinct.Name',
path: actor => actor.system.attributes.instinct.data.value path: actor => actor.system.traits.instinct.data.value
}, },
presence: { presence: {
name: 'DAGGERHEART.Abilities.Presence.Name', name: 'DAGGERHEART.Abilities.Presence.Name',
path: actor => actor.system.attributes.presence.data.value path: actor => actor.system.traits.presence.data.value
}, },
knowledge: { knowledge: {
name: 'DAGGERHEART.Abilities.Knowledge.Name', name: 'DAGGERHEART.Abilities.Knowledge.Name',
path: actor => actor.system.attributes.knowledge.data.value path: actor => actor.system.traits.knowledge.data.value
}, },
spellcastingTrait: { spellcastingTrait: {
name: 'DAGGERHEART.FeatureProperty.SpellcastingTrait', name: 'DAGGERHEART.FeatureProperty.SpellcastingTrait',
path: actor => actor.system.attributes[actor.system.subclass.system.spellcastingTrait].data.value path: actor => actor.system.traits[actor.system.subclass.system.spellcastingTrait].data.value
} }
}; };

View file

@ -25,7 +25,8 @@ export const gameSettings = {
AbilityArray: 'AbilityArray', AbilityArray: 'AbilityArray',
RangeMeasurement: 'RangeMeasurement' RangeMeasurement: 'RangeMeasurement'
}, },
DualityRollColor: 'DualityRollColor' DualityRollColor: 'DualityRollColor',
LevelTiers: 'LevelTiers'
}; };
export const DualityRollColor = { export const DualityRollColor = {

371
module/data/levelTier.mjs Normal file
View file

@ -0,0 +1,371 @@
export class DhLevelTiers extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
tiers: new fields.TypedObjectField(new fields.EmbeddedDataField(DhLevelTier))
};
}
}
class DhLevelTier extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
tier: new fields.NumberField({ required: true, integer: true }),
name: new fields.StringField({ required: true }),
levels: new fields.SchemaField({
start: new fields.NumberField({ required: true, integer: true }),
end: new fields.NumberField({ required: true, integer: true })
}),
initialAchievements: new fields.SchemaField({
experience: new fields.SchemaField({
nr: new fields.NumberField({ required: true, initial: 1 }),
modifier: new fields.NumberField({ required: true, initial: 2 })
}),
proficiency: new fields.NumberField({ integer: true, initial: 1 })
}),
availableOptions: new fields.NumberField({ required: true, initial: 2 }),
domainCardByLevel: new fields.NumberField({ initial: 1 }),
options: new fields.TypedObjectField(new fields.EmbeddedDataField(DhLevelOption))
};
}
}
class DhLevelOption extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
label: new fields.StringField({ required: true }),
checkboxQuantity: new fields.NumberField({ required: true, integer: true, initial: 1 }),
minCost: new fields.NumberField({ required: true, integer: true, initial: 1 }),
type: new fields.StringField({ required: true, choices: LevelOptionType }),
choice: new fields.StringField(),
value: new fields.NumberField({ integer: true }),
amount: new fields.NumberField({ integer: true })
};
}
}
// class DhLevelOptionType extends foundry.abstract.DataModel {
// static defineSchema(){
// return new fields.SchemaField({
// trait: new fields.SchemaField({
// id: new fields.StringField({ required: true }),
// label: new fields.StringField({ required: true }),
// }),
// attribute: new fields.SchemaField({
// id: new fields.StringField({ required: true }),
// label: new fields.StringField({ required: true }),
// choice: new fields.StringField({ required: true, choices: attributeChoices })
// }),
// experience: new fields.SchemaField({
// id: new fields.StringField({ required: true }),
// label: new fields.StringField({ required: true }),
// }),
// domainCard: new fields.SchemaField({
// id: new fields.StringField({ required: true }),
// label: new fields.StringField({ required: true }),
// }),
// subclass: new fields.SchemaField({
// id: new fields.StringField({ required: true }),
// label: new fields.StringField({ required: true }),
// }),
// });
// }
// }
const LevelOptionType = {
trait: {
id: 'trait',
label: 'Character Trait'
},
// attribute: {
// id: 'attribute',
// label: 'Attribute',
// choices: attributeChoices,
// },
hitPoint: {
id: 'hitPoint',
label: 'Hit Points'
},
stress: {
id: 'stress',
label: 'Stress'
},
evasion: {
id: 'evasion',
label: 'Evasion'
},
proficiency: {
id: 'proficiency',
label: 'Proficiency'
},
experience: {
id: 'experience',
label: 'Experience'
},
domainCard: {
id: 'domainCard',
label: 'Domain Card'
},
subclass: {
id: 'subclass',
label: 'Subclass'
},
multiclass: {
id: 'multiclass',
label: 'Multiclass'
}
};
// const attributeChoices = {
// hitPoint: {
// id: 'hitPoint',
// label: 'Hit Points',
// },
// stress: {
// id: 'stress',
// label: 'Stress',
// },
// evasion: {
// id: 'evasion',
// label: 'Evasion',
// },
// proficiency: {
// id: 'proficiency',
// label: 'Proficiency',
// },
// };
export const defaultLevelTiers = {
tiers: {
2: {
tier: 2,
name: 'Tier 2',
levels: {
start: 2,
end: 4
},
initialAchievements: {
experience: {
nr: 2,
modifier: 1
},
proficiency: 1
},
availableOptions: 2,
domainCardByLevel: 1,
options: {
trait: {
label: 'DAGGERHEART.LevelUp.Options.trait',
checkboxQuantity: 3,
minCost: 1,
type: LevelOptionType.trait.id,
amount: 2
},
hitPoint: {
label: 'DAGGERHEART.LevelUp.Options.hitPoint',
checkboxQuantity: 2,
minCost: 1,
type: LevelOptionType.hitPoint.id,
value: 1,
value: 1
},
stress: {
label: 'DAGGERHEART.LevelUp.Options.stress',
checkboxQuantity: 2,
minCost: 1,
type: LevelOptionType.stress.id,
value: 1
},
experience: {
label: 'DAGGERHEART.LevelUp.Options.experience',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.experience.id,
value: 1,
amount: 2
},
domainCard: {
label: 'DAGGERHEART.LevelUp.Options.domainCard',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.domainCard.id,
amount: 1
},
evasion: {
label: 'DAGGERHEART.LevelUp.Options.evasion',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.evasion.id,
value: 1
}
}
},
3: {
tier: 3,
name: 'Tier 3',
levels: {
start: 5,
end: 7
},
initialAchievements: {
experience: {
nr: 2,
modifier: 1
},
proficiency: 1
},
availableOptions: 2,
domainCardByLevel: 1,
options: {
trait: {
label: 'DAGGERHEART.LevelUp.Options.trait',
checkboxQuantity: 3,
minCost: 1,
type: LevelOptionType.trait.id,
amount: 2
},
hitPoint: {
label: 'DAGGERHEART.LevelUp.Options.hitPoint',
checkboxQuantity: 2,
minCost: 1,
type: LevelOptionType.hitPoint.id,
value: 1
},
stress: {
label: 'DAGGERHEART.LevelUp.Options.stress',
checkboxQuantity: 2,
minCost: 1,
type: LevelOptionType.stress.id,
value: 1
},
experience: {
label: 'DAGGERHEART.LevelUp.Options.experience',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.experience.id,
value: 1,
amount: 2
},
domainCard: {
label: 'DAGGERHEART.LevelUp.Options.domainCard',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.domainCard.id,
amount: 1
},
evasion: {
label: 'DAGGERHEART.LevelUp.Options.evasion',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.evasion.id,
value: 1
},
subclass: {
label: 'DAGGERHEART.LevelUp.Options.subclass',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.subclass.id
},
proficiency: {
label: 'DAGGERHEART.LevelUp.Options.proficiency',
checkboxQuantity: 2,
minCost: 2,
type: LevelOptionType.proficiency.id,
value: 1
},
multiclass: {
label: 'DAGGERHEART.LevelUp.Options.multiclass',
checkboxQuantity: 2,
minCost: 2,
type: LevelOptionType.multiclass.id
}
}
},
4: {
tier: 4,
name: 'Tier 4',
levels: {
start: 8,
end: 10
},
initialAchievements: {
experience: {
nr: 2,
modifier: 1
},
proficiency: 1
},
availableOptions: 2,
domainCardByLevel: 1,
options: {
trait: {
label: 'DAGGERHEART.LevelUp.Options.trait',
checkboxQuantity: 3,
minCost: 1,
type: LevelOptionType.trait.id,
amount: 2
},
hitPoint: {
label: 'DAGGERHEART.LevelUp.Options.hitPoint',
checkboxQuantity: 2,
minCost: 1,
type: LevelOptionType.hitPoint.id,
value: 1
},
stress: {
label: 'DAGGERHEART.LevelUp.Options.stress',
checkboxQuantity: 2,
minCost: 1,
type: LevelOptionType.stress.id,
value: 1
},
experience: {
label: 'DAGGERHEART.LevelUp.Options.experience',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.experience.id,
value: 1,
amount: 2
},
domainCard: {
label: 'DAGGERHEART.LevelUp.Options.domainCard',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.domainCard.id,
amount: 1
},
evasion: {
label: 'DAGGERHEART.LevelUp.Options.evasion',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.evasion.id,
value: 1
},
subclass: {
label: 'DAGGERHEART.LevelUp.Options.subclass',
checkboxQuantity: 1,
minCost: 1,
type: LevelOptionType.subclass.id
},
proficiency: {
label: 'DAGGERHEART.LevelUp.Options.proficiency',
checkboxQuantity: 2,
minCost: 2,
type: LevelOptionType.proficiency.id,
value: 1
},
multiclass: {
label: 'DAGGERHEART.LevelUp.Options.multiclass',
checkboxQuantity: 2,
minCost: 2,
type: LevelOptionType.multiclass.id
}
}
}
}
};

View file

@ -10,26 +10,8 @@ const attributeField = () =>
bonus: new fields.NumberField({ initial: 0, integer: true }), bonus: new fields.NumberField({ initial: 0, integer: true }),
actualValue: 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 })
});
const levelUpTier = () => ({
attributes: new fields.TypedObjectField(new fields.BooleanField()),
hitPointSlots: new fields.TypedObjectField(new fields.BooleanField()),
stressSlots: new fields.TypedObjectField(new fields.BooleanField()),
experiences: new fields.TypedObjectField(new fields.ArrayField(new fields.StringField({}))),
proficiency: new fields.TypedObjectField(new fields.BooleanField()),
armorOrEvasionSlot: new fields.TypedObjectField(new fields.StringField({})),
subclass: new fields.TypedObjectField(
new fields.SchemaField({
multiclass: new fields.BooleanField(),
feature: new fields.StringField({})
}) })
), });
multiclass: new fields.TypedObjectField(new fields.BooleanField())
});
export default class DhpPC extends foundry.abstract.TypeDataModel { export default class DhpPC extends foundry.abstract.TypeDataModel {
static defineSchema() { static defineSchema() {
@ -61,7 +43,7 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
}) })
) )
}), }),
attributes: new fields.SchemaField({ traits: new fields.SchemaField({
agility: attributeField(), agility: attributeField(),
strength: attributeField(), strength: attributeField(),
finesse: attributeField(), finesse: attributeField(),
@ -78,14 +60,13 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
experiences: new fields.ArrayField( experiences: new fields.ArrayField(
new fields.SchemaField({ new fields.SchemaField({
id: new fields.StringField({ required: true }), id: new fields.StringField({ required: true }),
level: new fields.NumberField({ required: true, integer: 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(), level: 1, description: '', value: 2 }, { id: foundry.utils.randomID(), description: '', value: 2 },
{ id: foundry.utils.randomID(), level: 1, description: '', value: 2 } { id: foundry.utils.randomID(), description: '', value: 2 }
] ]
} }
), ),
@ -100,30 +81,6 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
maxLoadout: new fields.NumberField({ initial: 2, integer: true }), 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 fields.TypedObjectField(
new fields.SchemaField({
level: new fields.NumberField({ required: true, integer: true }),
tier1: new fields.SchemaField({
...levelUpTier()
}),
tier2: new fields.SchemaField(
{
...levelUpTier()
},
{ nullable: true, initial: null }
),
tier3: new fields.SchemaField(
{
...levelUpTier()
},
{ nullable: true, initial: null }
)
})
)
}),
story: new fields.SchemaField({ story: new fields.SchemaField({
background: new fields.HTMLField(), background: new fields.HTMLField(),
appearance: new fields.HTMLField(), appearance: new fields.HTMLField(),
@ -141,6 +98,7 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
max: new fields.NumberField({ initial: 6, integer: true }), max: new fields.NumberField({ initial: 6, integer: true }),
value: new fields.NumberField({ initial: 0, integer: true }) value: new fields.NumberField({ initial: 0, integer: true })
}) })
// levelUpData: new fields.TypeDataModel(DhpLevelUpData),
}; };
} }
@ -292,30 +250,30 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
}; };
} }
get totalAttributeMarks() { // get totalAttributeMarks() {
return Object.keys(this.levelData.levelups).reduce((nr, level) => { // return Object.keys(this.levelData.levelups).reduce((nr, level) => {
const nrAttributeMarks = Object.keys(this.levelData.levelups[level]).reduce((nr, tier) => { // const nrAttributeMarks = Object.keys(this.levelData.levelups[level]).reduce((nr, tier) => {
nr += Object.keys(this.levelData.levelups[level][tier]?.attributes ?? {}).length * 2; // nr += Object.keys(this.levelData.levelups[level][tier]?.attributes ?? {}).length * 2;
return nr; // return nr;
}, 0); // }, 0);
nr.push(...Array(nrAttributeMarks).fill(Number.parseInt(level))); // nr.push(...Array(nrAttributeMarks).fill(Number.parseInt(level)));
return nr; // return nr;
}, []); // }, []);
} // }
get availableAttributeMarks() { // get availableAttributeMarks() {
const attributeMarks = Object.keys(this.attributes).flatMap(y => this.attributes[y].levelMarks); // const attributeMarks = Object.keys(this.attributes).flatMap(y => this.attributes[y].levelMarks);
return this.totalAttributeMarks.reduce((acc, attribute) => { // return this.totalAttributeMarks.reduce((acc, attribute) => {
if (!attributeMarks.findSplice(x => x === attribute)) { // if (!attributeMarks.findSplice(x => x === attribute)) {
acc.push(attribute); // acc.push(attribute);
} // }
return acc; // return acc;
}, []); // }, []);
} // }
get effects() { get effects() {
return this.parent.items.reduce((acc, item) => { return this.parent.items.reduce((acc, item) => {
@ -373,8 +331,8 @@ export default class DhpPC extends foundry.abstract.TypeDataModel {
this.resources.hope.value = Math.max(this.resources.hope.max - 1, 0); this.resources.hope.value = Math.max(this.resources.hope.max - 1, 0);
} }
for (var attributeKey in this.attributes) { for (var attributeKey in this.traits) {
const attribute = this.attributes[attributeKey]; const attribute = this.traits[attributeKey];
attribute.levelMark = attribute.levelMarks.find(x => this.isSameTier(x)) ?? null; attribute.levelMark = attribute.levelMarks.find(x => this.isSameTier(x)) ?? null;

View file

@ -31,9 +31,9 @@ export default class DhpActor extends Actor {
return acc; return acc;
}, {}); }, {});
changed.system.attributes = Object.keys(this.system.attributes).reduce((acc, key) => { changed.system.traits = Object.keys(this.system.traits).reduce((acc, key) => {
acc[key] = { acc[key] = {
levelMarks: this.system.attributes[key].levelMarks.filter( levelMarks: this.system.traits[key].levelMarks.filter(
x => x <= changed.system.levelData.currentLevel x => x <= changed.system.levelData.currentLevel
) )
}; };