Item Improvements added to the homebrew manager.

This commit is contained in:
2026-06-08 16:53:54 +02:00
parent 3bafc14255
commit f9e0473b2a
11 changed files with 204 additions and 99 deletions

View File

@@ -33,7 +33,7 @@
</NavigationMenuTrigger>
<NavigationMenuContent class="absolute top-0 w-full sm:w-auto bg-light-0 dark:bg-dark-0 border border-light-30 dark:border-dark-30 py-2 z-20 flex flex-col">
<NuxtLink :href="{ name: 'character-list' }" class="hover:bg-light-30 dark:hover:bg-dark-30 px-4 py-2 select-none" active-class="!text-accent-blue"><span class="flex-1 truncate">Personnages publics</span></NuxtLink>
<NuxtLink :href="{ name: 'character-id-edit', params: { id: 'new' } }" class="hover:bg-light-30 dark:hover:bg-dark-30 px-4 py-2 select-none" active-class="!text-accent-blue"><span class="flex-1 truncate">Nouveau personnage</span></NuxtLink>
<NuxtLink :href="{ name: 'character-id', params: { id: 'new' } }" class="hover:bg-light-30 dark:hover:bg-dark-30 px-4 py-2 select-none" active-class="!text-accent-blue"><span class="flex-1 truncate">Nouveau personnage</span></NuxtLink>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>

View File

@@ -1,28 +0,0 @@
<script setup lang="ts">
import { CharacterBuilder } from '~~/shared/character';
import { unifySlug } from '~~/shared/general';
definePageMeta({
requiresAuth: true,
validState: true,
});
const id = unifySlug(useRouter().currentRoute.value.params.id ?? "new");
const container = useTemplateRef('container');
onMounted(() => {
queueMicrotask(() => {
if(container.value)
{
const builder = new CharacterBuilder(container.value, id === 'new' ? undefined : id);
useShortcuts({
"Meta_S": () => builder.save(false),
});
}
});
})
</script>
<template>
<div class="flex flex-1 max-w-full flex-col align-center" ref="container"></div>
</template>

View File

@@ -55,7 +55,7 @@ async function duplicateCharacter(id: number)
</div>
</NuxtLink>
<div class="flex justify-around items-center py-2 px-4 gap-4">
<NuxtLink :to="{ name: 'character-id-edit', params: { id: character.id } }" class="text-sm font-bold cursor-pointer hover:text-accent-blue">Editer</NuxtLink>
<NuxtLink :to="{ name: 'character-id', params: { id: character.id } }" class="text-sm font-bold cursor-pointer hover:text-accent-blue">Editer</NuxtLink>
<span class="w-px h-full bg-light-50 dark:bg-dark-50"></span>
<NuxtLink @click="duplicateCharacter(character.id)" class="text-sm font-bold cursor-pointer hover:text-accent-blue">Dupliquer</NuxtLink>
<span class="w-px h-full bg-light-50 dark:bg-dark-50"></span>
@@ -83,7 +83,7 @@ async function duplicateCharacter(id: number)
<NuxtLink v-if="user && user.state === 1" class="inline-flex justify-center items-center outline-none leading-none transition-[box-shadow]
text-light-100 dark:text-dark-100 bg-light-20 dark:bg-dark-20 border border-light-40 dark:border-dark-40
hover:bg-light-25 dark:hover:bg-dark-25 hover:border-light-50 dark:hover:border-dark-50
focus:bg-light-30 dark:focus:bg-dark-30 focus:border-light-50 dark:focus:border-dark-50 focus:shadow-raw focus:shadow-light-50 dark:focus:shadow-dark-50 py-2 px-4" :to="{ name: 'character-id-edit', params: { id: 'new' } }">Nouveau personnage</NuxtLink>
focus:bg-light-30 dark:focus:bg-dark-30 focus:border-light-50 dark:focus:border-dark-50 focus:shadow-raw focus:shadow-light-50 dark:focus:shadow-dark-50 py-2 px-4" :to="{ name: 'character-id', params: { id: 'new' } }">Nouveau personnage</NuxtLink>
<div v-else>Veuillez validez votre adresse mail pour pouvoir créer des personnages.</div>
<NuxtLink class="inline-flex justify-center items-center outline-none leading-none transition-[box-shadow]
text-light-100 dark:text-dark-100 bg-light-20 dark:bg-dark-20 border border-light-40 dark:border-dark-40

View File

@@ -41,7 +41,7 @@ const { user } = useUserSession();
<NuxtLink class="inline-flex justify-center items-center outline-none leading-none transition-[box-shadow]
text-light-100 dark:text-dark-100 bg-light-20 dark:bg-dark-20 border border-light-40 dark:border-dark-40
hover:bg-light-25 dark:hover:bg-dark-25 hover:border-light-50 dark:hover:border-dark-50
focus:bg-light-30 dark:focus:bg-dark-30 focus:border-light-50 dark:focus:border-dark-50 focus:shadow-raw focus:shadow-light-50 dark:focus:shadow-dark-50 py-2 px-4" :to="{ name: 'character-id-edit', params: { id: 'new' } }">Nouveau personnage</NuxtLink>
focus:bg-light-30 dark:focus:bg-dark-30 focus:border-light-50 dark:focus:border-dark-50 focus:shadow-raw focus:shadow-light-50 dark:focus:shadow-dark-50 py-2 px-4" :to="{ name: 'character-id', params: { id: 'new' } }">Nouveau personnage</NuxtLink>
</template>
<div v-else>Veuillez valider votre adresse mail pour pouvoir créer des personnages.</div>
</div>

View File

@@ -1,4 +1,4 @@
import type { MAIN_STATS, ABILITIES, LEVELS, TRAINING_LEVELS, SPELL_TYPES, CATEGORIES, SPELL_ELEMENTS, ALIGNMENTS, RESISTANCES, DAMAGE_TYPES, WEAPON_TYPES, PropertySum, ITEM_BUFFER_KEYS } from "#shared/character";
import type { MAIN_STATS, ABILITIES, LEVELS, TRAINING_LEVELS, SPELL_TYPES, CATEGORIES, SPELL_ELEMENTS, ALIGNMENTS, RESISTANCES, DAMAGE_TYPES, WEAPON_TYPES, CRAFTING_TYPES, PropertySum, ITEM_BUFFER_KEYS } from "#shared/character";
import type { Localized } from "../types/general";
export type MainStat = typeof MAIN_STATS[number];
@@ -12,6 +12,7 @@ export type Alignment = typeof ALIGNMENTS[number];
export type Resistance = typeof RESISTANCES[number];
export type DamageType = typeof DAMAGE_TYPES[number];
export type WeaponType = typeof WEAPON_TYPES[number];
export type CraftingType = typeof CRAFTING_TYPES[number];
export type FeatureID = string;
export type FeatureEffectID = string;
@@ -56,8 +57,9 @@ export type CharacterVariables = {
spells: string[]; //Spell ID
items: ItemState[];
money: number;
components: { money: number, natural: number, mineral: number, processed: number, magical: number };
transformed: boolean;
craft?: { item: string, progress: number };
};
export type TreeLeaf = {
id: FeatureID;
@@ -81,7 +83,7 @@ type MundaneState = { };
type ItemState = {
id: string;
amount: number;
enchantments?: string[];
improvements?: string[];
charges?: number;
equipped?: boolean;
state?: (ArmorState | WeaponState | WondrousState | MundaneState) & CommonState;
@@ -93,7 +95,7 @@ export type CharacterConfig = {
spells: Record<string, SpellConfig>;
aspects: Record<string, AspectConfig>;
features: Record<FeatureID, Feature>;
enchantments: Record<string, EnchantementConfig>;
improvements: Record<string, ImprovementConfig>;
items: Record<string, ItemConfig>;
action: Record<string, { id: string, name: string, description: string, cost?: number, variants?: string[], parent?: string }>;
reaction: Record<string, { id: string, name: string, description: string, cost?: number, variants?: string[], parent?: string }>;
@@ -107,13 +109,15 @@ export type CharacterConfig = {
poison: Record<FeatureID, { name: string, difficulty: number, efficienty: number, solubility: number }>; //TODO
dedication: Record<FeatureID, { name: string, requirement: Array<{ stat: MainStat, amount: number }> }>; //TODO
};
export type EnchantementConfig = {
export type ImprovementConfig = {
id: string;
name: string; //TODO -> TextID
description: i18nID;
rarity: 'common' | 'uncommon' | 'rare' | 'veryrare' | 'legendary';
effect: Array<FeatureEquipment | FeatureValue | FeatureList>;
power: number;
restrictions?: Array<'armor' | 'mundane' | 'wondrous' | 'weapon' | `armor/${ArmorConfig['type']}` | `weapon/${WeaponConfig['type'][number]}`>; // Need to respect *any* of the restriction, not every restrictions.
craft: { difficulty?: number, ability?: CraftingType };
restrictions?: Partial<Record<'armor' | 'mundane' | 'wondrous' | 'weapon' | `armor/${ArmorConfig['type']}` | `weapon/${WeaponConfig['type'][number]}` | string, boolean>>; // Need to respect *any* of the restriction, not every restrictions.
cursed: boolean;
}
export type ItemConfig = CommonItemConfig & (ArmorConfig | WeaponConfig | WondrousConfig | MundaneConfig);
@@ -122,18 +126,18 @@ type CommonItemConfig = {
name: string; //TODO -> TextID
flavoring?: i18nID;
description: i18nID;
rarity: 'common' | 'uncommon' | 'rare' | 'legendary';
rarity: 'common' | 'uncommon' | 'rare' | 'veryrare' | 'legendary';
weight?: number; //Optionnal but highly recommended
price?: number; //Optionnal but highly recommended
capacity?: number; //Optionnal as most mundane items should not receive enchantments (potions, herbal heals, etc...)
capacity?: number; //Optionnal as most mundane items should not receive improvements (potions, herbal heals, etc...)
powercost?: number; //Optionnal
charge?: number //Max amount of charges
enchantments?: string[]; //Enchantment ID
improvements?: string[]; //Improvement ID
effects?: Array<FeatureValue | FeatureState | FeatureEquipment | FeatureList>;
equippable: boolean;
consummable: boolean;
craft?: { mineral: number, natural: number, processed: number, magical: number };
//variants?: string[];
craft: { mineral: number, natural: number, processed: number, magical: number, difficulty?: number, ability?: CraftingType };
variants?: string[]; //ID array
};
type ArmorConfig = {
category: 'armor';