Character BuilderTabs rework

This commit is contained in:
Clément Pons 2025-08-26 10:18:07 +02:00
parent 6fe3746df4
commit 5387dc66c3
1 changed files with 78 additions and 113 deletions

View File

@ -192,14 +192,6 @@ export const CharacterValidation = z.object({
thumbnail: z.any(), thumbnail: z.any(),
}); });
const stepTexts: Record<number, string> = {
0: 'Choisissez un peuple afin de définir la progression de votre personnage au fil des niveaux.',
1: 'Déterminez la progression de votre personnage en choisissant une option par niveau disponible.',
2: 'Spécialisez votre personnage en attribuant vos points d\'entrainement parmi les 7 branches disponibles.\nChaque paliers de 3 points augmentent votre modifieur.',
3: 'Diversifiez vos possibilités en affectant vos points dans les différentes compétences disponibles.',
4: 'Déterminez l\'Aspect qui vous corresponds et benéficiez de puissants bonus.'
};
type Property = { value: number | string | false, id: string, operation: "set" | "add" }; type Property = { value: number | string | false, id: string, operation: "set" | "add" };
type PropertySum = { list: Array<Property>, value: number, _dirty: boolean }; type PropertySum = { list: Array<Property>, value: number, _dirty: boolean };
export class CharacterCompiler export class CharacterCompiler
@ -400,7 +392,7 @@ export class CharacterBuilder extends CharacterCompiler
private _container: HTMLDivElement; private _container: HTMLDivElement;
private _content?: HTMLDivElement; private _content?: HTMLDivElement;
private _stepsHeader: HTMLDivElement[] = []; private _stepsHeader: HTMLDivElement[] = [];
private _stepsContent: Array<BuilderTab | (() => BuilderTab)> = []; private _steps: Array<BuilderTabConstructor> = [];
private _helperText!: Text; private _helperText!: Text;
private id?: string; private id?: string;
@ -437,34 +429,18 @@ export class CharacterBuilder extends CharacterCompiler
} }
private render() private render()
{ {
this._stepsHeader = [ this._steps = [
dom("div", { class: "group flex items-center", }, [ PeoplePicker,
dom("div", { class: "px-2 py-1 border-b border-transparent hover:border-accent-blue disabled:text-light-50 dark:disabled:text-dark-50 disabled:hover:border-transparent group-data-[state=active]:text-accent-blue cursor-pointer", listeners: { click: e => this.display(0) } }, [text("Peuples")]), LevelPicker,
]), TrainingPicker,
dom("div", { class: "group flex items-center", }, [ AbilityPicker,
icon("radix-icons:chevron-right", { class: "w-6 h-6 flex justify-center items-center group-data-[disabled]:text-light-50 dark:group-data-[disabled]:text-dark-50 group-data-[disabled]:hover:border-transparent me-4" }), AspectPicker,
dom("div", { class: "px-2 py-1 border-b border-transparent hover:border-accent-blue disabled:text-light-50 dark:disabled:text-dark-50 disabled:hover:border-transparent group-data-[state=active]:text-accent-blue cursor-pointer", listeners: { click: e => this.display(1) } }, [text("Niveaux")]),
]),
dom("div", { class: "group flex items-center", }, [
icon("radix-icons:chevron-right", { class: "w-6 h-6 flex justify-center items-center group-data-[disabled]:text-light-50 dark:group-data-[disabled]:text-dark-50 group-data-[disabled]:hover:border-transparent me-4" }),
dom("div", { class: "px-2 py-1 border-b border-transparent hover:border-accent-blue disabled:text-light-50 dark:disabled:text-dark-50 disabled:hover:border-transparent group-data-[state=active]:text-accent-blue cursor-pointer", listeners: { click: e => this.display(2) } }, [text("Entrainement")]),
]),
dom("div", { class: "group flex items-center", }, [
icon("radix-icons:chevron-right", { class: "w-6 h-6 flex justify-center items-center group-data-[disabled]:text-light-50 dark:group-data-[disabled]:text-dark-50 group-data-[disabled]:hover:border-transparent me-4" }),
dom("div", { class: "px-2 py-1 border-b border-transparent hover:border-accent-blue disabled:text-light-50 dark:disabled:text-dark-50 disabled:hover:border-transparent group-data-[state=active]:text-accent-blue cursor-pointer", listeners: { click: e => this.display(3) } }, [text("Compétences")]),
]),
dom("div", { class: "group flex items-center", }, [
icon("radix-icons:chevron-right", { class: "w-6 h-6 flex justify-center items-center group-data-[disabled]:text-light-50 dark:group-data-[disabled]:text-dark-50 group-data-[disabled]:hover:border-transparent me-4" }),
dom("div", { class: "px-2 py-1 border-b border-transparent hover:border-accent-blue disabled:text-light-50 dark:disabled:text-dark-50 disabled:hover:border-transparent group-data-[state=active]:text-accent-blue cursor-pointer", listeners: { click: e => this.display(4) } }, [text("Aspect")])
]),
];
this._stepsContent = [
new PeoplePicker(this),
() => new LevelPicker(this),
() => new TrainingPicker(this),
() => new AbilityPicker(this),
() => new AspectPicker(this),
]; ];
this._stepsHeader = this._steps.map((e, i) =>
dom("div", { class: "group flex items-center", }, [
dom("div", { class: "px-2 py-1 border-b border-transparent hover:border-accent-blue disabled:text-light-50 dark:disabled:text-dark-50 disabled:hover:border-transparent group-data-[state=active]:text-accent-blue cursor-pointer", listeners: { click: () => this.display(i) } }, [text(e.name)]),
])
);
this._helperText = text("Choisissez un peuple afin de définir la progression de votre personnage au fil des niveaux.") this._helperText = text("Choisissez un peuple afin de définir la progression de votre personnage au fil des niveaux.")
this._content = dom('div', { class: 'flex-1 outline-none max-w-full w-full overflow-y-auto', attributes: { id: 'characterEditorContainer' } }); this._content = dom('div', { class: 'flex-1 outline-none max-w-full w-full overflow-y-auto', attributes: { id: 'characterEditorContainer' } });
this._container.appendChild(div('flex flex-1 flex-col justify-start items-center px-8 w-full h-full overflow-y-hidden', [ this._container.appendChild(div('flex flex-1 flex-col justify-start items-center px-8 w-full h-full overflow-y-hidden', [
@ -485,18 +461,15 @@ export class CharacterBuilder extends CharacterCompiler
if(step < 0 || step >= this._stepsHeader.length) if(step < 0 || step >= this._stepsHeader.length)
return; return;
if(step !== 0 && this._stepsContent.slice(0, step).some(e => !(e as BuilderTab).validate())) if(step !== 0 && this._steps.slice(0, step).some(e => !e.validate(this)))
return; return;
this._stepsContent.forEach((e, i, arr) => arr[i] = i <= step ? typeof e === 'function' ? e() : e : e);
this._stepsHeader.forEach(e => e.setAttribute('data-state', 'inactive')); this._stepsHeader.forEach(e => e.setAttribute('data-state', 'inactive'));
this._stepsHeader[step]!.setAttribute('data-state', 'active'); this._stepsHeader[step]!.setAttribute('data-state', 'active');
(this._stepsContent[step]! as BuilderTab).update(); this._content?.replaceChildren(...(new this._steps[step]!(this)).dom);
this._content?.replaceChildren(...(this._stepsContent[step] as BuilderTab)!.dom);
this._helperText.textContent = stepTexts[step]!; this._helperText.textContent = this._steps[step]!.description;
} }
async save(leave: boolean = true) async save(leave: boolean = true)
{ {
@ -696,25 +669,37 @@ export class PickableFeature
return this._content; return this._content;
} }
} }
interface BuilderTab { abstract class BuilderTab {
dom: Array<Node | string>; protected _builder: CharacterBuilder;
update: () => void; protected _content!: Array<Node | string>;
validate: () => boolean; static name: string;
}; static description: string;
class PeoplePicker implements BuilderTab
{
private _builder: CharacterBuilder;
private _content: Array<Node | string>;
constructor(builder: CharacterBuilder) { this._builder = builder; }
update() { }
static validate(builder: CharacterBuilder): boolean { return false; }
get dom() { return this._content; }
};
type BuilderTabConstructor = {
new (builder: CharacterBuilder): BuilderTab;
name: string;
description: string;
validate(builder: CharacterBuilder): boolean;
}
class PeoplePicker extends BuilderTab
{
private _nameInput: HTMLInputElement; private _nameInput: HTMLInputElement;
private _visibilityInput: HTMLDivElement; private _visibilityInput: HTMLDivElement;
private _options: HTMLDivElement[]; private _options: HTMLDivElement[];
private _activeOption?: HTMLDivElement; private _activeOption?: HTMLDivElement;
static override name = 'Peuple';
static override description = 'Choisissez un peuple afin de définir la progression de votre personnage au fil des niveaux.';
constructor(builder: CharacterBuilder) constructor(builder: CharacterBuilder)
{ {
this._builder = builder; super(builder);
this._nameInput = input('text', { this._nameInput = input('text', {
input: (value) => { input: (value) => {
@ -746,7 +731,7 @@ class PeoplePicker implements BuilderTab
button(text('Suivant'), () => this._builder.display(1), 'h-[35px] px-[15px]'), button(text('Suivant'), () => this._builder.display(1), 'h-[35px] px-[15px]'),
]), div('flex flex-1 gap-4 p-2 overflow-x-auto justify-center', this._options)]; ]), div('flex flex-1 gap-4 p-2 overflow-x-auto justify-center', this._options)];
} }
update() override update()
{ {
this._nameInput.value = this._builder.character.name; this._nameInput.value = this._builder.character.name;
this._visibilityInput.setAttribute('data-state', this._builder.character.visibility === "private" ? "checked" : "unchecked"); this._visibilityInput.setAttribute('data-state', this._builder.character.visibility === "private" ? "checked" : "unchecked");
@ -758,29 +743,25 @@ class PeoplePicker implements BuilderTab
"border-accent-blue outline-2 outline outline-accent-blue".split(" ").forEach(e => this._activeOption?.classList.toggle(e, true)); "border-accent-blue outline-2 outline outline-accent-blue".split(" ").forEach(e => this._activeOption?.classList.toggle(e, true));
} }
} }
validate(): boolean static override validate(builder: CharacterBuilder): boolean
{ {
return this._builder.character.people !== undefined; return builder.character.people !== undefined;
}
get dom()
{
return this._content;
} }
} }
class LevelPicker implements BuilderTab class LevelPicker extends BuilderTab
{ {
private _builder: CharacterBuilder;
private _content: Array<Node | string>;
private _levelInput: HTMLInputElement; private _levelInput: HTMLInputElement;
private _pointsInput: HTMLInputElement; private _pointsInput: HTMLInputElement;
private _healthText: Text; private _healthText: Text;
private _manaText: Text; private _manaText: Text;
private _options: HTMLDivElement[][]; private _options: HTMLDivElement[][];
static override name = 'Niveaux';
static override description = 'Déterminez la progression de votre personnage en choisissant une option par niveau disponible.';
constructor(builder: CharacterBuilder) constructor(builder: CharacterBuilder)
{ {
this._builder = builder; super(builder);
this._levelInput = numberpicker({ defaultValue: this._builder.character.level, min: 1, max: 20, input: (value) => { this._levelInput = numberpicker({ defaultValue: this._builder.character.level, min: 1, max: 20, input: (value) => {
this._builder.character.level = value; this._builder.character.level = value;
@ -814,7 +795,7 @@ class LevelPicker implements BuilderTab
button(text('Suivant'), () => this._builder.display(2), 'h-[35px] px-[15px]'), button(text('Suivant'), () => this._builder.display(2), 'h-[35px] px-[15px]'),
]), div('flex flex-col flex-1 gap-4 mx-8 my-4', this._options.flatMap(e => [...e]))]; ]), div('flex flex-col flex-1 gap-4 mx-8 my-4', this._options.flatMap(e => [...e]))];
} }
update() override update()
{ {
const values = this._builder.values; const values = this._builder.values;
@ -839,20 +820,13 @@ class LevelPicker implements BuilderTab
}); });
}); */ }); */
} }
validate(): boolean static override validate(builder: CharacterBuilder): boolean
{ {
return this._builder.character.level - Object.keys(this._builder.character.leveling).length >= 0; return builder.character.level - Object.keys(builder.character.leveling).length >= 0;
}
get dom()
{
return this._content;
} }
} }
class TrainingPicker implements BuilderTab class TrainingPicker extends BuilderTab
{ {
private _builder: CharacterBuilder;
private _content: Array<Node | string>;
private _pointsInput: HTMLInputElement; private _pointsInput: HTMLInputElement;
private _healthText: Text; private _healthText: Text;
private _manaText: Text; private _manaText: Text;
@ -862,15 +836,18 @@ class TrainingPicker implements BuilderTab
private _statIndicator: HTMLSpanElement; private _statIndicator: HTMLSpanElement;
private _statContainer: HTMLDivElement; private _statContainer: HTMLDivElement;
static override name = 'Entrainement';
static override description = 'Spécialisez votre personnage en attribuant vos points d\'entrainement parmi les 7 branches disponibles.\nChaque paliers de 3 points augmentent votre modifieur.';
constructor(builder: CharacterBuilder) constructor(builder: CharacterBuilder)
{ {
super(builder);
const statRenderBlock = (stat: MainStat) => { const statRenderBlock = (stat: MainStat) => {
return Object.entries(config.training[stat]).map( return Object.entries(config.training[stat]).map(
(level) => [ div("w-full flex h-px", [div("border-t border-dashed border-light-50 dark:border-dark-50 w-full"), dom('span', { class: "relative" }, [ text(level[0]) ])]), (level) => [ div("w-full flex h-px", [div("border-t border-dashed border-light-50 dark:border-dark-50 w-full"), dom('span', { class: "relative" }, [ text(level[0]) ])]),
div("flex flex-row gap-4 justify-center", level[1].map((option, j) => new PickableFeature(option, { state: level[0] == '0' || this._builder.character.training[stat as MainStat][level[0] as any as TrainingLevel] === j, choices: this._builder.character.choices }).dom)) div("flex flex-row gap-4 justify-center", level[1].map((option, j) => new PickableFeature(option, { state: level[0] == '0' || this._builder.character.training[stat as MainStat][level[0] as any as TrainingLevel] === j, choices: this._builder.character.choices }).dom))
]) ])
} }
this._builder = builder;
this._pointsInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }}); this._pointsInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }});
this._healthText = text("0"), this._manaText = text("0"); this._healthText = text("0"), this._manaText = text("0");
@ -912,7 +889,7 @@ class TrainingPicker implements BuilderTab
this._statContainer.style.left = `-${tab * 100}%`; this._statContainer.style.left = `-${tab * 100}%`;
} }
update() override update()
{ {
const values = this._builder.values; const values = this._builder.values;
const training = Object.values(this._builder.character.training).reduce((p, v) => p + Object.values(v).filter(e => e !== undefined).length, 0); const training = Object.values(this._builder.character.training).reduce((p, v) => p + Object.values(v).filter(e => e !== undefined).length, 0);
@ -921,31 +898,28 @@ class TrainingPicker implements BuilderTab
this._healthText.textContent = values.health?.toString() ?? '0'; this._healthText.textContent = values.health?.toString() ?? '0';
this._manaText.textContent = values.mana?.toString() ?? '0'; this._manaText.textContent = values.mana?.toString() ?? '0';
} }
validate(): boolean static override validate(builder: CharacterBuilder): boolean
{ {
const values = this._builder.values; const values = builder.values;
const training = Object.values(this._builder.character.training).reduce((p, v) => p + Object.values(v).filter(e => e !== undefined).length, 0); const training = Object.values(builder.character.training).reduce((p, v) => p + Object.values(v).filter(e => e !== undefined).length, 0);
return (values.training ?? 0) - training >= 0; return (values.training ?? 0) - training >= 0;
} }
get dom()
{
return this._content;
} }
} class AbilityPicker extends BuilderTab
class AbilityPicker implements BuilderTab
{ {
private _builder: CharacterBuilder;
private _content: Array<Node | string>;
private _pointsInput: HTMLInputElement; private _pointsInput: HTMLInputElement;
private _options: HTMLDivElement[]; private _options: HTMLDivElement[];
private _tooltips: Text[] = []; private _tooltips: Text[] = [];
private _maxs: HTMLElement[] = []; private _maxs: HTMLElement[] = [];
static override name = 'Compétences';
static override description = 'Diversifiez vos possibilités en affectant vos points dans les différentes compétences disponibles.';
constructor(builder: CharacterBuilder) constructor(builder: CharacterBuilder)
{ {
super(builder);
const numberInput = (value?: number, update?: (value: number) => number | undefined) => { const numberInput = (value?: number, update?: (value: number) => number | undefined) => {
const input = dom("input", { class: `w-14 mx-4 caret-light-50 dark:caret-dark-50 text-light-100 dark:text-dark-100 placeholder:text-light-50 dark:placeholder:text-dark-50 bg-light-20 dark:bg-dark-20 appearance-none outline-none px-3 py-1 focus:shadow-raw transition-[box-shadow] focus:shadow-light-40 dark:focus:shadow-dark-40 border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50 data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20`, listeners: { const input = dom("input", { class: `w-14 mx-4 caret-light-50 dark:caret-dark-50 text-light-100 dark:text-dark-100 placeholder:text-light-50 dark:placeholder:text-dark-50 bg-light-20 dark:bg-dark-20 appearance-none outline-none px-3 py-1 focus:shadow-raw transition-[box-shadow] focus:shadow-light-40 dark:focus:shadow-dark-40 border border-light-35 dark:border-dark-35 hover:border-light-50 dark:hover:border-dark-50 data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20`, listeners: {
input: (e: Event) => { input: (e: Event) => {
@ -980,7 +954,6 @@ class AbilityPicker implements BuilderTab
arr.push(value); arr.push(value);
return value; return value;
} }
this._builder = builder;
this._pointsInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }}); this._pointsInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }});
@ -1017,7 +990,7 @@ class AbilityPicker implements BuilderTab
button(text('Suivant'), () => this._builder.display(4), 'h-[35px] px-[15px]'), button(text('Suivant'), () => this._builder.display(4), 'h-[35px] px-[15px]'),
]), div('flex flex-row flex-wrap justify-center items-center flex-1 gap-12 mx-8 my-4 px-48', this._options)]; ]), div('flex flex-row flex-wrap justify-center items-center flex-1 gap-12 mx-8 my-4 px-48', this._options)];
} }
update() override update()
{ {
const values = this._builder.values; const values = this._builder.values;
const abilities = Object.values(this._builder.character.abilities).reduce((p, v) => p + v, 0); const abilities = Object.values(this._builder.character.abilities).reduce((p, v) => p + v, 0);
@ -1034,23 +1007,16 @@ class AbilityPicker implements BuilderTab
return this._builder.character.abilities[e]; return this._builder.character.abilities[e];
}) })
} }
validate(): boolean static override validate(builder: CharacterBuilder): boolean
{ {
const values = this._builder.values; const values = builder.values;
const abilities = Object.values(this._builder.character.abilities).reduce((p, v) => p + v, 0); const abilities = Object.values(builder.character.abilities).reduce((p, v) => p + v, 0);
return (values.ability ?? 0) - abilities >= 0; return (values.ability ?? 0) - abilities >= 0;
} }
get dom()
{
return this._content;
} }
} class AspectPicker extends BuilderTab
class AspectPicker implements BuilderTab
{ {
private _builder: CharacterBuilder;
private _content: Array<Node | string>;
private _physicInput: HTMLInputElement; private _physicInput: HTMLInputElement;
private _mentalInput: HTMLInputElement; private _mentalInput: HTMLInputElement;
private _personalityInput: HTMLInputElement; private _personalityInput: HTMLInputElement;
@ -1059,9 +1025,12 @@ class AspectPicker implements BuilderTab
private _options: HTMLDivElement[]; private _options: HTMLDivElement[];
static override name = 'Aspect';
static override description = 'Déterminez l\'Aspect qui vous corresponds et benéficiez de puissants bonus.';
constructor(builder: CharacterBuilder) constructor(builder: CharacterBuilder)
{ {
this._builder = builder; super(builder);
this._physicInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }}); this._physicInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }});
this._mentalInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }}); this._mentalInput = dom("input", { class: `w-14 mx-4 text-light-70 dark:text-dark-70 tabular-nums bg-light-10 dark:bg-dark-10 appearance-none outline-none ps-3 pe-1 py-1 focus:shadow-raw transition-[box-shadow] border bg-light-20 bg-dark-20 border-light-20 dark:border-dark-20`, attributes: { type: "number", disabled: true }});
@ -1119,7 +1088,7 @@ class AspectPicker implements BuilderTab
button(text('Enregistrer'), () => this._builder.save(), 'h-[35px] px-[15px]'), button(text('Enregistrer'), () => this._builder.save(), 'h-[35px] px-[15px]'),
]), div('flex flex-row flex-wrap justify-center items-center flex-1 gap-8 mx-8 my-4 px-8', this._options)]; ]), div('flex flex-row flex-wrap justify-center items-center flex-1 gap-8 mx-8 my-4 px-8', this._options)];
} }
update() override update()
{ {
const physic = Object.values(this._builder.character.training['strength']).length + Object.values(this._builder.character.training['dexterity']).length + Object.values(this._builder.character.training['constitution']).length; const physic = Object.values(this._builder.character.training['strength']).length + Object.values(this._builder.character.training['dexterity']).length + Object.values(this._builder.character.training['constitution']).length;
const mental = Object.values(this._builder.character.training['intelligence']).length + Object.values(this._builder.character.training['curiosity']).length; const mental = Object.values(this._builder.character.training['intelligence']).length + Object.values(this._builder.character.training['curiosity']).length;
@ -1148,16 +1117,16 @@ class AspectPicker implements BuilderTab
return true; return true;
})); }));
} }
validate(): boolean static override validate(builder: CharacterBuilder): boolean
{ {
const physic = Object.values(this._builder.character.training['strength']).length + Object.values(this._builder.character.training['dexterity']).length + Object.values(this._builder.character.training['constitution']).length; const physic = Object.values(builder.character.training['strength']).length + Object.values(builder.character.training['dexterity']).length + Object.values(builder.character.training['constitution']).length;
const mental = Object.values(this._builder.character.training['intelligence']).length + Object.values(this._builder.character.training['curiosity']).length; const mental = Object.values(builder.character.training['intelligence']).length + Object.values(builder.character.training['curiosity']).length;
const personality = Object.values(this._builder.character.training['charisma']).length + Object.values(this._builder.character.training['psyche']).length; const personality = Object.values(builder.character.training['charisma']).length + Object.values(builder.character.training['psyche']).length;
if(this._builder.character.aspect === undefined) if(builder.character.aspect === undefined)
return false; return false;
const aspect = config.aspects[this._builder.character.aspect]! const aspect = config.aspects[builder.character.aspect]!
if(physic > aspect.physic.max || physic < aspect.physic.min) if(physic > aspect.physic.max || physic < aspect.physic.min)
return false; return false;
@ -1168,8 +1137,4 @@ class AspectPicker implements BuilderTab
return true; return true;
} }
get dom()
{
return this._content;
}
} }