New ability display, sereval Character compile and creation fixes
This commit is contained in:
parent
61d2d144b7
commit
eb0c33deae
BIN
db.sqlite-shm
BIN
db.sqlite-shm
Binary file not shown.
BIN
db.sqlite-wal
BIN
db.sqlite-wal
Binary file not shown.
|
|
@ -1,5 +1,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import characterConfig from '#shared/character-config.json';
|
||||||
|
import type { CharacterConfig } from '~/types/character';
|
||||||
const { data: characters, error, status } = await useFetch(`/api/character`, { params: { visibility: "public" } });
|
const { data: characters, error, status } = await useFetch(`/api/character`, { params: { visibility: "public" } });
|
||||||
|
const config = characterConfig as CharacterConfig;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -11,13 +14,22 @@ const { data: characters, error, status } = await useFetch(`/api/character`, { p
|
||||||
<Loading size="large" />
|
<Loading size="large" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="status === 'success'" class="grid p-6 2xl:grid-cols-3 lg:grid-cols-2 grid-cols-1 gap-4 w-full">
|
<div v-else-if="status === 'success'" class="grid p-6 2xl:grid-cols-3 lg:grid-cols-2 grid-cols-1 gap-4 w-full">
|
||||||
<div class="border border-light-30 dark:border-dark-30 p-3 flex flex-row gap-4" v-for="character of characters">
|
<div class="flex flex-col w-[360px] border border-light-35 dark:border-dark-35" v-for="character of characters">
|
||||||
<Avatar size="large" icon="radix-icons:person" src="" />
|
<NuxtLink :to="{ name: 'character-id', params: { id: character.id } }" class="group bg-light-10 dark:bg-dark-10 p-2 flex flex-col gap-2">
|
||||||
<div class="flex flex-1 flex-shrink flex-col truncate">
|
<div class="flex flex-row gap-8 ps-4 items-center">
|
||||||
<NuxtLink class="text-xl font-bold hover:text-accent-blue truncate" :to="{ name: 'character-id', params: { id: character.id } }" :title="character.name">{{ character.name }}</NuxtLink>
|
<div class="flex flex-1 flex-col gap-2 justify-center">
|
||||||
<span class="text-sm truncate">Niveau {{ character.level }}</span>
|
<span class="text-lg font-bold group-hover:text-accent-blue">{{ character.name }}</span>
|
||||||
|
<span class="border-b w-full border-light-50 dark:border-dark-50"></span>
|
||||||
|
<div class="flex flex-row flex-1 items-stretch gap-4">
|
||||||
|
<span class="text-sm">Niveau {{ character.level }}</span>
|
||||||
|
<span class="w-px h-full bg-light-50 dark:bg-dark-50"></span>
|
||||||
|
<span class="text-sm italic">{{ config.peoples[character.people!]?.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="rounded-full w-[96px] h-[96px] border border-light-50 dark:border-dark-50 bg-light-100 dark:bg-dark-100 !bg-opacity-10"></div>
|
||||||
|
</div>
|
||||||
|
</NuxtLink>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<span>Erreur de chargement</span>
|
<span>Erreur de chargement</span>
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export default defineEventHandler(async (e) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
where = (character, { eq, and }) => and(eq(character.owner, session.user!.id), eq(character.visibility, "private"));
|
where = (character, { eq, and }) => and(eq(character.owner, session.user!.id));
|
||||||
}
|
}
|
||||||
else if(visibility === 'public')
|
else if(visibility === 'public')
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,12 @@ export default defineEventHandler(async (e) => {
|
||||||
thumbnail: body.data.thumbnail,
|
thumbnail: body.data.thumbnail,
|
||||||
}).returning({ id: characterTable.id }).get().id;
|
}).returning({ id: characterTable.id }).get().id;
|
||||||
|
|
||||||
if(Object.keys(body.data.leveling).length > 0) tx.insert(characterLevelingTable).values(Object.entries(body.data.leveling).map(e => ({ character: id, level: parseInt(e[0], 10), choice: e[1]! }))).run();
|
if(Object.keys(body.data.leveling).length > 0) tx.insert(characterLevelingTable).values(Object.entries(body.data.leveling).filter(e => e[1] !== undefined).map(e => ({ character: id, level: parseInt(e[0], 10), choice: e[1]! }))).run();
|
||||||
|
|
||||||
const training = Object.entries(body.data.training).flatMap(e => Object.entries(e[1]).map(_e => ({ character: id, stat: e[0] as MainStat, level: parseInt(_e[0], 10), choice: _e[1]! })));
|
const training = Object.entries(body.data.training).flatMap(e => Object.entries(e[1]).filter(e => e[1] !== undefined).map(_e => ({ character: id, stat: e[0] as MainStat, level: parseInt(_e[0], 10), choice: _e[1]! })));
|
||||||
if(training.length > 0) tx.insert(characterTrainingTable).values(training).run();
|
if(training.length > 0) tx.insert(characterTrainingTable).values(training).run();
|
||||||
|
|
||||||
const abilities = Object.entries(body.data.abilities).map(e => ({ character: id, ability: e[0] as Ability, value: e[1] }));
|
const abilities = Object.entries(body.data.abilities).filter(e => e[1] !== undefined).map(e => ({ character: id, ability: e[0] as Ability, value: e[1] }));
|
||||||
if(abilities.length > 0) tx.insert(characterAbilitiesTable).values(abilities).run();
|
if(abilities.length > 0) tx.insert(characterAbilitiesTable).values(abilities).run();
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export const defaultCharacter: Character = {
|
||||||
people: undefined,
|
people: undefined,
|
||||||
level: 1,
|
level: 1,
|
||||||
|
|
||||||
training: MAIN_STATS.reduce((p, v) => { p[v] = { 0: 0 }; return p; }, {} as Record<MainStat, Partial<Record<TrainingLevel, number>>>),
|
training: MAIN_STATS.reduce((p, v) => { p[v] = { 0: 0, 1: 0, 2: 0, 3: 0, 4: 0 }; return p; }, {} as Record<MainStat, Partial<Record<TrainingLevel, number>>>),
|
||||||
leveling: { 1: 0 },
|
leveling: { 1: 0 },
|
||||||
abilities: {},
|
abilities: {},
|
||||||
choices: {},
|
choices: {},
|
||||||
|
|
@ -227,7 +227,7 @@ export const CharacterVariablesValidation = z.object({
|
||||||
state: z.number().min(1).max(7).or(z.literal(true)),
|
state: z.number().min(1).max(7).or(z.literal(true)),
|
||||||
})),
|
})),
|
||||||
spells: z.array(z.string()),
|
spells: z.array(z.string()),
|
||||||
equipment: z.array(z.string()),
|
items: z.array(z.string()),
|
||||||
});
|
});
|
||||||
export const CharacterValidation = z.object({
|
export const CharacterValidation = z.object({
|
||||||
id: z.number(),
|
id: z.number(),
|
||||||
|
|
@ -424,13 +424,16 @@ export class CharacterCompiler
|
||||||
if(buffer && buffer._dirty === true)
|
if(buffer && buffer._dirty === true)
|
||||||
{
|
{
|
||||||
let sum = 0, shortcut = false;
|
let sum = 0, shortcut = false;
|
||||||
for(let i = 0; i < buffer.list.length; i++)
|
for(let j = 0; j < buffer.list.length; j++)
|
||||||
{
|
{
|
||||||
if(typeof buffer.list[i]!.value === 'string') // Add or set a modifier
|
if(typeof buffer.list[j]!.value === 'string') // Add or set a modifier
|
||||||
{
|
{
|
||||||
const modifier = this._buffer[buffer.list[i]!.value as string];
|
const modifier = this._buffer[buffer.list[j]!.value as string];
|
||||||
if(!modifier)
|
if(!modifier)
|
||||||
{
|
{
|
||||||
|
if(!queue.includes(buffer.list[j]!.value as string))
|
||||||
|
this._buffer[buffer.list[j]!.value as string] = { _dirty: false, list: [], min: -Infinity, value: 0 };
|
||||||
|
|
||||||
queue.push(property);
|
queue.push(property);
|
||||||
shortcut = true;
|
shortcut = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -438,29 +441,29 @@ export class CharacterCompiler
|
||||||
else if(modifier._dirty)
|
else if(modifier._dirty)
|
||||||
{
|
{
|
||||||
//Put it back in queue since its dependencies haven't been resolved yet
|
//Put it back in queue since its dependencies haven't been resolved yet
|
||||||
queue.push(buffer.list[i]!.value as string);
|
queue.push(buffer.list[j]!.value as string);
|
||||||
queue.push(property);
|
queue.push(property);
|
||||||
shortcut = true;
|
shortcut = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(buffer.list[i]?.operation === 'add')
|
if(buffer.list[j]?.operation === 'add')
|
||||||
sum += modifier.value;
|
sum += modifier.value;
|
||||||
else if(buffer.list[i]?.operation === 'set')
|
else if(buffer.list[j]?.operation === 'set')
|
||||||
sum = modifier.value;
|
sum = modifier.value;
|
||||||
else if(buffer.list[i]?.operation === 'min')
|
else if(buffer.list[j]?.operation === 'min')
|
||||||
this._buffer[property]!.min = modifier.value;
|
this._buffer[property]!.min = modifier.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(buffer.list[i]?.operation === 'add')
|
if(buffer.list[j]?.operation === 'add')
|
||||||
sum += buffer.list[i]!.value as number;
|
sum += buffer.list[j]!.value as number;
|
||||||
else if(buffer.list[i]?.operation === 'set')
|
else if(buffer.list[j]?.operation === 'set')
|
||||||
sum = buffer.list[i]!.value as number;
|
sum = buffer.list[j]!.value as number;
|
||||||
else if(buffer.list[i]?.operation === 'min')
|
else if(buffer.list[j]?.operation === 'min')
|
||||||
this._buffer[property]!.min = buffer.list[i]!.value as number;
|
this._buffer[property]!.min = buffer.list[j]!.value as number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1348,18 +1351,18 @@ export class CharacterSheet
|
||||||
]),
|
]),
|
||||||
|
|
||||||
div("flex flex-1 flex-row items-stretch justify-center py-2 gap-4", [
|
div("flex flex-1 flex-row items-stretch justify-center py-2 gap-4", [
|
||||||
div("flex flex-col gap-4 py-1 w-80", [
|
div("flex flex-col gap-4 py-1 w-60", [
|
||||||
div("flex flex-col py-1 gap-4", [
|
div("flex flex-col py-1 gap-4", [
|
||||||
div("flex flex-row items-center justify-center gap-4", [
|
div("flex flex-row items-center justify-center gap-4", [
|
||||||
div("flex flex-row items-center justify-center gap-2", [ dom("div", { class: 'text-xl font-semibold', text: "Compétences" }), proses('a', preview, [ icon('radix-icons:question-mark-circled', { width: 16, height: 16, class: 'text-light-70 dark:text-dark-70' }) ], { href: 'regles/l\'entrainement/competences', size: 'small', class: 'h-4' }) ]),
|
div("flex flex-row items-center justify-center gap-2", [ dom("div", { class: 'text-xl font-semibold', text: "Compétences" }), proses('a', preview, [ icon('radix-icons:question-mark-circled', { width: 16, height: 16, class: 'text-light-70 dark:text-dark-70' }) ], { href: 'regles/l\'entrainement/competences', size: 'small', class: 'h-4' }) ]),
|
||||||
div("flex flex-1 border-t border-dashed border-light-50 dark:border-dark-50")
|
div("flex flex-1 border-t border-dashed border-light-50 dark:border-dark-50")
|
||||||
]),
|
]),
|
||||||
|
|
||||||
div("grid grid-cols-3 gap-2",
|
div("grid grid-cols-2 gap-2",
|
||||||
Object.entries(character.abilities).map(([ability, value]) =>
|
Object.entries(character.abilities).map(([ability, value]) =>
|
||||||
div("flex flex-col px-2 items-center text-sm text-light-70 dark:text-dark-70", [
|
div("flex flex-row px-1 justify-between items-center", [
|
||||||
dom("span", { class: "font-bold text-base text-light-100 dark:text-dark-100", text: `+${value}` }),
|
span("text-sm text-light-70 dark:text-dark-70 max-w-20 truncate", abilityTexts[ability as Ability] || ability),
|
||||||
dom("span", { text: abilityTexts[ability as Ability] || ability })
|
span("font-bold text-base text-light-100 dark:text-dark-100", `+${value}`),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue