112 lines
4.9 KiB
Vue
112 lines
4.9 KiB
Vue
|
|
<template>
|
||
|
|
<div class="h-full flex flex-col p-4 gap-4 bg-[#1b1026] overflow-y-auto custom-scrollbar">
|
||
|
|
<!-- Pet Avatar -->Portrait & Basic Info -->
|
||
|
|
<PixelFrame class="flex-shrink-0" title="PET INFO">
|
||
|
|
<!-- Helper Buttons Overlay -->
|
||
|
|
<div class="absolute top-1 right-1 z-30">
|
||
|
|
<button
|
||
|
|
@click="$emit('openAchievements')"
|
||
|
|
class="p-1 bg-[#2b193f] border border-[#f6b26b] hover:bg-[#3d2459] active:translate-y-0.5 group"
|
||
|
|
title="Achievements"
|
||
|
|
>
|
||
|
|
<Trophy :size="14" class="text-[#f6b26b] group-hover:text-white" />
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="flex flex-col items-center p-1 relative">
|
||
|
|
<div class="w-20 h-20 bg-[#1b1026] border-4 border-[#4a3b5e] mb-2 relative overflow-hidden group shadow-inner flex items-center justify-center">
|
||
|
|
<!-- Background for portrait -->
|
||
|
|
<div class="absolute inset-0 bg-[#2b193f] opacity-50" />
|
||
|
|
|
||
|
|
<!-- The Animated Pixel Avatar -->
|
||
|
|
<div class="scale-110 transform translate-y-1">
|
||
|
|
<PixelAvatar
|
||
|
|
skinColor="#ffdbac"
|
||
|
|
hairColor="#e0d8f0"
|
||
|
|
outfitColor="#9fd75b"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Scanline on portrait -->
|
||
|
|
<div class="absolute inset-0 bg-[linear-gradient(rgba(0,0,0,0)_50%,rgba(0,0,0,0.2)_50%)] bg-[length:100%_4px] pointer-events-none z-20" />
|
||
|
|
</div>
|
||
|
|
<h2 class="text-xl text-[#f6b26b] tracking-[0.2em] font-bold border-b-2 border-[#f6b26b] mb-1 leading-none pb-1">{{ stats.name }}</h2>
|
||
|
|
<span class="text-xs text-[#8f80a0] uppercase tracking-wide">{{ stats.class }}</span>
|
||
|
|
</div>
|
||
|
|
</PixelFrame>
|
||
|
|
|
||
|
|
<!-- Vitals - Updated to Health, Hunger, Happiness -->
|
||
|
|
<div class="flex flex-col gap-1 px-1">
|
||
|
|
<RetroResourceBar :current="stats.hp" :max="stats.maxHp" type="hp" label="Health" :icon="Heart" />
|
||
|
|
<RetroResourceBar v-if="stats.hunger !== undefined" :current="stats.hunger" :max="stats.maxHunger || 100" type="energy" label="Hunger" :icon="Drumstick" />
|
||
|
|
<RetroResourceBar v-if="stats.happiness !== undefined" :current="stats.happiness" :max="stats.maxHappiness || 100" type="mana" label="Happy" :icon="Smile" />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Pet Details Grid -->
|
||
|
|
<PixelFrame class="flex-shrink-0 mt-1" variant="inset">
|
||
|
|
<div class="grid grid-cols-2 gap-x-2 gap-y-2 text-[10px] uppercase text-[#8f80a0]">
|
||
|
|
<div class="flex flex-col border-r border-[#4a3b5e] pr-1">
|
||
|
|
<span class="text-[#4a3b5e]">Age</span>
|
||
|
|
<span class="text-[#e0d8f0] font-mono tracking-wide">{{ stats.age }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="flex flex-col pl-1">
|
||
|
|
<span class="text-[#4a3b5e]">Gen</span>
|
||
|
|
<span class="text-[#e0d8f0] font-mono tracking-wide">{{ stats.generation }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="flex items-center gap-1 border-t border-[#4a3b5e] pt-1 col-span-2">
|
||
|
|
<Ruler :size="10" />
|
||
|
|
<span class="text-[#e0d8f0]">{{ stats.height }}</span>
|
||
|
|
<span class="text-[#4a3b5e] mx-1">|</span>
|
||
|
|
<Scale :size="10" />
|
||
|
|
<span class="text-[#e0d8f0]">{{ stats.weight }}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</PixelFrame>
|
||
|
|
|
||
|
|
<!-- Fate & God Favor -->
|
||
|
|
<div class="flex flex-col gap-2 mt-2 px-1">
|
||
|
|
<!-- Fate -->
|
||
|
|
<div v-if="stats.fate" class="flex items-center gap-2 bg-[#2b193f] p-1 border border-[#4a3b5e] rounded">
|
||
|
|
<Leaf :size="12" color="#99e550" />
|
||
|
|
<div class="flex flex-col leading-none">
|
||
|
|
<span class="text-[8px] text-[#8f80a0] uppercase">Fate</span>
|
||
|
|
<span class="text-[10px] text-[#e0d8f0] tracking-wide">{{ stats.fate }}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- God Favor -->
|
||
|
|
<div v-if="stats.godFavor" class="flex flex-col gap-1">
|
||
|
|
<div class="flex justify-between text-[10px] text-[#8f80a0] uppercase">
|
||
|
|
<span>Favor: {{ stats.godFavor.name }}</span>
|
||
|
|
<span>{{ stats.godFavor.current }}/{{ stats.godFavor.max }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="h-2 bg-[#150c1f] border border-[#4a3b5e] rounded-full overflow-hidden">
|
||
|
|
<div :style="{ width: `${(stats.godFavor.current / stats.godFavor.max) * 100}%` }" class="h-full bg-[#f6b26b]" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Gold -->
|
||
|
|
<div class="mt-auto px-1 pb-1">
|
||
|
|
<RetroCounter :icon="Coins" :value="stats.gold || 0" color="#ffe762" />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { Ruler, Scale, Heart, Smile, Drumstick, Coins, Leaf, Trophy } from 'lucide-vue-next';
|
||
|
|
import PixelFrame from './PixelFrame.vue';
|
||
|
|
import RetroResourceBar from './RetroResourceBar.vue';
|
||
|
|
import RetroCounter from './RetroCounter.vue';
|
||
|
|
import PixelAvatar from './PixelAvatar.vue';
|
||
|
|
import type { EntityStats } from '~/types/pixel';
|
||
|
|
|
||
|
|
interface Props {
|
||
|
|
stats: EntityStats;
|
||
|
|
}
|
||
|
|
|
||
|
|
defineProps<Props>();
|
||
|
|
defineEmits(['openAchievements']);
|
||
|
|
</script>
|