Add LevelPicker
This commit is contained in:
parent
ba8c7b05e6
commit
3ef98df5d2
BIN
db.sqlite-shm
BIN
db.sqlite-shm
Binary file not shown.
BIN
db.sqlite-wal
BIN
db.sqlite-wal
Binary file not shown.
|
|
@ -186,248 +186,168 @@
|
|||
"options": {
|
||||
"1": [
|
||||
{
|
||||
"training": 35,
|
||||
"health": 14
|
||||
"description": "+35 points de statistiques.\n+14 PV max."
|
||||
}
|
||||
],
|
||||
"2": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 3,
|
||||
"mana": 2
|
||||
"description": "+1 point de statistique.\n+3 PV max.\n+2 mana max."
|
||||
},
|
||||
{
|
||||
"health": 6,
|
||||
"mana": 3,
|
||||
"abilities": 1
|
||||
"description": "+1 point de compétence.\n+6 PV max.\n+3 mana max."
|
||||
}
|
||||
],
|
||||
"3": [
|
||||
{
|
||||
"training": 2,
|
||||
"health": 3,
|
||||
"mana": 1,
|
||||
"abilities": 1
|
||||
"description": "+2 points de statistiques.\n+1 point de compétence.\n+3 PV max.\n+1 mana max."
|
||||
}
|
||||
],
|
||||
"4": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 4,
|
||||
"mana": 2,
|
||||
"abilities": 2
|
||||
"description": "+1 point de statistique.\n+2 points de compétences.\n+4 PV max.\n+2 mana max."
|
||||
}
|
||||
],
|
||||
"5": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 4,
|
||||
"mana": 2,
|
||||
"abilities": 2
|
||||
"description": "+1 point de statistique.\n+2 points de compétences.\n+4 PV max.\n+2 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"shaping": 1,
|
||||
"health": 8,
|
||||
"mana": 4
|
||||
"description": "+1 point de statistique.\n+1 transformation par jour.\n+8 PV max.\n+4 mana max."
|
||||
},
|
||||
{
|
||||
"training": 2,
|
||||
"health": 7,
|
||||
"mana": 2
|
||||
"description": "+2 points de statistiques.\n+7 PV max.\n+2 mana max."
|
||||
}
|
||||
],
|
||||
"6": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 3,
|
||||
"mana": 3
|
||||
"description": "+1 point de statistique.\n+3 PV max.\n+3 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"abilities": 3,
|
||||
"spellslots": 1
|
||||
"description": "+1 point de statistique.\n+3 points de compétences.\n+1 sort maitrisé."
|
||||
}
|
||||
],
|
||||
"7": [
|
||||
{
|
||||
"training": 2,
|
||||
"health": 3,
|
||||
"mana": 5
|
||||
"description": "+2 points de statistiques.\n+3 PV max.\n+5 mana max."
|
||||
},
|
||||
{
|
||||
"training": 2,
|
||||
"health": 5,
|
||||
"mana": 2
|
||||
"description": "+2 points de statistiques.\n+5 PV max.\n+2 mana max."
|
||||
}
|
||||
],
|
||||
"8": [
|
||||
{
|
||||
"training": 3
|
||||
"description": "+3 points de statistiques."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"health": 6,
|
||||
"mana": 6,
|
||||
"spellslots": 1
|
||||
"description": "+1 point de statistique.\n+6 PV max.\n+6 mana max.\n+1 sort maitrisé."
|
||||
}
|
||||
],
|
||||
"9": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 3,
|
||||
"mana": 5
|
||||
"description": "+1 point de statistique.\n+3 PV max.\n+5 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"health": 2,
|
||||
"abilities": 2
|
||||
"description": "+1 point de statistique.\n+2 points de compétences.\n+2 PV max."
|
||||
}
|
||||
],
|
||||
"10": [
|
||||
{
|
||||
"training": 2
|
||||
"description": "+2 points de statistiques."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"shaping": 1,
|
||||
"abilities": 2
|
||||
"description": "+1 point de statistique.\n+1 transformation par jour.\n+2 points de compétences."
|
||||
},
|
||||
{
|
||||
"modifier": 1,
|
||||
"abilities": 1
|
||||
"description": "+1 au modifieur de votre choix.\n+1 point de compétence."
|
||||
}
|
||||
],
|
||||
"11": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 7,
|
||||
"mana": 1
|
||||
"description": "+1 point de statistique.\n+7 PV max.\n+1 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"health": 2,
|
||||
"mana": 5
|
||||
"description": "+1 point de statistique.\n+2 PV max.\n+5 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"abilities": 2
|
||||
"description": "+1 point de statistique.\n+2 points de compétences."
|
||||
}
|
||||
],
|
||||
"12": [
|
||||
{
|
||||
"training": 2,
|
||||
"spellslots": 1
|
||||
"description": "+2 points de statistiques.\n+1 sort maitrisé."
|
||||
},
|
||||
{
|
||||
"training": 2,
|
||||
"health": 8
|
||||
"description": "+2 points de statistiques.\n+8 PV max."
|
||||
},
|
||||
{
|
||||
"training": 2,
|
||||
"mana": 7
|
||||
"description": "+2 points de statistiques.\n+7 mana max."
|
||||
}
|
||||
],
|
||||
"13": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 2,
|
||||
"mana": 2,
|
||||
"abilities": 1
|
||||
"description": "+1 point de statistique.\n+1 point de compétence.\n+2 PV max.\n+2 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"shaping": 1,
|
||||
"health": 4,
|
||||
"mana": 4
|
||||
"description": "+1 point de statistique.\n+1 transformation par jour.\n+4 PV max.\n+4 mana max."
|
||||
}
|
||||
],
|
||||
"14": [
|
||||
{
|
||||
"training": 3,
|
||||
"health": 3,
|
||||
"mana": 5
|
||||
"description": "+3 points de statistiques.\n+3 PV max.\n+5 mana max."
|
||||
},
|
||||
{
|
||||
"training": 3,
|
||||
"health": 6,
|
||||
"mana": 1
|
||||
"description": "+3 points de statistiques.\n+6 PV max.\n+1 mana max."
|
||||
}
|
||||
],
|
||||
"15": [
|
||||
{
|
||||
"training": 1
|
||||
"description": "+1 point de statistique."
|
||||
},
|
||||
{
|
||||
"health": 5,
|
||||
"mana": 5,
|
||||
"abilities": 1
|
||||
"description": "+1 point de compétence.\n+5 PV max.\n+5 mana max."
|
||||
}
|
||||
],
|
||||
"16": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 3,
|
||||
"mana": 5
|
||||
"description": "+1 point de statistique.\n+3 PV max.\n+5 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"health": 5,
|
||||
"mana": 2
|
||||
"description": "+1 point de statistique.\n+5 PV max.\n+2 mana max."
|
||||
}
|
||||
],
|
||||
"17": [
|
||||
{
|
||||
"training": 2,
|
||||
"abilities": 1,
|
||||
"spellslots": 1
|
||||
"description": "+2 points de statistiques.\n+1 point de compétence.\n+1 sort maitrisé."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"shaping": 1,
|
||||
"abilities": 2,
|
||||
"spellslots": 1
|
||||
"description": "+1 point de statistique.\n+1 transformation par jour.\n+2 points de compétences.\n+1 sort maitrisé."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"health": 7,
|
||||
"mana": 5,
|
||||
"abilities": 1
|
||||
"description": "+1 point de statistique.\n+1 point de compétence.\n+7 PV max.\n+5 mana max."
|
||||
}
|
||||
],
|
||||
"18": [
|
||||
{
|
||||
"training": 1,
|
||||
"health": 6,
|
||||
"mana": 1
|
||||
"description": "+1 point de statistique.\n+6 PV max.\n+1 mana max."
|
||||
},
|
||||
{
|
||||
"training": 1,
|
||||
"health": 2,
|
||||
"mana": 5
|
||||
"description": "+1 point de statistique.\n+2 PV max.\n+5 mana max."
|
||||
}
|
||||
],
|
||||
"19": [
|
||||
{
|
||||
"training": 2,
|
||||
"health": 6,
|
||||
"mana": 3,
|
||||
"abilities": 2
|
||||
"description": "+2 points de statistiques.\n+2 points de compétences.\n+6 PV max.\n+3 mana max."
|
||||
},
|
||||
{
|
||||
"training": 2,
|
||||
"health": 2,
|
||||
"mana": 5,
|
||||
"spellslots": 1
|
||||
"description": "+2 points de statistiques.\n+2 PV max.\n+5 mana max.\n+1 sort maitrisé."
|
||||
}
|
||||
],
|
||||
"20": [
|
||||
{
|
||||
"training": 2
|
||||
"description": "+2 points de statistiques."
|
||||
},
|
||||
{
|
||||
"modifier": 1,
|
||||
"abilities": 1
|
||||
"description": "+1 au modifieur de votre choix.\n+1 point de compétence."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import characterConfig from './character-config.json';
|
|||
import { button, loading } from "./proses";
|
||||
import { div, dom, icon, text } from "./dom.util";
|
||||
import { popper } from "./floating.util";
|
||||
import { clamp } from "./general.util";
|
||||
|
||||
const config = characterConfig as CharacterConfig;
|
||||
|
||||
|
|
@ -182,6 +183,7 @@ export class CharacterBuilder
|
|||
];
|
||||
this._stepsContent = [
|
||||
new PeoplePicker(this),
|
||||
new LevelPicker(this),
|
||||
];
|
||||
this._content = div('flex-1 outline-none max-w-full w-full overflow-y-auto');
|
||||
this._container.appendChild(div('flex flex-1 flex-col justify-start items-center px-8 w-full h-full overflow-y-hidden', [
|
||||
|
|
@ -301,7 +303,7 @@ export class CharacterBuilder
|
|||
}
|
||||
})
|
||||
}
|
||||
private updateLevel(level: Level)
|
||||
updateLevel(level: Level)
|
||||
{
|
||||
this._character.level = level;
|
||||
|
||||
|
|
@ -320,7 +322,7 @@ export class CharacterBuilder
|
|||
}
|
||||
}
|
||||
}
|
||||
private toggleLevelOption(level: Level, choice: number)
|
||||
toggleLevelOption(level: Level, choice: number)
|
||||
{
|
||||
if(level > this._character.level) //Cannot add more level options than the current level
|
||||
return;
|
||||
|
|
@ -355,7 +357,7 @@ export class CharacterBuilder
|
|||
this.add(config.peoples[this._character.people!]!.options[level][choice]!);
|
||||
}
|
||||
}
|
||||
private toggleTrainingOption(stat: MainStat, level: TrainingLevel, option: number)
|
||||
toggleTrainingOption(stat: MainStat, level: TrainingLevel, option: number)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -422,17 +424,6 @@ class PeoplePicker implements BuilderTab
|
|||
|
||||
constructor(builder: CharacterBuilder)
|
||||
{
|
||||
/*
|
||||
<div class="flex flex-1 gap-4 p-2 overflow-x-auto justify-center">
|
||||
<div v-for="(people, i) of config.peoples" @click="model.character.people = i" class="flex flex-col flex-nowrap gap-2 p-2 border border-light-35 dark:border-dark-35
|
||||
cursor-pointer hover:border-light-70 dark:hover:border-dark-70 w-[320px]" :class="{ '!border-accent-blue outline-2 outline outline-accent-blue': model.character.people === i }">
|
||||
<Avatar :src="people.name" :text="`Image placeholder`" class="h-[320px]" />
|
||||
<span class="text-xl font-bold text-center">{{ people.name }}</span>
|
||||
<span class="w-full border-b border-light-50 dark:border-dark-50"></span>
|
||||
<span class="text-wrap word-break">{{ people.description }}</span>
|
||||
</div>
|
||||
</div>
|
||||
*/
|
||||
this._builder = builder;
|
||||
|
||||
this._nameInput = dom("input", { class: `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
|
||||
|
|
@ -496,3 +487,108 @@ class PeoplePicker implements BuilderTab
|
|||
return this._content;
|
||||
}
|
||||
}
|
||||
class LevelPicker implements BuilderTab
|
||||
{
|
||||
private _builder: CharacterBuilder;
|
||||
private _content: Array<Node | string>;
|
||||
|
||||
private _levelInput: HTMLInputElement;
|
||||
private _pointsInput: HTMLInputElement;
|
||||
private _healthText: Text;
|
||||
private _manaText: Text;
|
||||
private _options: HTMLDivElement[][];
|
||||
|
||||
constructor(builder: CharacterBuilder)
|
||||
{
|
||||
this._builder = builder;
|
||||
|
||||
this._levelInput = 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) => {
|
||||
this._builder.character.level = parseInt(this._levelInput.value) ?? 1;
|
||||
this.updateLevel();
|
||||
},
|
||||
keydown: (e: KeyboardEvent) => {
|
||||
let value = this._levelInput.value;
|
||||
switch(e.key)
|
||||
{
|
||||
case "ArrowUp":
|
||||
value = clamp(parseInt(value) + 1, 1, 20).toString();
|
||||
break;
|
||||
case "ArrowDown":
|
||||
value = clamp(parseInt(value) - 1, 1, 20).toString();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(this._levelInput.value !== value)
|
||||
{
|
||||
this._levelInput.value = value;
|
||||
this._builder.character.level = parseInt(value);
|
||||
this.updateLevel();
|
||||
}
|
||||
}
|
||||
}});
|
||||
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 px-3 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._options = Object.entries(config.peoples[this._builder.character.people!]!.options).map(
|
||||
(level) => [ div("w-full h-px", [div("border-t border-dashed border-light-50 dark:border-dark-50 w-full"), div("sticky top-0", [ text(level[0]) ])]),
|
||||
div("flex flex-row gap-4 justify-center", level[1].map((option, j) => dom("div", { class: ["flex border border-light-50 dark:border-dark-50 px-4 py-2 w-[400px]", { 'hover:border-light-70 dark:hover:border-dark-70 cursor-pointer': (level[0] as any as Level) <= this._builder.character.level, '!border-accent-blue bg-accent-blue bg-opacity-20': this._builder.character.leveling?.some(e => e[0] == (level[0] as any as Level) && e[1] === j) ?? false }], listeners: { click: e => {
|
||||
this._builder.toggleLevelOption(level[0] as any as Level, j);
|
||||
}}}, [ dom('span', { class: "text-wrap whitespace-pre", text: option.description }) ])))
|
||||
]);
|
||||
|
||||
this._content = [ div("flex flex-1 gap-12 px-2 py-4 justify-center items-center", [
|
||||
dom("label", { class: "flex justify-center items-center my-2" }, [
|
||||
dom("span", { class: "pb-1 md:p-0", text: "Niveau" }),
|
||||
this._levelInput,
|
||||
]),
|
||||
dom("label", { class: "flex justify-center items-center my-2" }, [
|
||||
dom("span", { class: "md:text-base text-sm", text: "Points restantes" }),
|
||||
this._pointsInput,
|
||||
]),
|
||||
div("flex justify-center items-center gap-2 my-2 md:text-base text-sm", [
|
||||
dom("span", { text: "Vie" }),
|
||||
this._healthText,
|
||||
]),
|
||||
div("flex justify-center items-center gap-2 my-2 md:text-base text-sm", [
|
||||
dom("span", { text: "Mana" }),
|
||||
this._manaText,
|
||||
]),
|
||||
button(text('Suivant'), () => this._builder.display(1), 'h-[35px] px-[15px]'),
|
||||
]), div('flex flex-col flex-1 gap-4 mx-8 my-4', this._options.flatMap(e => [...e]))];
|
||||
}
|
||||
update()
|
||||
{
|
||||
const values = this._builder.values;
|
||||
|
||||
this._levelInput.value = this._builder.character.level.toString();
|
||||
this._pointsInput.value = (this._builder.character.level - this._builder.character.leveling.length).toString();
|
||||
this._healthText.textContent = values.health?.toString() ?? '0';
|
||||
this._manaText.textContent = values.mana?.toString() ?? '0';
|
||||
|
||||
this.updateLevel();
|
||||
}
|
||||
private updateLevel()
|
||||
{
|
||||
this._builder.updateLevel(this._builder.character.level as Level);
|
||||
|
||||
this._options.forEach((e, i) => {
|
||||
e[0]?.classList.toggle("opacity-30", ((i + 1) as Level) > this._builder.character.level);
|
||||
e[1]?.classList.toggle("opacity-30", ((i + 1) as Level) > this._builder.character.level);
|
||||
e[1]?.childNodes.forEach((option, j) => {
|
||||
'hover:border-light-70 dark:hover:border-dark-70 cursor-pointer'.split(" ").forEach(_e => (option as HTMLDivElement).classList.toggle(_e, ((i + 1) as Level) <= this._builder.character.level));
|
||||
'!border-accent-blue bg-accent-blue bg-opacity-20'.split(" ").forEach(_e => (option as HTMLDivElement).classList.toggle(_e, this._builder.character.leveling?.some(e => e[0] == ((i + 1) as Level) && e[1] === j) ?? false));
|
||||
})
|
||||
});
|
||||
}
|
||||
validate(): boolean
|
||||
{
|
||||
return this._builder.character.people !== undefined;
|
||||
}
|
||||
get dom()
|
||||
{
|
||||
return this._content;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue