175 - Character Sheet Levelup Functionality (#181)

* Attached CharacterCreate and Levelup functionality to the sheet

* Changed to a warning icon
This commit is contained in:
WBHarry 2025-06-25 16:33:38 +02:00 committed by GitHub
parent 7f898bb983
commit d9c003b64b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 218 additions and 61 deletions

View file

@ -5,7 +5,7 @@ import AncestrySelectionDialog from '../ancestrySelectionDialog.mjs';
import DaggerheartSheet from './daggerheart-sheet.mjs';
import { abilities } from '../../config/actorConfig.mjs';
import DhlevelUp from '../levelup.mjs';
import DHDualityRoll from '../../data/chat-message/dualityRoll.mjs';
import DhCharacterCreation from '../characterCreation.mjs';
const { ActorSheetV2 } = foundry.applications.sheets;
const { TextEditor } = foundry.applications.ux;
@ -47,7 +47,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
useAdvancementCard: this.useAdvancementCard,
useAdvancementAbility: this.useAdvancementAbility,
toggleEquipItem: this.toggleEquipItem,
levelup: this.openLevelUp,
levelManagement: this.levelManagement,
editImage: this._onEditImage
},
window: {
@ -217,7 +217,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
_attachPartListeners(partId, htmlElement, options) {
super._attachPartListeners(partId, htmlElement, options);
// htmlElement.querySelector('.level-value').addEventListener('change', this.onLevelChange.bind(this));
htmlElement.querySelector('.level-value')?.addEventListener('change', this.onLevelChange.bind(this));
// To Remove when ContextMenu Handler is made
htmlElement
.querySelectorAll('[data-item-id]')
@ -457,7 +457,19 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
}
}
static openLevelUp() {
static levelManagement() {
if (this.document.system.needsCharacterSetup) {
this.characterSetup();
} else {
this.openLevelUp();
}
}
characterSetup() {
new DhCharacterCreation(this.document).render(true);
}
openLevelUp() {
if (!this.document.system.class.value || !this.document.system.class.subclass) {
ui.notifications.error(game.i18n.localize('DAGGERHEART.Sheets.PC.Errors.missingClassOrSubclass'));
return;

View file

@ -110,6 +110,10 @@ export default class DhCharacter extends BaseDataActor {
return this.parent.items.find(x => x.type === 'community') ?? null;
}
get needsCharacterSetup() {
return !this.class.value || !this.class.subclass;
}
get domains() {
const classDomains = this.class.value ? this.class.value.system.domains : [];
const multiclassDomains = this.multiclass.value ? this.multiclass.value.system.domains : [];

View file

@ -32,10 +32,22 @@ export default class DhpActor extends Actor {
if (this.type !== 'character' || newLevel === this.system.levelData.level.changed) return;
if (newLevel > this.system.levelData.level.current) {
await this.update({ 'system.levelData.level.changed': newLevel });
const maxLevel = Object.values(
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers
).reduce((acc, tier) => Math.max(acc, tier.levels.end), 0);
if (newLevel > maxLevel) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.Sheets.PC.Errors.tooHighLevel'));
}
await this.update({ 'system.levelData.level.changed': Math.min(newLevel, maxLevel) });
} else {
const usedLevel = Math.max(newLevel, 1);
if (newLevel < 1) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.Sheets.PC.Errors.tooLowLevel'));
}
const updatedLevelups = Object.keys(this.system.levelData.levelups).reduce((acc, level) => {
if (Number(level) > newLevel) acc[`-=${level}`] = null;
if (Number(level) > usedLevel) acc[`-=${level}`] = null;
return acc;
}, {});
@ -45,7 +57,7 @@ export default class DhpActor extends Actor {
const subclassFeatureState = { class: null, multiclass: null };
let multiclass = null;
Object.keys(this.system.levelData.levelups)
.filter(x => x > newLevel)
.filter(x => x > usedLevel)
.forEach(levelKey => {
const level = this.system.levelData.levelups[levelKey];
const achievementCards = level.achievements.domainCards.map(x => x.itemUuid);
@ -106,8 +118,8 @@ export default class DhpActor extends Actor {
system: {
levelData: {
level: {
current: newLevel,
changed: newLevel
current: usedLevel,
changed: usedLevel
},
levelups: updatedLevelups
}

View file

@ -189,20 +189,20 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) =>
}
});
const onSelect = async event => {
const inputElement = event.detail.tagify.DOM.originalInput;
const selectedOptions = event.detail?.value ? JSON.parse(event.detail.value) : [];
const unusedDropDownItems = event.detail.tagify.suggestedListItems;
const missingOptions = Object.keys(options).filter(x => !unusedDropDownItems.find(item => item.value === x));
const removedItem = missingOptions.find(x => !selectedOptions.find(item => item.value === x));
const addedItem = removedItem ? null : selectedOptions.find(x => missingOptions.find(item => item === x.value));
const changedItem = { option: removedItem ?? addedItem.value, removed: Boolean(removedItem) };
onChange(selectedOptions, changedItem, inputElement);
};
tagifyElement.on('change', onSelect);
tagifyElement.on('add', event => {
const input = event.detail.tagify.DOM.originalInput;
const currentList = input.value ? JSON.parse(input.value) : [];
onChange([...currentList, event.detail.data], { option: event.detail.data.value, removed: false }, input);
});
tagifyElement.on('remove', event => {
const input = event.detail.tagify.DOM.originalInput;
const currentList = input.value ? JSON.parse(input.value) : [];
onChange(
currentList.filter(x => x.value !== event.detail.data.value),
{ option: event.detail.data.value, removed: true },
event.detail.tagify.DOM.originalInput
);
});
};
export const getDeleteKeys = (property, innerProperty, innerPropertyDefaultValue) => {