mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 19:51:08 +01:00
424 lines
18 KiB
JavaScript
424 lines
18 KiB
JavaScript
import { DhLevelup } from '../data/levelup.mjs';
|
|
|
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
|
|
|
export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
constructor(actor) {
|
|
super({});
|
|
|
|
this.actor = actor;
|
|
this.levelTiers = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers);
|
|
|
|
const playerLevelupData = actor.system.levelData;
|
|
this.levelup = new DhLevelup(DhLevelup.initializeData(this.levelTiers, playerLevelupData));
|
|
}
|
|
|
|
get title() {
|
|
return `${this.actor.name} - Level Up`;
|
|
}
|
|
|
|
static DEFAULT_OPTIONS = {
|
|
classes: ['daggerheart', 'levelup'],
|
|
position: { width: 1200, height: 'auto' },
|
|
window: {
|
|
resizable: true
|
|
},
|
|
actions: {},
|
|
form: {
|
|
handler: this.updateForm,
|
|
submitOnChange: true,
|
|
closeOnSubmit: false
|
|
}
|
|
};
|
|
|
|
static PARTS = {
|
|
form: {
|
|
id: 'levelup',
|
|
template: 'systems/daggerheart/templates/views/levelup.hbs'
|
|
}
|
|
};
|
|
|
|
async _prepareContext(_options) {
|
|
const context = await super._prepareContext(_options);
|
|
context.levelup = this.levelup;
|
|
|
|
return context;
|
|
}
|
|
|
|
static async updateForm(event, _, formData) {
|
|
await this.document.update(formData.object);
|
|
this.render();
|
|
}
|
|
}
|
|
|
|
// import SelectDialog from '../dialogs/selectDialog.mjs';
|
|
// import { getTier } from '../helpers/utils.mjs';
|
|
// import DhpMulticlassDialog from './multiclassDialog.mjs';
|
|
|
|
// const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
|
|
|
// export default class DhpLevelup extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
// constructor(actor) {
|
|
// super({});
|
|
|
|
// this.actor = actor;
|
|
// this.data = foundry.utils.deepClone(actor.system.levelData);
|
|
// this.activeLevel = actor.system.levelData.currentLevel + 1;
|
|
// }
|
|
|
|
// get title() {
|
|
// return `${this.actor.name} - Level Up`;
|
|
// }
|
|
|
|
// static DEFAULT_OPTIONS = {
|
|
// classes: ['daggerheart', 'views', 'levelup'],
|
|
// position: { width: 1200, height: 'auto' },
|
|
// window: {
|
|
// resizable: true
|
|
// },
|
|
|
|
// actions: {
|
|
// toggleBox: this.toggleBox,
|
|
// advanceLevel: this.advanceLevel,
|
|
// finishLevelup: this.finishLevelup
|
|
// }
|
|
// };
|
|
|
|
// static PARTS = {
|
|
// form: {
|
|
// id: 'levelup',
|
|
// template: 'systems/daggerheart/templates/views/levelup.hbs'
|
|
// }
|
|
// };
|
|
|
|
// async _prepareContext(_options) {
|
|
// let selectedChoices = 0,
|
|
// multiclassing = {},
|
|
// subclassing = {};
|
|
// const leveledTiers = Object.keys(this.data.levelups).reduce(
|
|
// (acc, levelKey) => {
|
|
// const levelData = this.data.levelups[levelKey];
|
|
// ['tier1', 'tier2', 'tier3'].forEach(tierKey => {
|
|
// let tierUpdate = {};
|
|
// const tierData = levelData[tierKey];
|
|
// if (tierData) {
|
|
// tierUpdate = Object.keys(tierData).reduce((acc, propertyKey) => {
|
|
// const values = tierData[propertyKey];
|
|
// const level = Number.parseInt(levelKey);
|
|
|
|
// acc[propertyKey] = Object.values(values).map(value => {
|
|
// if (value && level === this.activeLevel) selectedChoices++;
|
|
// if (propertyKey === 'multiclass') multiclassing[levelKey] = true;
|
|
// if (propertyKey === 'subclass') subclassing[tierKey] = true;
|
|
|
|
// return { level: level, value: value };
|
|
// });
|
|
|
|
// return acc;
|
|
// }, {});
|
|
// }
|
|
|
|
// Object.keys(tierUpdate).forEach(propertyKey => {
|
|
// const property = tierUpdate[propertyKey];
|
|
// const propertyValues = foundry.utils.getProperty(acc, `${tierKey}.${propertyKey}`) ?? [];
|
|
// foundry.utils.setProperty(acc, `${tierKey}.${propertyKey}`, [...propertyValues, ...property]);
|
|
// });
|
|
// });
|
|
|
|
// return acc;
|
|
// },
|
|
// { tier1: {}, tier2: {}, tier3: {} }
|
|
// );
|
|
|
|
// const activeTier = getTier(this.activeLevel);
|
|
// const data = Object.keys(SYSTEM.ACTOR.levelupData).reduce((acc, tierKey) => {
|
|
// const tier = SYSTEM.ACTOR.levelupData[tierKey];
|
|
// acc[tierKey] = {
|
|
// label: game.i18n.localize(tier.label),
|
|
// info: game.i18n.localize(tier.info),
|
|
// pretext: game.i18n.localize(tier.pretext),
|
|
// postext: game.i18n.localize(tier.posttext),
|
|
// active: tierKey <= activeTier,
|
|
// choices: Object.keys(tier.choices).reduce((acc, propertyKey) => {
|
|
// const property = tier.choices[propertyKey];
|
|
// acc[propertyKey] = { description: property.description, cost: property.cost ?? 1, values: [] };
|
|
// for (var i = 0; i < property.maxChoices; i++) {
|
|
// const leveledValue = leveledTiers[tierKey][propertyKey]?.[i];
|
|
// const subclassLock =
|
|
// propertyKey === 'subclass' &&
|
|
// Object.keys(multiclassing).find(x => getTier(Number.parseInt(x)) === tierKey);
|
|
// const subclassMulticlassLock = propertyKey === 'multiclass' && subclassing[tierKey];
|
|
// const multiclassLock =
|
|
// propertyKey === 'multiclass' &&
|
|
// Object.keys(multiclassing).length > 0 &&
|
|
// !(
|
|
// leveledValue &&
|
|
// Object.keys(multiclassing).find(x => Number.parseInt(x) === leveledValue.level)
|
|
// );
|
|
// const locked =
|
|
// (leveledValue && leveledValue.level !== this.activeLevel) ||
|
|
// subclassLock ||
|
|
// subclassMulticlassLock ||
|
|
// multiclassLock;
|
|
// const disabled =
|
|
// tierKey > activeTier ||
|
|
// (selectedChoices === 2 && !(leveledValue && leveledValue.level === this.activeLevel)) ||
|
|
// locked;
|
|
|
|
// acc[propertyKey].values.push({
|
|
// selected: leveledValue?.value !== undefined,
|
|
// path: `levelups.${this.activeLevel}.${tierKey}.${propertyKey}.${i}`,
|
|
// description: game.i18n.localize(property.description),
|
|
// disabled: disabled,
|
|
// locked: locked
|
|
// });
|
|
// }
|
|
|
|
// return acc;
|
|
// }, {})
|
|
// };
|
|
|
|
// return acc;
|
|
// }, {});
|
|
|
|
// return {
|
|
// data: data,
|
|
// activeLevel: this.activeLevel,
|
|
// changedLevel: this.actor.system.levelData.changedLevel,
|
|
// completedSelection: selectedChoices === 2
|
|
// };
|
|
// }
|
|
|
|
// static async toggleBox(_, button) {
|
|
// const path = button.dataset.path;
|
|
// if (foundry.utils.getProperty(this.data, path)) {
|
|
// const pathParts = path.split('.');
|
|
// const arrayPart = pathParts.slice(0, pathParts.length - 1).join('.');
|
|
// let array = foundry.utils.getProperty(this.data, arrayPart);
|
|
// if (button.dataset.levelAttribute === 'multiclass') {
|
|
// array = [];
|
|
// } else {
|
|
// delete array[Number.parseInt(pathParts[pathParts.length - 1])];
|
|
// }
|
|
// foundry.utils.setProperty(this.data, arrayPart, array);
|
|
// } else {
|
|
// const updates = [{ path: path, value: { level: this.activeLevel } }];
|
|
// const levelChoices = SYSTEM.ACTOR.levelChoices[button.dataset.levelAttribute];
|
|
// if (button.dataset.levelAttribute === 'subclass') {
|
|
// if (!this.actor.system.multiclassSubclass) {
|
|
// updates[0].value.value = {
|
|
// multiclass: false,
|
|
// feature: this.actor.system.subclass.system.specializationFeature.unlocked
|
|
// ? 'mastery'
|
|
// : 'specialization'
|
|
// };
|
|
// } else {
|
|
// const choices = [
|
|
// { name: this.actor.system.subclass.name, value: this.actor.system.subclass.uuid },
|
|
// {
|
|
// name: this.actor.system.multiclassSubclass.name,
|
|
// value: this.actor.system.multiclassSubclass.uuid
|
|
// }
|
|
// ];
|
|
// const indexes = await SelectDialog.selectItem({
|
|
// actor: this.actor,
|
|
// choices: choices,
|
|
// title: levelChoices.title,
|
|
// nrChoices: 1
|
|
// });
|
|
// if (indexes.length === 0) {
|
|
// this.render();
|
|
// return;
|
|
// }
|
|
// const multiclassSubclass = choices[indexes[0]].name === this.actor.system.multiclassSubclass.name;
|
|
// updates[0].value.value = {
|
|
// multiclass: multiclassSubclass,
|
|
// feature: this.actor.system.multiclassSubclass.system.specializationFeature.unlocked
|
|
// ? 'mastery'
|
|
// : 'specialization'
|
|
// };
|
|
// }
|
|
// } else if (button.dataset.levelAttribute === 'multiclass') {
|
|
// const multiclassAwait = new Promise(resolve => {
|
|
// new DhpMulticlassDialog(this.actor.name, this.actor.system.class, resolve).render(true);
|
|
// });
|
|
// const multiclassData = await multiclassAwait;
|
|
// if (!multiclassData) {
|
|
// this.render();
|
|
// return;
|
|
// }
|
|
|
|
// const pathParts = path.split('.');
|
|
// const arrayPart = pathParts.slice(0, pathParts.length - 1).join('.');
|
|
// updates[0] = {
|
|
// path: [arrayPart, '0'].join('.'),
|
|
// value: {
|
|
// level: this.activeLevel,
|
|
// value: {
|
|
// class: multiclassData.class,
|
|
// subclass: multiclassData.subclass,
|
|
// domain: multiclassData.domain,
|
|
// level: this.activeLevel
|
|
// }
|
|
// }
|
|
// };
|
|
// updates[1] = {
|
|
// path: [arrayPart, '1'].join('.'),
|
|
// value: {
|
|
// level: this.activeLevel,
|
|
// value: {
|
|
// class: multiclassData.class,
|
|
// subclass: multiclassData.subclass,
|
|
// domain: multiclassData.domain,
|
|
// level: this.activeLevel
|
|
// }
|
|
// }
|
|
// };
|
|
// } else {
|
|
// if (levelChoices.choices.length > 0) {
|
|
// if (typeof levelChoices.choices === 'string') {
|
|
// const choices = foundry.utils
|
|
// .getProperty(this.actor, levelChoices.choices)
|
|
// .map(x => ({ name: x.description, value: x.id }));
|
|
// const indexes = await SelectDialog.selectItem({
|
|
// actor: this.actor,
|
|
// choices: choices,
|
|
// title: levelChoices.title,
|
|
// nrChoices: levelChoices.nrChoices
|
|
// });
|
|
// if (indexes.length === 0) {
|
|
// this.render();
|
|
// return;
|
|
// }
|
|
// updates[0].value.value = choices
|
|
// .filter((_, index) => indexes.includes(index))
|
|
// .map(x => x.value);
|
|
// } else {
|
|
// const indexes = await SelectDialog.selectItem({
|
|
// actor: this.actor,
|
|
// choices: levelChoices.choices,
|
|
// title: levelChoices.title,
|
|
// nrChoices: levelChoices.nrChoices
|
|
// });
|
|
// if (indexes.length === 0) {
|
|
// this.render();
|
|
// return;
|
|
// }
|
|
// updates[0].value.value = levelChoices.choices[indexes[0]].path;
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// const update = updates.reduce((acc, x) => {
|
|
// acc[x.path] = x.value;
|
|
|
|
// return acc;
|
|
// }, {});
|
|
|
|
// this.data = foundry.utils.mergeObject(this.data, update);
|
|
// }
|
|
|
|
// this.render();
|
|
// }
|
|
|
|
// static advanceLevel() {
|
|
// this.activeLevel += 1;
|
|
// this.render();
|
|
// }
|
|
|
|
// static async finishLevelup() {
|
|
// this.data.currentLevel = this.data.changedLevel;
|
|
// let multiclass = null;
|
|
// for (var level in this.data.levelups) {
|
|
// for (var tier in this.data.levelups[level]) {
|
|
// for (var category in this.data.levelups[level][tier]) {
|
|
// for (var value in this.data.levelups[level][tier][category]) {
|
|
// if (category === 'multiclass') {
|
|
// multiclass = this.data.levelups[level][tier][category][value].value;
|
|
// this.data.levelups[level][tier][category][value] = true;
|
|
// } else {
|
|
// this.data.levelups[level][tier][category][value] =
|
|
// this.data.levelups[level][tier][category][value].value ?? true;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// const tiersMoved =
|
|
// getTier(this.actor.system.levelData.changedLevel, true) -
|
|
// getTier(this.actor.system.levelData.currentLevel, true);
|
|
// const experiences = Array.from(Array(tiersMoved), (_, index) => ({
|
|
// id: foundry.utils.randomID(),
|
|
// level: this.actor.system.experiences.length + index * 3,
|
|
// description: '',
|
|
// value: 1
|
|
// }));
|
|
|
|
// await this.actor.update(
|
|
// {
|
|
// system: {
|
|
// levelData: this.data,
|
|
// experiences: [...this.actor.system.experiences, ...experiences]
|
|
// }
|
|
// },
|
|
// { diff: false }
|
|
// );
|
|
|
|
// if (!this.actor.multiclass && multiclass) {
|
|
// const multiclassClass = (await fromUuid(multiclass.class.uuid)).toObject();
|
|
// multiclassClass.system.domains = [multiclass.domain.id];
|
|
// multiclassClass.system.multiclass = multiclass.level;
|
|
|
|
// const multiclassFeatures = [];
|
|
// for (var i = 0; i < multiclassClass.system.features.length; i++) {
|
|
// const feature = (await fromUuid(multiclassClass.system.features[i].uuid)).toObject();
|
|
// feature.system.multiclass = multiclass.level;
|
|
// multiclassFeatures.push(feature);
|
|
// }
|
|
|
|
// const multiclassSubclass = (await fromUuid(multiclass.subclass.uuid)).toObject();
|
|
// multiclassSubclass.system.multiclass = multiclass.level;
|
|
|
|
// const multiclassSubclassFeatures = {};
|
|
// const features = [
|
|
// multiclassSubclass.system.foundationFeature,
|
|
// multiclassSubclass.system.specializationFeature,
|
|
// multiclassSubclass.system.masteryFeature
|
|
// ];
|
|
// for (var i = 0; i < features.length; i++) {
|
|
// const path = i === 0 ? 'foundationFeature' : i === 1 ? 'specializationFeature' : 'masteryFeature';
|
|
// const feature = features[i];
|
|
// for (var ability of feature.abilities) {
|
|
// const data = (await fromUuid(ability.uuid)).toObject();
|
|
// if (i > 0) data.system.disabled = true;
|
|
// data.system.multiclass = multiclass.level;
|
|
// if (!multiclassSubclassFeatures[path]) multiclassSubclassFeatures[path] = [data];
|
|
// else multiclassSubclassFeatures[path].push(data);
|
|
// // data.uuid = feature.uuid;
|
|
|
|
// // const abilityData = await this._onDropItemCreate(data);
|
|
// // ability.uuid = abilityData[0].uuid;
|
|
|
|
// // createdItems.push(abilityData);
|
|
// }
|
|
// }
|
|
|
|
// for (let subclassFeaturesKey in multiclassSubclassFeatures) {
|
|
// const values = multiclassSubclassFeatures[subclassFeaturesKey];
|
|
// const abilityResults = await this.actor.createEmbeddedDocuments('Item', values);
|
|
// for (var i = 0; i < abilityResults.length; i++) {
|
|
// multiclassSubclass.system[subclassFeaturesKey].abilities[i].uuid = abilityResults[i].uuid;
|
|
// }
|
|
// }
|
|
|
|
// await this.actor.createEmbeddedDocuments('Item', [
|
|
// multiclassClass,
|
|
// ...multiclassFeatures,
|
|
// multiclassSubclass
|
|
// ]);
|
|
// }
|
|
|
|
// this.close();
|
|
// }
|
|
// }
|