Added a simple ViewMode for a character's levelup progression (#997)

This commit is contained in:
WBHarry 2025-08-18 03:59:57 +02:00 committed by GitHub
parent 5cd5de31aa
commit f69e5704e4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 143 additions and 6 deletions

View file

@ -193,7 +193,8 @@
"companionLevelup": { "companionLevelup": {
"confirmTitle": "Companion Levelup", "confirmTitle": "Companion Levelup",
"confirmText": "Would you like to level up your companion {name} by {levelChange} levels at this time? (You can do it manually later)" "confirmText": "Would you like to level up your companion {name} by {levelChange} levels at this time? (You can do it manually later)"
} },
"viewLevelups": "View Levelups"
}, },
"Companion": { "Companion": {
"FIELDS": { "FIELDS": {
@ -493,7 +494,8 @@
"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": "Take an additional domain card of your level or lower from a domain you have access to." "posttext": "Take an additional domain card of your level or lower from a domain you have access to."
}, },
"title": "{actor} Level Up" "title": "{actor} Level Up",
"viewModeTitle": "{actor} Level Up (View Mode)"
}, },
"MulticlassChoice": { "MulticlassChoice": {
"title": "Multiclassing - {actor}", "title": "Multiclassing - {actor}",

View file

@ -1,3 +1,4 @@
export { default as CharacterLevelup } from './characterLevelup.mjs'; export { default as CharacterLevelup } from './characterLevelup.mjs';
export { default as CompanionLevelup } from './companionLevelup.mjs'; export { default as CompanionLevelup } from './companionLevelup.mjs';
export { default as Levelup } from './levelup.mjs'; export { default as Levelup } from './levelup.mjs';
export { default as LevelupViewMode } from './levelupViewMode.mjs';

View file

@ -0,0 +1,95 @@
import { chunkify } from '../../helpers/utils.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
export default class DhlevelUpViewMode extends HandlebarsApplicationMixin(ApplicationV2) {
constructor(actor) {
super({});
this.actor = actor;
}
get title() {
return game.i18n.format('DAGGERHEART.APPLICATIONS.Levelup.viewModeTitle', { actor: this.actor.name });
}
static DEFAULT_OPTIONS = {
classes: ['daggerheart', 'dialog', 'dh-style', 'levelup'],
position: { width: 1000, height: 'auto' },
window: {
resizable: true,
icon: 'fa-solid fa-arrow-turn-up'
}
};
static PARTS = {
main: { template: 'systems/daggerheart/templates/levelup/tabs/viewMode.hbs' }
};
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
const { tiers } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers);
const tierKeys = Object.keys(tiers);
const selections = Object.keys(this.actor.system.levelData.levelups).reduce(
(acc, key) => {
const level = this.actor.system.levelData.levelups[key];
Object.keys(level.selections).forEach(optionKey => {
const choice = level.selections[optionKey];
if (!acc[choice.tier][choice.optionKey]) acc[choice.tier][choice.optionKey] = {};
acc[choice.tier][choice.optionKey][choice.checkboxNr] = choice;
});
return acc;
},
tierKeys.reduce((acc, key) => {
acc[key] = {};
return acc;
}, {})
);
context.tiers = tierKeys.map((tierKey, tierIndex) => {
const tier = tiers[tierKey];
return {
name: tier.name,
active: true,
groups: Object.keys(tier.options).map(optionKey => {
const option = tier.options[optionKey];
const checkboxes = [...Array(option.checkboxSelections).keys()].flatMap(index => {
const checkboxNr = index + 1;
const checkboxData = selections[tierKey]?.[optionKey]?.[checkboxNr];
const checkbox = { ...option, checkboxNr, tier: tierKey, disabled: true };
if (checkboxData) {
checkbox.level = checkboxData.level;
checkbox.selected = true;
}
return checkbox;
});
let label = game.i18n.localize(option.label);
return {
label: label,
checkboxGroups: chunkify(checkboxes, option.minCost, chunkedBoxes => {
const anySelected = chunkedBoxes.some(x => x.selected);
const anyDisabled = chunkedBoxes.some(x => x.disabled);
return {
multi: option.minCost > 1,
checkboxes: chunkedBoxes.map(x => ({
...x,
selected: anySelected,
disabled: anyDisabled
}))
};
})
};
})
};
});
return context;
}
}

View file

@ -1,7 +1,7 @@
import DHBaseActorSheet from '../api/base-actor.mjs'; import DHBaseActorSheet from '../api/base-actor.mjs';
import DhpDeathMove from '../../dialogs/deathMove.mjs'; import DhpDeathMove from '../../dialogs/deathMove.mjs';
import { abilities } from '../../../config/actorConfig.mjs'; import { abilities } from '../../../config/actorConfig.mjs';
import DhCharacterlevelUp from '../../levelup/characterLevelup.mjs'; import { CharacterLevelup, LevelupViewMode } from '../../levelup/_module.mjs';
import DhCharacterCreation from '../../characterCreation/characterCreation.mjs'; import DhCharacterCreation from '../../characterCreation/characterCreation.mjs';
import FilterMenu from '../../ux/filter-menu.mjs'; import FilterMenu from '../../ux/filter-menu.mjs';
import { getDocFromElement, getDocFromElementSync } from '../../../helpers/utils.mjs'; import { getDocFromElement, getDocFromElementSync } from '../../../helpers/utils.mjs';
@ -23,6 +23,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
openPack: CharacterSheet.#openPack, openPack: CharacterSheet.#openPack,
makeDeathMove: CharacterSheet.#makeDeathMove, makeDeathMove: CharacterSheet.#makeDeathMove,
levelManagement: CharacterSheet.#levelManagement, levelManagement: CharacterSheet.#levelManagement,
viewLevelups: CharacterSheet.#viewLevelups,
toggleEquipItem: CharacterSheet.#toggleEquipItem, toggleEquipItem: CharacterSheet.#toggleEquipItem,
toggleResourceDice: CharacterSheet.#toggleResourceDice, toggleResourceDice: CharacterSheet.#toggleResourceDice,
handleResourceDice: CharacterSheet.#handleResourceDice, handleResourceDice: CharacterSheet.#handleResourceDice,
@ -30,7 +31,14 @@ export default class CharacterSheet extends DHBaseActorSheet {
tempBrowser: CharacterSheet.#tempBrowser tempBrowser: CharacterSheet.#tempBrowser
}, },
window: { window: {
resizable: true resizable: true,
controls: [
{
icon: 'fa-solid fa-angles-up',
label: 'DAGGERHEART.ACTORS.Character.viewLevelups',
action: 'viewLevelups'
}
]
}, },
dragDrop: [ dragDrop: [
{ {
@ -585,7 +593,14 @@ export default class CharacterSheet extends DHBaseActorSheet {
if (!value || !subclass) if (!value || !subclass)
return ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.missingClassOrSubclass')); return ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.missingClassOrSubclass'));
new DhCharacterlevelUp(this.document).render({ force: true }); new CharacterLevelup(this.document).render({ force: true });
}
/**
* Opens the charater level management window in viewMode.
*/
static #viewLevelups() {
new LevelupViewMode(this.document).render({ force: true });
} }
/** /**
@ -638,7 +653,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
ability: abilityLabel ability: abilityLabel
}) })
}); });
this.consumeResource(result?.costs); this.consumeResource(result?.costs);
} }

View file

@ -0,0 +1,24 @@
<div class="section-container">
<div class="tiers-container">
{{#each this.tiers as |tier key|}}
<fieldset class="tier-container">
<legend>{{tier.name}}</legend>
{{#each tier.groups}}
<div class="checkbox-group-container">
<div class="checkboxes-container">
{{#each this.checkboxGroups}}
<div class="checkbox-grouping-coontainer {{#if this.multi}}multi{{/if}}">
{{#each this.checkboxes}}
<input type="checkbox" class="selection-checkbox{{#if (gt this.cost 1)}} multi{{/if}}" {{checked this.selected}} disabled />
{{/each}}
</div>
{{/each}}
</div>
<span class="checkbox-group-label">{{this.label}}</span>
</div>
{{/each}}
</fieldset>
{{/each}}
</div>
</div>