Character creation UI fixes, updates and resistances are displayed.
This commit is contained in:
parent
0771d5ebd1
commit
7a11c5382c
BIN
db.sqlite-shm
BIN
db.sqlite-shm
Binary file not shown.
BIN
db.sqlite-wal
BIN
db.sqlite-wal
Binary file not shown.
|
|
@ -4,9 +4,9 @@ function raceOptionToText(option: RaceOption): string
|
||||||
{
|
{
|
||||||
const text = [];
|
const text = [];
|
||||||
if(option.training) text.push(`+${option.training} point${option.training > 1 ? 's' : ''} de statistique${option.training > 1 ? 's' : ''}.`);
|
if(option.training) text.push(`+${option.training} point${option.training > 1 ? 's' : ''} de statistique${option.training > 1 ? 's' : ''}.`);
|
||||||
if(option.spec) text.push(`+${option.spec} spécialisation${option.spec > 1 ? 's' : ''}.`);
|
|
||||||
if(option.shaping) text.push(`+${option.shaping} transformation${option.shaping > 1 ? 's' : ''} par jour.`);
|
if(option.shaping) text.push(`+${option.shaping} transformation${option.shaping > 1 ? 's' : ''} par jour.`);
|
||||||
if(option.modifier) text.push(`+${option.modifier} au modifieur de votre choix.`);
|
if(option.modifier) text.push(`+${option.modifier} au modifieur de votre choix.`);
|
||||||
|
if(option.abilities) text.push(`+${option.abilities} point${option.abilities > 1 ? 's' : ''} de compétence${option.abilities > 1 ? 's' : ''}.`);
|
||||||
if(option.health) text.push(`+${option.health} PV max.`);
|
if(option.health) text.push(`+${option.health} PV max.`);
|
||||||
if(option.mana) text.push(`+${option.mana} mana max.`);
|
if(option.mana) text.push(`+${option.mana} mana max.`);
|
||||||
return text.join('\n');
|
return text.join('\n');
|
||||||
|
|
@ -31,9 +31,9 @@ function abilitySpecialFeatures(type: "points" | "max", curiosity: DoubleIndex<T
|
||||||
{
|
{
|
||||||
if(type === 'points')
|
if(type === 'points')
|
||||||
{
|
{
|
||||||
if(curiosity.find(e => e[0] == 7 && e[1] === 0))
|
if(curiosity.find(e => e[0] == 6 && e[1] === 0))
|
||||||
return Math.max(6, value);
|
return Math.max(6, value);
|
||||||
if(curiosity.find(e => e[0] == 7 && e[1] === 2))
|
if(curiosity.find(e => e[0] == 6 && e[1] === 2))
|
||||||
return value + 1;
|
return value + 1;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
@ -80,13 +80,13 @@ const raceOptions = computed(() => data.value.progress.race.index !== undefined
|
||||||
const selectedRaceOptions = computed(() => raceOptions !== undefined ? data.value.progress.race.progress!.map(e => raceOptions.value![e[0]][e[1]]) : undefined);
|
const selectedRaceOptions = computed(() => raceOptions !== undefined ? data.value.progress.race.progress!.map(e => raceOptions.value![e[0]][e[1]]) : undefined);
|
||||||
const trainingPoints = computed(() => raceOptions.value ? data.value.progress.race.progress?.reduce((p, v) => p + (raceOptions.value![v[0]][v[1]].training ?? 0), 0) : 0);
|
const trainingPoints = computed(() => raceOptions.value ? data.value.progress.race.progress?.reduce((p, v) => p + (raceOptions.value![v[0]][v[1]].training ?? 0), 0) : 0);
|
||||||
const training = computed(() => Object.entries(characterConfig.training).map(e => [e[0], getFeaturesOf(e[0] as MainStat, data.value.progress.training[e[0] as MainStat])]) as [MainStat, TrainingOption[]][]);
|
const training = computed(() => Object.entries(characterConfig.training).map(e => [e[0], getFeaturesOf(e[0] as MainStat, data.value.progress.training[e[0] as MainStat])]) as [MainStat, TrainingOption[]][]);
|
||||||
const maxTraining = computed(() => Object.entries(data.value.progress.training).reduce((p, v) => { p[v[0]] = v[1].reduce((_p, _v) => Math.max(_p, _v[0]) , 0); return p; }, {} as Record<MainStat, number>));
|
const maxTraining = computed(() => Object.entries(data.value.progress.training).reduce((p, v) => { p[v[0] as MainStat] = v[1].reduce((_p, _v) => Math.max(_p, _v[0]) , 0); return p; }, {} as Record<MainStat, number>));
|
||||||
const trainingSpent = computed(() => Object.values(maxTraining.value).reduce((p, v) => p + v, 0));
|
const trainingSpent = computed(() => Object.values(maxTraining.value).reduce((p, v) => p + v, 0));
|
||||||
const modifiers = computed(() => Object.entries(maxTraining.value).reduce((p, v) => { p[v[0]] = Math.floor(v[1] / 3) + (data.value.progress.modifiers ? (data.value.progress.modifiers[v[0] as MainStat] ?? 0) : 0); return p; }, {} as Record<MainStat, number>))
|
const modifiers = computed(() => Object.entries(maxTraining.value).reduce((p, v) => { p[v[0] as MainStat] = Math.floor(v[1] / 3) + (data.value.progress.modifiers ? (data.value.progress.modifiers[v[0] as MainStat] ?? 0) : 0); return p; }, {} as Record<MainStat, number>))
|
||||||
const modifierPoints = computed(() => (selectedRaceOptions.value ? selectedRaceOptions.value.reduce((p, v) => p + (v?.modifier ?? 0), 0) : 0) + training.value.reduce((p, v) => p + v[1].reduce((_p, _v) => _p + (_v?.modifier ?? 0), 0), 0));
|
const modifierPoints = computed(() => (selectedRaceOptions.value ? selectedRaceOptions.value.reduce((p, v) => p + (v?.modifier ?? 0), 0) : 0) + training.value.reduce((p, v) => p + v[1].reduce((_p, _v) => _p + (_v?.modifier ?? 0), 0), 0));
|
||||||
const modifierSpent = computed(() => Object.values(data.value.progress.modifiers ?? {}).reduce((p, v) => p + v, 0));
|
const modifierSpent = computed(() => Object.values(data.value.progress.modifiers ?? {}).reduce((p, v) => p + v, 0));
|
||||||
const abilityPoints = computed(() => training.value.flatMap(e => e[1].filter(_e => _e.ability !== undefined)).reduce((p, v) => p + v.ability!, 0));
|
const abilityPoints = computed(() => training.value.flatMap(e => e[1].filter(_e => _e.ability !== undefined)).reduce((p, v) => p + v.ability!, 0));
|
||||||
const abilityMax = computed(() => Object.entries(characterConfig.ability).reduce((p, v) => { p[v[0]] = abilitySpecialFeatures("max", data.value.progress.training.curiosity, Math.floor(maxTraining.value[v[1].max[0]] / 3) + Math.floor(maxTraining.value[v[1].max[1]] / 3)); return p; }, {} as Record<Ability, number>));
|
const abilityMax = computed(() => Object.entries(characterConfig.abilities).reduce((p, v) => { p[v[0] as Ability] = abilitySpecialFeatures("max", data.value.progress.training.curiosity, Math.floor(maxTraining.value[v[1].max[0]] / 3) + Math.floor(maxTraining.value[v[1].max[1]] / 3)); return p; }, {} as Record<Ability, number>));
|
||||||
const abilitySpent = computed(() => Object.values(data.value.progress.abilities ?? {}).reduce((p, v) => p + v[0], 0));
|
const abilitySpent = computed(() => Object.values(data.value.progress.abilities ?? {}).reduce((p, v) => p + v[0], 0));
|
||||||
|
|
||||||
if(id !== 'new')
|
if(id !== 'new')
|
||||||
|
|
@ -277,14 +277,14 @@ useShortcuts({
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default>
|
||||||
<div class="flex flex-col gap-4 max-h-[50vh] pe-4 relative overflow-y-auto overflow-x-hidden">
|
<div class="flex flex-col gap-4 max-h-[50vh] pe-4 relative overflow-y-auto overflow-x-hidden">
|
||||||
<div class="sticky top-0 py-2 bg-light-0 dark:bg-dark-0 z-10 flex justify-between">
|
<div class="sticky top-0 z-10 py-2 bg-light-0 dark:bg-dark-0 flex justify-between">
|
||||||
<Icon icon="radix-icons:caret-left" class="w-6 h-6 border border-light-30 dark:border-dark-30 cursor-pointer" @click="() => trainingTab = clamp(trainingTab - 1, 0, 6)" />
|
<Icon icon="radix-icons:caret-left" class="w-6 h-6 border border-light-30 dark:border-dark-30 cursor-pointer" @click="() => trainingTab = clamp(trainingTab - 1, 0, 6)" />
|
||||||
<span class="text-xl" :class="{ 'text-light-red dark:text-dark-red': (trainingPoints ?? 0) < trainingSpent }">Points d'entrainement restants: {{ (trainingPoints ?? 0) - trainingSpent }}</span>
|
<span class="text-xl" :class="{ 'text-light-red dark:text-dark-red': (trainingPoints ?? 0) < trainingSpent }">Points d'entrainement restants: {{ (trainingPoints ?? 0) - trainingSpent }}</span>
|
||||||
<Icon icon="radix-icons:caret-right" class="w-6 h-6 border border-light-30 dark:border-dark-30 cursor-pointer" @click="() => trainingTab = clamp(trainingTab + 1, 0, 6)" />
|
<Icon icon="radix-icons:caret-right" class="w-6 h-6 border border-light-30 dark:border-dark-30 cursor-pointer" @click="() => trainingTab = clamp(trainingTab + 1, 0, 6)" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-4 relative" :style="`left: calc(calc(-100% - 1em) * ${trainingTab}); transition: left .5s ease;`">
|
<div class="flex gap-4 relative" :style="`left: calc(calc(-100% - 1em) * ${trainingTab}); transition: left .5s ease;`">
|
||||||
<div class="flex w-full flex-shrink-0 flex-col gap-2 relative" v-for="(text, stat) of mainStatTexts">
|
<div class="flex w-full flex-shrink-0 flex-col gap-2 relative" v-for="(text, stat) of mainStatTexts">
|
||||||
<div class="sticky top-1 left-16 flex justify-between">
|
<div class="sticky top-1 mx-16 z-10 flex justify-between">
|
||||||
<div class="py-1 px-3 bg-light-0 dark:bg-dark-0 z-10 text-xl font-bold border border-light-30 dark:border-dark-30 flex">{{ text }}
|
<div class="py-1 px-3 bg-light-0 dark:bg-dark-0 z-10 text-xl font-bold border border-light-30 dark:border-dark-30 flex">{{ text }}
|
||||||
<div class="flex gap-2" v-if="maxTraining[stat] >= 0">: Niveau {{ maxTraining[stat] }} (+{{ modifiers[stat] }}
|
<div class="flex gap-2" v-if="maxTraining[stat] >= 0">: Niveau {{ maxTraining[stat] }} (+{{ modifiers[stat] }}
|
||||||
<NumberFieldRoot :default-value="data.progress.modifiers[stat] ?? 0" v-model="data.progress.modifiers[stat]" class="flex justify-center border border-light-35 dark:border-dark-35 bg-light-20 dark:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20 data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20
|
<NumberFieldRoot :default-value="data.progress.modifiers[stat] ?? 0" v-model="data.progress.modifiers[stat]" class="flex justify-center border border-light-35 dark:border-dark-35 bg-light-20 dark:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20 data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20
|
||||||
|
|
@ -312,9 +312,9 @@ useShortcuts({
|
||||||
<span class="text-xl -mx-2" :class="{ 'text-light-red dark:text-dark-red': (abilityPoints ?? 0) < abilitySpent }">Points d'entrainement restants: {{ (abilityPoints ?? 0) - abilitySpent }}</span>
|
<span class="text-xl -mx-2" :class="{ 'text-light-red dark:text-dark-red': (abilityPoints ?? 0) < abilitySpent }">Points d'entrainement restants: {{ (abilityPoints ?? 0) - abilitySpent }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid gap-4 grid-cols-6">
|
<div class="grid gap-4 grid-cols-6">
|
||||||
<div v-for="(ability, index) of characterConfig.ability" class="flex flex-col items-center border border-light-30 dark:border-dark-30 p-2">
|
<div v-for="(ability, index) of characterConfig.abilities" class="flex flex-col items-center border border-light-30 dark:border-dark-30 p-2">
|
||||||
<div class="flex items-center justify-center gap-4">
|
<div class="flex items-center justify-center gap-4">
|
||||||
<NumberFieldRoot :min="0" :max="abilityMax[index]" :default-value="data.progress.abilities[index] ? data.progress.abilities[index][0] : 0" @update:model-value="(value) => { data.progress.abilities[index] = [value, data.progress.abilities[index] ? data.progress.abilities[index][1] : 0]; }" class="border border-light-35 dark:border-dark-35 bg-light-20 dark:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20 data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20
|
<NumberFieldRoot :min="0" :default-value="data.progress.abilities[index] ? data.progress.abilities[index][0] : 0" @update:model-value="(value) => { data.progress.abilities[index] = [value, data.progress.abilities[index] ? data.progress.abilities[index][1] : 0]; }" class="border border-light-35 dark:border-dark-35 bg-light-20 dark:bg-dark-20 data-[disabled]:border-light-20 dark:data-[disabled]:border-dark-20 data-[disabled]:bg-light-20 dark:data-[disabled]:bg-dark-20
|
||||||
data-[disabled]:text-light-70 dark:data-[disabled]:text-dark-70 hover:border-light-50 dark:hover:border-dark-50 has-[:focus]:shadow-raw transition-[box-shadow] has-[:focus]:shadow-light-40 dark:has-[:focus]:shadow-dark-40">
|
data-[disabled]:text-light-70 dark:data-[disabled]:text-dark-70 hover:border-light-50 dark:hover:border-dark-50 has-[:focus]:shadow-raw transition-[box-shadow] has-[:focus]:shadow-light-40 dark:has-[:focus]:shadow-dark-40">
|
||||||
<NumberFieldInput class="tabular-nums w-8 bg-transparent px-3 py-1 outline-none caret-light-50 dark:caret-dark-50" />
|
<NumberFieldInput class="tabular-nums w-8 bg-transparent px-3 py-1 outline-none caret-light-50 dark:caret-dark-50" />
|
||||||
</NumberFieldRoot>
|
</NumberFieldRoot>
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const { data: character, status, error } = await useAsyncData(() => useRequestFe
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-1 px-8">
|
<div class="flex flex-1 px-8">
|
||||||
<div class="flex flex-col pe-8 gap-8 py-8 w-80">
|
<div class="flex flex-col pe-8 gap-4 py-8 w-80">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<span class="text-lg font-semibold border-b border-light-30 dark:border-dark-30">Maitrise d'arme</span>
|
<span class="text-lg font-semibold border-b border-light-30 dark:border-dark-30">Maitrise d'arme</span>
|
||||||
<div class="grid grid-cols-2 gap-x-3 gap-y-1">
|
<div class="grid grid-cols-2 gap-x-3 gap-y-1">
|
||||||
|
|
@ -96,10 +96,16 @@ const { data: character, status, error } = await useAsyncData(() => useRequestFe
|
||||||
<span>Sorts de savoir: <span class="font-bold">{{ character.spellranks.knowledge }}</span></span>
|
<span>Sorts de savoir: <span class="font-bold">{{ character.spellranks.knowledge }}</span></span>
|
||||||
<span>Sorts d'instinct: <span class="font-bold">{{ character.spellranks.instinct }}</span></span>
|
<span>Sorts d'instinct: <span class="font-bold">{{ character.spellranks.instinct }}</span></span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span class="text-lg font-semibold border-b border-light-30 dark:border-dark-30 mb-2 flex items-center gap-4">Résistances (Attaque/Défense) <Tooltip side="right" message="Les défenses affichées incluent déjà leur modifieur de statistique."><Icon icon="radix-icons:question-mark-circled" /></Tooltip></span>
|
||||||
|
<div class="grid grid-cols-3 gap-1">
|
||||||
|
<div class="flex flex-col px-2 items-center text-sm text-light-70 dark:text-dark-70" v-for="(value, resistance) of character.resistance"><span class="font-bold text-base text-light-100 dark:text-dark-100">+{{ value[0] }}/+{{ value[1] + character.modifier[config.resistances[resistance].statistic as MainStat] }}</span><span>{{ config.resistances[resistance].name }}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<span class="text-lg font-semibold border-b border-light-30 dark:border-dark-30 mb-2">Compétences</span>
|
<span class="text-lg font-semibold border-b border-light-30 dark:border-dark-30 mb-2">Compétences</span>
|
||||||
<div class="grid grid-cols-3 gap-1">
|
<div class="grid grid-cols-3 gap-1">
|
||||||
<div class="flex flex-col px-2 items-center" v-for="(value, ability) of character.abilities"><span class="font-bold">+{{ value }}</span><span>{{ config.ability[ability].name }}</span></div>
|
<div class="flex flex-col px-2 items-center text-sm text-light-70 dark:text-dark-70" v-for="(value, ability) of character.abilities"><span class="font-bold text-base text-light-100 dark:text-dark-100">+{{ value }}</span><span>{{ config.abilities[ability].name }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ function compileCharacter(character: Character & { username?: string }): Compile
|
||||||
health: raceOptions.reduce((p, v) => p + (v.health ?? 0), 0),
|
health: raceOptions.reduce((p, v) => p + (v.health ?? 0), 0),
|
||||||
mana: raceOptions.reduce((p, v) => p + (v.mana ?? 0), 0),
|
mana: raceOptions.reduce((p, v) => p + (v.mana ?? 0), 0),
|
||||||
race: character.progress.race.index ?? -1,
|
race: character.progress.race.index ?? -1,
|
||||||
modifier: features.map(e => [e[0], Math.floor(e[1].length / 3)] as [MainStat, number]).reduce((p, v) => { p[v[0]] = v[1]; return p }, {} as Record<MainStat, number>),
|
modifier: features.map(e => [e[0], Math.floor((e[1].length - 1) / 3) + (character.progress.modifiers[e[0]] ?? 0)] as [MainStat, number]).reduce((p, v) => { p[v[0]] = v[1]; return p }, {} as Record<MainStat, number>),
|
||||||
level: character.progress.level,
|
level: character.progress.level,
|
||||||
features: {
|
features: {
|
||||||
action: [],
|
action: [],
|
||||||
|
|
@ -154,10 +154,12 @@ function compileCharacter(character: Character & { username?: string }): Compile
|
||||||
deception: 0
|
deception: 0
|
||||||
},
|
},
|
||||||
spellslots: 0,
|
spellslots: 0,
|
||||||
|
artslots: 0,
|
||||||
spellranks: {
|
spellranks: {
|
||||||
instinct: 0,
|
instinct: 0,
|
||||||
knowledge: 0,
|
knowledge: 0,
|
||||||
precision: 0
|
precision: 0,
|
||||||
|
arts: 0,
|
||||||
},
|
},
|
||||||
speed: false,
|
speed: false,
|
||||||
defense: {
|
defense: {
|
||||||
|
|
@ -180,7 +182,7 @@ function compileCharacter(character: Character & { username?: string }): Compile
|
||||||
resistance: {
|
resistance: {
|
||||||
stun: [0, 0],
|
stun: [0, 0],
|
||||||
bleed: [0, 0],
|
bleed: [0, 0],
|
||||||
posion: [0, 0],
|
poison: [0, 0],
|
||||||
fear: [0, 0],
|
fear: [0, 0],
|
||||||
influence: [0, 0],
|
influence: [0, 0],
|
||||||
charm: [0, 0],
|
charm: [0, 0],
|
||||||
|
|
@ -211,6 +213,8 @@ function applyTrainingOption(stat: MainStat, option: TrainingOption, character:
|
||||||
if(option.spellrank) character.spellranks[option.spellrank]++;
|
if(option.spellrank) character.spellranks[option.spellrank]++;
|
||||||
if(option.defense) option.defense.forEach(e => character.defense[e]++);
|
if(option.defense) option.defense.forEach(e => character.defense[e]++);
|
||||||
if(option.resistance) option.resistance.forEach(e => character.resistance[e[0]][e[1] === "attack" ? 0 : 1]++);
|
if(option.resistance) option.resistance.forEach(e => character.resistance[e[0]][e[1] === "attack" ? 0 : 1]++);
|
||||||
|
if(option.spellslot) character.spellslots += option.spellslot in character.modifier ? character.modifier[option.spellslot as MainStat] : option.spellslot as number;
|
||||||
|
if(option.arts) character.artslots += option.arts in character.modifier ? character.modifier[option.arts as MainStat] : option.arts as number;
|
||||||
|
|
||||||
option.description.forEach(line => !line.disposable && (last || !line.replaced) && character.features[line.category ?? "misc"].push(line.text));
|
option.description.forEach(line => !line.disposable && (last || !line.replaced) && character.features[line.category ?? "misc"].push(line.text));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const transport = nodemailer.createTransport({
|
||||||
user: config.mail.user,
|
user: config.mail.user,
|
||||||
pass: config.mail.passwd,
|
pass: config.mail.passwd,
|
||||||
},
|
},
|
||||||
tls: { rejectUnauthorized: config.mail.port !== "465" },
|
tls: { rejectUnauthorized: false },
|
||||||
dkim: {
|
dkim: {
|
||||||
domainName: domain,
|
domainName: domain,
|
||||||
keySelector: selector,
|
keySelector: selector,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"ability": {
|
"abilities": {
|
||||||
"athletics": { "max": ["strength", "constitution"], "name": "Athlétisme", "description": "La capacité à effectuer un acte physique intense ou prolongé. Permet de pousser, contraindre, nager, courir." },
|
"athletics": { "max": ["strength", "constitution"], "name": "Athlétisme", "description": "La capacité à effectuer un acte physique intense ou prolongé. Permet de pousser, contraindre, nager, courir." },
|
||||||
"acrobatics": { "max": ["strength", "dexterity"], "name": "Acrobatique", "description": "La capacité à se mouvoir avec souplesse sous la contrainte. Permet d'escalader, d'enjamber, de sauter." },
|
"acrobatics": { "max": ["strength", "dexterity"], "name": "Acrobatique", "description": "La capacité à se mouvoir avec souplesse sous la contrainte. Permet d'escalader, d'enjamber, de sauter." },
|
||||||
"intimidation": { "max": ["strength", "charisma"], "name": "Intimidation", "description": "La capacité à intimider et inspirer la crainte." },
|
"intimidation": { "max": ["strength", "charisma"], "name": "Intimidation", "description": "La capacité à intimider et inspirer la crainte." },
|
||||||
|
|
@ -18,6 +18,18 @@
|
||||||
"animalhandling": { "max": ["charisma", "psyche"], "name": "Dressage", "description": "" },
|
"animalhandling": { "max": ["charisma", "psyche"], "name": "Dressage", "description": "" },
|
||||||
"deception": { "max": ["charisma", "psyche"], "name": "Mensonge", "description": "" }
|
"deception": { "max": ["charisma", "psyche"], "name": "Mensonge", "description": "" }
|
||||||
},
|
},
|
||||||
|
"resistances": {
|
||||||
|
"stun": { "name": "Hébètement", "statistic": "strength" },
|
||||||
|
"bleed": { "name": "Saignement", "statistic": "constitution" },
|
||||||
|
"poison": { "name": "Empoisonement", "statistic": "constitution" },
|
||||||
|
"fear": { "name": "Peur", "statistic": "psyche" },
|
||||||
|
"influence": { "name": "Influence", "statistic": "curiosity" },
|
||||||
|
"charm": { "name": "Charme", "statistic": "charisma" },
|
||||||
|
"possesion": { "name": "Possession", "statistic": "psyche" },
|
||||||
|
"precision": { "name": "Précision", "statistic": "dexterity" },
|
||||||
|
"knowledge": { "name": "Savoir", "statistic": "intelligence" },
|
||||||
|
"instinct": { "name": "Instinct", "statistic": "psyche" }
|
||||||
|
},
|
||||||
"peoples": [
|
"peoples": [
|
||||||
{
|
{
|
||||||
"name": "Humain",
|
"name": "Humain",
|
||||||
|
|
@ -26,26 +38,26 @@
|
||||||
"maxOption": 3
|
"maxOption": 3
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"1": [ { "training": 43, "health": 14 } ],
|
"1": [ { "training": 35, "health": 14 } ],
|
||||||
"2": [ { "training": 1, "health": 4, "mana": 2 }, { "spec": 1, "health": 4, "mana": 2 } ],
|
"2": [ { "training": 1, "health": 4, "mana": 2 }, { "health": 7, "mana": 4, "abilities": 1 } ],
|
||||||
"3": [ { "training": 1, "health": 4, "mana": 2 } ],
|
"3": [ { "training": 2, "health": 4, "mana": 2, "abilities": 1 } ],
|
||||||
"4": [ { "training": 1, "health": 4, "mana": 2 } ],
|
"4": [ { "training": 1, "health": 4, "mana": 2, "abilities": 2 } ],
|
||||||
"5": [ { "training": 1, "health": 6, "mana": 2 }, { "shaping": 1, "health": 8, "mana": 3 }, { "spec": 1, "health": 8, "mana": 3 } ],
|
"5": [ { "training": 1, "health": 6, "mana": 2, "abilities": 2 }, { "training": 1, "shaping": 1, "health": 9, "mana": 5 }, { "training": 2, "health": 8, "mana": 3 } ],
|
||||||
"6": [ { "training": 1, "health": 2, "mana": 2, "spec": 1 }, { "training": 2 } ],
|
"6": [ { "training": 1, "health": 3, "mana": 3 }, { "training": 1, "abilities": 3 } ],
|
||||||
"7": [ { "training": 1, "health": 4, "mana": 6 }, { "training": 1, "health": 6, "mana": 2 } ],
|
"7": [ { "training": 2, "health": 4, "mana": 6 }, { "training": 2, "health": 6, "mana": 2 } ],
|
||||||
"8": [ { "training": 1 }, { "health": 8, "mana": 8 } ],
|
"8": [ { "training": 3 }, { "training": 1, "health": 8, "mana": 8 } ],
|
||||||
"9": [ { "training": 1, "health": 4, "mana": 6 }, { "training": 1, "health": 6, "mana": 2 } ],
|
"9": [ { "training": 1, "health": 4, "mana": 6 }, { "training": 1, "health": 3, "mana": 1, "abilities": 2 } ],
|
||||||
"10": [ { "training": 2 }, { "training": 1, "shaping": 1 }, { "modifier": 1 } ],
|
"10": [ { "training": 2 }, { "training": 1, "shaping": 1, "abilities": 2 }, { "modifier": 1, "abilities": 1 } ],
|
||||||
"11": [ { "training": 1, "health": 8, "mana": 1 }, { "training": 1, "health": 3, "mana": 5 } ],
|
"11": [ { "training": 1, "health": 8, "mana": 1 }, { "training": 1, "health": 3, "mana": 5 }, { "training": 1, "abilities": 2 } ],
|
||||||
"12": [ { "training": 1, "health": 4, "mana": 2 }, { "training": 1, "health": 8 }, { "training": 1, "mana": 7 } ],
|
"12": [ { "training": 2, "health": 4, "mana": 2 }, { "training": 2, "health": 8 }, { "training": 2, "mana": 7 } ],
|
||||||
"13": [ { "spec": 1, "health": 2, "mana": 2 }, { "shaping": 1, "health": 2, "mana": 2 } ],
|
"13": [ { "training": 1, "health": 2, "mana": 2, "abilities": 1 }, { "training": 1, "shaping": 1, "health": 4, "mana": 4 } ],
|
||||||
"14": [ { "training": 1, "health": 4, "mana": 6 }, { "training": 1, "health": 6, "mana": 2 } ],
|
"14": [ { "training": 3, "health": 4, "mana": 4 }, { "training": 3, "health": 6, "mana": 2 } ],
|
||||||
"15": [ { "training": 1 }, { "health": 8, "mana": 8 } ],
|
"15": [ { "training": 1 }, { "health": 6, "mana": 6, "abilities": 1 } ],
|
||||||
"16": [ { "training": 1, "health": 4, "mana": 6 }, { "training": 1, "health": 6, "mana": 2 } ],
|
"16": [ { "training": 1, "health": 4, "mana": 6 }, { "training": 1, "health": 6, "mana": 2 } ],
|
||||||
"17": [ { "training": 1, "spec": 1 }, { "training": 1, "shaping": 1 }, { "training": 1, "health": 6, "mana": 4 } ],
|
"17": [ { "training": 2, "abilities": 1 }, { "training": 1, "shaping": 1, "abilities": 2 }, { "training": 1, "health": 6, "mana": 4, "abilities": 1 } ],
|
||||||
"18": [ { "training": 1, "health": 6, "mana": 1 }, { "training": 1, "health": 2, "mana": 5 } ],
|
"18": [ { "training": 1, "health": 6, "mana": 1 }, { "training": 1, "health": 2, "mana": 5 } ],
|
||||||
"19": [ { "training": 1, "health": 6, "mana": 2 }, { "training": 1, "health": 3, "mana": 5 } ],
|
"19": [ { "training": 2, "health": 6, "mana": 2, "abilities": 1 }, { "training": 2, "health": 3, "mana": 5, "abilities": 1 } ],
|
||||||
"20": [ { "training": 2 }, { "modifier": 1 } ]
|
"20": [ { "training": 2 }, { "modifier": 1, "abilities": 1 } ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -1771,6 +1783,15 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ability": 4
|
"ability": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"text": "+1 spécialisation.",
|
||||||
|
"disposable": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"spec": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"5": [
|
"5": [
|
||||||
|
|
@ -1809,39 +1830,6 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"6": [
|
"6": [
|
||||||
{
|
|
||||||
"description": [
|
|
||||||
{
|
|
||||||
"text": "À chaque augmentation de modifieur, vous pouvez ajouter 1 point à n'importe quel compétence dont le maximum a été augmenté.",
|
|
||||||
"disposable": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": [
|
|
||||||
{
|
|
||||||
"text": "En combat, vous pouvez lancer 2 [[1. Règles/99. Annexes/4. Équipement#Les armes de jet|armes de jet]] en 3 points d'action.",
|
|
||||||
"disposable": false,
|
|
||||||
"category": "action"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "+1 point de compétence.",
|
|
||||||
"disposable": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": [
|
|
||||||
{
|
|
||||||
"text": "+3 points de compétence.",
|
|
||||||
"disposable": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ability": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"7": [
|
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
|
|
@ -1858,10 +1846,20 @@
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
"text": "Lorsque vous utilisez un objet consommable, vous pouvez lancer un d12. Si vous faites 12, l'objet ne se consomme pas. Cela fonctionne également sur les objets à charges.",
|
"text": "En combat, vous pouvez lancer 2 [[1. Règles/99. Annexes/4. Équipement#Les armes de jet|armes de jet]] en 3 points d'action.",
|
||||||
|
"disposable": false,
|
||||||
|
"category": "action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Vous êtes capable de fabriquer des objets magiques d'une rareté accrue.",
|
||||||
"disposable": false
|
"disposable": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "+1 point de compétence.",
|
||||||
|
"disposable": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"ability": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
|
|
@ -1877,7 +1875,15 @@
|
||||||
"ability": 2
|
"ability": 2
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"8": [
|
"7": [
|
||||||
|
{
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"text": "Lorsque vous utilisez un objet consommable, vous pouvez lancer un d12. Si vous faites 12, l'objet ne se consomme pas. Cela fonctionne également sur les objets à charges.",
|
||||||
|
"disposable": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
|
|
@ -1886,6 +1892,17 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"text": "+1 spécialisation.",
|
||||||
|
"disposable": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"spec": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
|
|
@ -1897,22 +1914,24 @@
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
"text": "+4 points de compétence.",
|
"text": "+3 points de compétence.",
|
||||||
"disposable": true
|
"disposable": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ability": 4
|
"ability": 3
|
||||||
}
|
},
|
||||||
],
|
|
||||||
"9": [
|
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
"text": "",
|
"text": "Vous pouvez maitriser un nombre de [[1. Magie|sorts]] et d'[[7. Œuvres|œuvres]] supplémentaires égal à votre modifieur de curiosité.",
|
||||||
"disposable": false
|
"disposable": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
},
|
"spellslot": "curiosity",
|
||||||
|
"arts": "curiosity"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"9": [
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
|
|
@ -1950,22 +1969,14 @@
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
"text": "+4 points de compétence.",
|
"text": "+1 spécialisation.",
|
||||||
"disposable": true
|
"disposable": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ability": 4
|
"spec": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"11": [
|
"11": [
|
||||||
{
|
|
||||||
"description": [
|
|
||||||
{
|
|
||||||
"text": "",
|
|
||||||
"disposable": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
|
|
@ -2236,9 +2247,10 @@
|
||||||
"description": [
|
"description": [
|
||||||
{
|
{
|
||||||
"text": "Vous pouvez retenir un nombre d'œuvre supplémentaire égal à votre mod. de charisme.",
|
"text": "Vous pouvez retenir un nombre d'œuvre supplémentaire égal à votre mod. de charisme.",
|
||||||
"disposable": false
|
"disposable": true
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"arts": "charisma"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"8": [
|
"8": [
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ export type MainStat = "strength" | "dexterity" | "constitution" | "intelligence
|
||||||
export type Ability = "athletics" | "acrobatics" | "intimidation" | "sleightofhand" | "stealth" | "survival" | "investigation" | "history" | "religion" | "arcana" | "understanding" | "perception" | "performance" | "medecine" | "persuasion" | "animalhandling" | "deception";
|
export type Ability = "athletics" | "acrobatics" | "intimidation" | "sleightofhand" | "stealth" | "survival" | "investigation" | "history" | "religion" | "arcana" | "understanding" | "perception" | "performance" | "medecine" | "persuasion" | "animalhandling" | "deception";
|
||||||
export type Level = | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;
|
export type Level = | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;
|
||||||
export type TrainingLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
|
export type TrainingLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
|
||||||
export type SpellType = "precision" | "knowledge" | "instinct";
|
export type SpellType = "precision" | "knowledge" | "instinct" | "arts";
|
||||||
export type Category = "action" | "reaction" | "freeaction" | "misc";
|
export type Category = "action" | "reaction" | "freeaction" | "misc";
|
||||||
export type Resistance = keyof CompiledCharacter["resistance"];
|
export type Resistance = keyof CompiledCharacter["resistance"];
|
||||||
|
|
||||||
|
|
@ -30,13 +30,18 @@ export type Character = {
|
||||||
export type CharacterConfig = {
|
export type CharacterConfig = {
|
||||||
peoples: Race[],
|
peoples: Race[],
|
||||||
training: Record<MainStat, Record<TrainingLevel, TrainingOption[]>>;
|
training: Record<MainStat, Record<TrainingLevel, TrainingOption[]>>;
|
||||||
ability: Record<Ability, AbilityConfig>;
|
abilities: Record<Ability, AbilityConfig>;
|
||||||
|
resistances: Record<Resistance, ResistanceConfig>;
|
||||||
};
|
};
|
||||||
export type AbilityConfig = {
|
export type AbilityConfig = {
|
||||||
max: [MainStat, MainStat];
|
max: [MainStat, MainStat];
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
};
|
||||||
|
export type ResistanceConfig = {
|
||||||
|
name: string;
|
||||||
|
statistic: MainStat;
|
||||||
|
};
|
||||||
export type Race = {
|
export type Race = {
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
|
@ -49,9 +54,9 @@ export type RaceOption = {
|
||||||
training?: number;
|
training?: number;
|
||||||
health?: number;
|
health?: number;
|
||||||
mana?: number;
|
mana?: number;
|
||||||
spec?: number;
|
|
||||||
shaping?: number;
|
shaping?: number;
|
||||||
modifier?: number;
|
modifier?: number;
|
||||||
|
abilities?: number;
|
||||||
};
|
};
|
||||||
export type Feature = {
|
export type Feature = {
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|
@ -86,17 +91,24 @@ export type TrainingOption = {
|
||||||
replaced?: boolean;
|
replaced?: boolean;
|
||||||
category?: Category;
|
category?: Category;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
//Automatically calculated by compiler
|
||||||
mana?: number;
|
mana?: number;
|
||||||
health?: number;
|
health?: number;
|
||||||
modifier?: number;
|
|
||||||
ability?: number;
|
|
||||||
speed?: false | number;
|
speed?: false | number;
|
||||||
initiative?: number;
|
initiative?: number;
|
||||||
mastery?: keyof CompiledCharacter["mastery"];
|
mastery?: keyof CompiledCharacter["mastery"];
|
||||||
spellrank?: SpellType;
|
spellrank?: SpellType;
|
||||||
spellslot?: number | MainStat;
|
|
||||||
defense?: Array<keyof CompiledCharacter["defense"]>;
|
defense?: Array<keyof CompiledCharacter["defense"]>;
|
||||||
resistance?: [Resistance, "attack" | "defense"][];
|
resistance?: [Resistance, "attack" | "defense"][];
|
||||||
|
|
||||||
|
//Used during character creation, not used by compiler
|
||||||
|
modifier?: number;
|
||||||
|
ability?: number;
|
||||||
|
spec?: number;
|
||||||
|
spellslot?: number | MainStat;
|
||||||
|
arts?: number | MainStat;
|
||||||
|
|
||||||
features?: Feature[]; //TODO
|
features?: Feature[]; //TODO
|
||||||
};
|
};
|
||||||
export type CompiledCharacter = {
|
export type CompiledCharacter = {
|
||||||
|
|
@ -108,6 +120,7 @@ export type CompiledCharacter = {
|
||||||
mana: number;
|
mana: number;
|
||||||
race: number;
|
race: number;
|
||||||
spellslots: number;
|
spellslots: number;
|
||||||
|
artslots: number;
|
||||||
spellranks: Record<SpellType, 0 | 1 | 2 | 3>;
|
spellranks: Record<SpellType, 0 | 1 | 2 | 3>;
|
||||||
aspect: string;
|
aspect: string;
|
||||||
speed: number | false;
|
speed: number | false;
|
||||||
|
|
@ -135,7 +148,7 @@ export type CompiledCharacter = {
|
||||||
resistance: { //First is attack, second is defense
|
resistance: { //First is attack, second is defense
|
||||||
stun: [number, number];
|
stun: [number, number];
|
||||||
bleed: [number, number];
|
bleed: [number, number];
|
||||||
posion: [number, number];
|
poison: [number, number];
|
||||||
fear: [number, number];
|
fear: [number, number];
|
||||||
influence: [number, number];
|
influence: [number, number];
|
||||||
charm: [number, number];
|
charm: [number, number];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue