pet_data/app/components/pixel/InventoryOverlay.vue

493 lines
28 KiB
Vue
Raw Normal View History

2025-11-26 06:53:44 +00:00
<template>
2025-11-27 08:42:55 +00:00
<div class="flex flex-col h-full gap-2 overflow-visible">
2025-11-26 06:53:44 +00:00
2025-11-26 15:31:46 +00:00
<!-- 1. 已装备装备栏 -->
2025-11-27 08:42:55 +00:00
<div class="grid grid-cols-2 md:grid-cols-3 gap-2 overflow-visible">
<div v-for="(slotConfig, key) in EQUIPMENT_SLOTS" :key="key" class="border border-[#4a3b5e] bg-[#0f0816] p-2 flex flex-col gap-2 overflow-visible">
2025-11-26 15:31:46 +00:00
<!-- 装备槽标题 -->
<div class="flex items-center gap-2 justify-center border-b border-[#2b193f] pb-1">
<component :is="SLOT_ICONS[key]" :size="14" class="text-[#8f80a0]" />
<span class="text-[#2ce8f4] text-xs font-bold uppercase">{{ slotConfig.name }}</span>
2025-11-26 06:53:44 +00:00
</div>
2025-11-26 15:31:46 +00:00
<!-- 实际装备槽 -->
2025-11-27 08:42:55 +00:00
<div class="bg-[#150c1f] border border-[#4a3b5e] p-2 min-h-[40px] flex flex-col items-center justify-center relative">
2025-11-26 15:31:46 +00:00
<span class="text-[9px] text-[#8f80a0] mb-1">装备</span>
2025-11-27 08:42:55 +00:00
<button
v-if="getEquippedItem(key, false)"
class="flex flex-col items-center gap-1 hover:bg-[#321e4a] transition-all p-1 rounded w-full"
@mouseenter="onEquippedItemMouseEnter(`${key}-equipment`)"
@mouseleave="onItemMouseLeave"
>
2025-11-26 15:31:46 +00:00
<div class="relative w-8 h-8">
<PixelItemIcon :category="getEquippedItem(key, false)!.category" :color="ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.color" />
</div>
<span class="text-xs text-center truncate w-full px-1 font-bold" :style="{ color: ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.color }">{{ getEquippedItem(key, false)!.name }}</span>
2025-11-27 08:42:55 +00:00
<!-- 懸浮卡片 -->
<div
v-show="hoveredEquippedSlot === `${key}-equipment`"
@mouseenter="onTooltipMouseEnter"
@mouseleave="onTooltipMouseLeave"
class="absolute top-full left-1/2 -translate-x-1/2 mt-2 px-4 py-3 bg-[#0f0816] border-2 border-[#4a3b5e] rounded-sm shadow-xl pointer-events-auto z-[100] w-72 text-left max-h-[400px] overflow-y-auto custom-scrollbar"
>
<!-- 物品头部 -->
<div class="flex gap-3 mb-3 pb-3 border-b border-[#4a3b5e]">
<div class="w-16 h-16 bg-[#1b1026] border-2 rounded flex items-center justify-center p-2 flex-shrink-0"
:style="{ borderColor: ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.color }">
<PixelItemIcon
:category="getEquippedItem(key, false)!.category"
:color="ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.color"
/>
</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-bold mb-1"
:style="{ color: ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.color }">
{{ getEquippedItem(key, false)!.name }}
</div>
<div class="flex gap-2 text-[10px] flex-wrap">
<span class="px-2 py-0.5 bg-[#1b1026] border border-[#4a3b5e] rounded text-[#8f80a0]">
{{ getItemTypeName(getEquippedItem(key, false)!.type) }}
</span>
<span class="px-2 py-0.5 border rounded font-bold"
:style="{
borderColor: ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.color,
color: ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.color
}">
{{ ITEM_RARITY[getEquippedItem(key, false)!.rarity]?.name }}
</span>
</div>
</div>
</div>
<!-- 描述 -->
<p class="text-[11px] text-[#e0d8f0] italic mb-3 leading-relaxed">
"{{ getEquippedItem(key, false)!.description }}"
</p>
<!-- 效果 -->
<div v-if="getEquippedItem(key, false)!.effects" class="mb-3 space-y-1">
<div class="text-[10px] text-[#99e550] font-bold mb-1">效果</div>
<div v-if="getEquippedItem(key, false)!.effects.flat" class="space-y-1">
<div v-for="(val, effectKey) in getEquippedItem(key, false)!.effects.flat" :key="effectKey"
class="text-[10px] text-[#9fd75b] flex justify-between border-b border-[#2b193f] border-dashed pb-1">
<span class="text-[#8f80a0]">{{ formatBuffKey(effectKey) }}</span>
<span class="font-mono font-bold">+{{ val }}</span>
</div>
</div>
<div v-if="getEquippedItem(key, false)!.effects.percent" class="space-y-1 mt-1">
<div v-for="(val, effectKey) in getEquippedItem(key, false)!.effects.percent" :key="effectKey"
class="text-[10px] text-[#2ce8f4] flex justify-between border-b border-[#2b193f] border-dashed pb-1">
<span class="text-[#8f80a0]">{{ formatBuffKey(effectKey) }}</span>
<span class="font-mono font-bold">+{{ (val * 100).toFixed(0) }}%</span>
</div>
</div>
</div>
<!-- 卸下按钮 -->
<div class="space-y-2 pt-2 border-t border-[#4a3b5e]">
<button
@click.stop="$emit('unequip', key, false)"
class="w-full px-3 py-2 bg-[#8f80a0] text-[#1b1026] rounded text-xs font-bold hover:bg-[#a598b8] transition-colors"
>
卸下裝備
</button>
</div>
</div>
</button>
2025-11-26 15:31:46 +00:00
<span v-else class="text-[10px] text-[#4a3b5e] z-10 opacity-50"></span>
2025-11-26 06:53:44 +00:00
</div>
2025-11-26 15:31:46 +00:00
<!-- 外观槽 -->
2025-11-27 08:42:55 +00:00
<div class="bg-[#150c1f] border border-[#4a3b5e] p-2 min-h-[40px] flex flex-col items-center justify-center relative">
2025-11-26 15:31:46 +00:00
<span class="text-[9px] text-[#8f80a0] mb-1">外觀</span>
2025-11-27 08:42:55 +00:00
<button
v-if="getEquippedItem(key, true)"
class="flex flex-col items-center gap-1 hover:bg-[#321e4a] transition-all p-1 rounded w-full"
@mouseenter="onEquippedItemMouseEnter(`${key}-appearance`)"
@mouseleave="onItemMouseLeave"
>
2025-11-26 15:31:46 +00:00
<div class="relative w-8 h-8">
<PixelItemIcon :category="getEquippedItem(key, true)!.category" :color="ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.color" />
</div>
<span class="text-xs text-center truncate w-full px-1 font-bold" :style="{ color: ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.color }">{{ getEquippedItem(key, true)!.name }}</span>
2025-11-27 08:42:55 +00:00
<!-- 懸浮卡片 -->
<div
v-show="hoveredEquippedSlot === `${key}-appearance`"
@mouseenter="onTooltipMouseEnter"
@mouseleave="onTooltipMouseLeave"
class="absolute top-full left-1/2 -translate-x-1/2 mt-2 px-4 py-3 bg-[#0f0816] border-2 border-[#4a3b5e] rounded-sm shadow-xl pointer-events-auto z-[100] w-72 text-left max-h-[400px] overflow-y-auto custom-scrollbar"
>
<!-- 物品头部 -->
<div class="flex gap-3 mb-3 pb-3 border-b border-[#4a3b5e]">
<div class="w-16 h-16 bg-[#1b1026] border-2 rounded flex items-center justify-center p-2 flex-shrink-0"
:style="{ borderColor: ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.color }">
<PixelItemIcon
:category="getEquippedItem(key, true)!.category"
:color="ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.color"
/>
</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-bold mb-1"
:style="{ color: ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.color }">
{{ getEquippedItem(key, true)!.name }}
</div>
<div class="flex gap-2 text-[10px] flex-wrap">
<span class="px-2 py-0.5 bg-[#1b1026] border border-[#4a3b5e] rounded text-[#8f80a0]">
{{ getItemTypeName(getEquippedItem(key, true)!.type) }}
</span>
<span class="px-2 py-0.5 border rounded font-bold"
:style="{
borderColor: ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.color,
color: ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.color
}">
{{ ITEM_RARITY[getEquippedItem(key, true)!.rarity]?.name }}
</span>
</div>
</div>
</div>
<!-- 描述 -->
<p class="text-[11px] text-[#e0d8f0] italic mb-3 leading-relaxed">
"{{ getEquippedItem(key, true)!.description }}"
</p>
<!-- 卸下按钮 -->
<div class="space-y-2 pt-2 border-t border-[#4a3b5e]">
<button
@click.stop="$emit('unequip', key, true)"
class="w-full px-3 py-2 bg-[#d584fb] text-[#1b1026] rounded text-xs font-bold hover:bg-[#e5a4ff] transition-colors"
>
卸下外觀
</button>
</div>
</div>
</button>
2025-11-26 15:31:46 +00:00
<span v-else class="text-[10px] text-[#4a3b5e] z-10 opacity-50"></span>
2025-11-26 06:53:44 +00:00
</div>
</div>
</div>
2025-11-27 08:42:55 +00:00
<!-- 2. 背包区域 - 固定高度 + 滚动 -->
<div class="flex-grow overflow-visible mt-2">
2025-11-26 15:31:46 +00:00
<PixelFrame class="h-full flex flex-col bg-[#1b1026]" :title="`背包 (${items.filter(i => !i.isEquipped).length})`">
2025-11-27 08:42:55 +00:00
<div class="overflow-y-auto overflow-x-visible p-3 custom-scrollbar" style="height: 400px;">
2025-11-26 15:31:46 +00:00
<div class="grid grid-cols-6 gap-2">
2025-11-27 08:42:55 +00:00
<!-- 动态格子数量基础30格有道具时自动扩展 -->
<div v-for="index in totalSlots" :key="index" class="relative aspect-square">
2025-11-26 15:31:46 +00:00
<!-- 有物品显示物品 + 悬浮卡片 -->
<template v-if="getInventorySlotItem(index - 1)">
2025-11-27 08:42:55 +00:00
<button
class="w-full h-full p-2 flex flex-col items-center justify-center gap-1 border-2 transition-all group rounded-sm border-[#4a3b5e] hover:border-[#8f80a0] hover:bg-[#321e4a] bg-[#2b193f]"
@mouseenter="onItemMouseEnter(index - 1)"
@mouseleave="onItemMouseLeave"
>
2025-11-26 15:31:46 +00:00
<div class="relative w-10 h-10">
<PixelItemIcon
:category="getInventorySlotItem(index - 1).category"
:color="ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color"
/>
<!-- 稀有度发光 -->
<div
v-if="['rare', 'epic', 'legendary'].includes(getInventorySlotItem(index - 1).rarity)"
class="absolute inset-0 rounded-full opacity-40 blur-md pointer-events-none"
:style="{ backgroundColor: ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color }"
></div>
<span
v-if="getInventorySlotItem(index - 1).quantity && getInventorySlotItem(index - 1).quantity > 1"
class="absolute -bottom-1 -right-1 text-[9px] bg-black text-white px-1 border border-[#4a3b5e] rounded-sm z-10 shadow-sm font-mono"
>{{ getInventorySlotItem(index - 1).quantity }}</span>
</div>
<span
class="text-[10px] text-center leading-tight line-clamp-2 w-full font-medium relative z-10"
:style="{
color: ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color,
textShadow: ['rare', 'epic', 'legendary'].includes(getInventorySlotItem(index - 1).rarity)
? `0 0 3px ${ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color}80`
: 'none'
}"
>{{ getInventorySlotItem(index - 1).name }}</span>
<!-- 详细悬浮卡片 -->
2025-11-27 08:42:55 +00:00
<div
v-show="hoveredItemIndex === index - 1"
@mouseenter="onTooltipMouseEnter"
@mouseleave="onTooltipMouseLeave"
class="absolute top-full left-1/2 -translate-x-1/2 mt-2 px-4 py-3 bg-[#0f0816] border-2 border-[#4a3b5e] rounded-sm shadow-xl pointer-events-auto z-[100] w-72 text-left max-h-[400px] overflow-y-auto custom-scrollbar"
>
2025-11-26 15:31:46 +00:00
<!-- 物品头部 -->
<div class="flex gap-3 mb-3 pb-3 border-b border-[#4a3b5e]">
<div class="w-16 h-16 bg-[#1b1026] border-2 rounded flex items-center justify-center p-2 flex-shrink-0"
:style="{ borderColor: ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color }">
<PixelItemIcon
:category="getInventorySlotItem(index - 1).category"
:color="ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color"
/>
</div>
<div class="flex-1 min-w-0">
<div class="text-sm font-bold mb-1"
:style="{ color: ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color }">
{{ getInventorySlotItem(index - 1).name }}
</div>
<div class="flex gap-2 text-[10px] flex-wrap">
<span class="px-2 py-0.5 bg-[#1b1026] border border-[#4a3b5e] rounded text-[#8f80a0]">
{{ getItemTypeName(getInventorySlotItem(index - 1).type) }}
</span>
<span class="px-2 py-0.5 border rounded font-bold"
:style="{
borderColor: ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color,
color: ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.color
}">
{{ ITEM_RARITY[getInventorySlotItem(index - 1).rarity]?.name }}
</span>
</div>
</div>
</div>
<!-- 描述 -->
<p class="text-[11px] text-[#e0d8f0] italic mb-3 leading-relaxed">
"{{ getInventorySlotItem(index - 1).description }}"
</p>
<!-- 效果 -->
<div v-if="getInventorySlotItem(index - 1).effects" class="mb-3 space-y-1">
<div class="text-[10px] text-[#99e550] font-bold mb-1">效果</div>
<div v-if="getInventorySlotItem(index - 1).effects.flat" class="space-y-1">
<div v-for="(val, key) in getInventorySlotItem(index - 1).effects.flat" :key="key"
class="text-[10px] text-[#9fd75b] flex justify-between border-b border-[#2b193f] border-dashed pb-1">
<span class="text-[#8f80a0]">{{ formatBuffKey(key) }}</span>
<span class="font-mono font-bold">+{{ val }}</span>
</div>
</div>
<div v-if="getInventorySlotItem(index - 1).effects.percent" class="space-y-1 mt-1">
<div v-for="(val, key) in getInventorySlotItem(index - 1).effects.percent" :key="key"
class="text-[10px] text-[#2ce8f4] flex justify-between border-b border-[#2b193f] border-dashed pb-1">
<span class="text-[#8f80a0]">{{ formatBuffKey(key) }}</span>
<span class="font-mono font-bold">+{{ (val * 100).toFixed(0) }}%</span>
</div>
</div>
</div>
<!-- 耐久度 -->
<div v-if="getInventorySlotItem(index - 1).maxDurability && getInventorySlotItem(index - 1).maxDurability !== Infinity" class="mb-3">
<div class="flex justify-between text-[10px] text-[#8f80a0] mb-1">
<span>耐久度</span>
<span class="font-mono">{{ getInventorySlotItem(index - 1).durability }} / {{ getInventorySlotItem(index - 1).maxDurability }}</span>
</div>
<div class="h-1.5 w-full bg-[#1b1026] border border-[#4a3b5e] rounded-full overflow-hidden">
<div class="h-full bg-[#f6b26b] transition-all"
:style="{ width: `${(getInventorySlotItem(index - 1).durability / getInventorySlotItem(index - 1).maxDurability) * 100}%` }">
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="space-y-2 pt-2 border-t border-[#4a3b5e]">
<!-- 装备按钮 -->
<button
v-if="getInventorySlotItem(index - 1).slot && getInventorySlotItem(index - 1).type !== ItemType.Appearance"
@click.stop="$emit('equip', getInventorySlotItem(index - 1).id, false)"
class="w-full px-3 py-2 bg-[#9fd75b] text-[#1b1026] rounded text-xs font-bold hover:bg-[#b5e87b] transition-colors"
>
裝備
</button>
<!-- 外观按钮 -->
<button
v-if="getInventorySlotItem(index - 1).type === ItemType.Appearance"
@click.stop="$emit('equip', getInventorySlotItem(index - 1).id, true)"
class="w-full px-3 py-2 bg-[#d584fb] text-[#1b1026] rounded text-xs font-bold hover:bg-[#e5a4ff] transition-colors"
>
裝備外觀
</button>
<!-- 使用按钮 -->
<button
v-if="getInventorySlotItem(index - 1).type === ItemType.Consumable"
@click.stop="$emit('use', getInventorySlotItem(index - 1).id)"
class="w-full px-3 py-2 bg-[#2ce8f4] text-[#1b1026] rounded text-xs font-bold hover:bg-[#5cf4ff] transition-colors"
>
使用物品
</button>
<!-- 修理按钮 -->
<button
v-if="getInventorySlotItem(index - 1).maxDurability && getInventorySlotItem(index - 1).maxDurability !== Infinity && getInventorySlotItem(index - 1).durability < getInventorySlotItem(index - 1).maxDurability"
@click.stop="$emit('repair', getInventorySlotItem(index - 1).id)"
class="w-full px-3 py-2 bg-[#f6b26b] text-[#1b1026] rounded text-xs font-bold hover:bg-[#ffc68b] transition-colors flex items-center justify-center gap-2"
>
<Hammer :size="12" />
修理 ({{ Math.ceil((getInventorySlotItem(index - 1).maxDurability - getInventorySlotItem(index - 1).durability) * 0.5) }} G)
</button>
<!-- 删除按钮 -->
<button
@click.stop="$emit('delete', getInventorySlotItem(index - 1).id)"
class="w-full px-3 py-2 bg-[#d95763] text-white rounded text-xs font-bold hover:bg-[#ff6b7a] transition-colors flex items-center justify-center gap-2"
>
<Trash2 :size="12" />
丟棄
</button>
</div>
</div>
</button>
</template>
<!-- 空格子占位符 -->
<div
v-else
class="w-full h-full border-2 border-[#2b193f] bg-[#150c1f] rounded-sm flex items-center justify-center opacity-30"
>
<div class="w-8 h-8 border border-[#2b193f] rounded opacity-20"></div>
2025-11-26 06:53:44 +00:00
</div>
2025-11-26 15:31:46 +00:00
</div>
2025-11-26 06:53:44 +00:00
</div>
</div>
</PixelFrame>
</div>
2025-11-26 15:31:46 +00:00
2025-11-26 06:53:44 +00:00
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
2025-11-26 15:31:46 +00:00
import { Sword, Shield, Crown, Gem, Sparkles, Star, HelpCircle, Trash2, X, Hammer } from 'lucide-vue-next';
2025-11-26 06:53:44 +00:00
import PixelFrame from './PixelFrame.vue';
import PixelButton from './PixelButton.vue';
2025-11-26 15:31:46 +00:00
import PixelItemIcon from './PixelItemIcon.vue';
import { formatBuffKey } from '../../utils/formatters.js';
2025-11-26 09:53:03 +00:00
2025-11-26 15:31:46 +00:00
import { ITEM_TYPE, ITEM_RARITY, EQUIPMENT_SLOTS, ITEM_TYPES } from '../../../../data/items.js';
2025-11-26 09:53:03 +00:00
// Use any types since we're using data directly
type Item = any;
2025-11-26 06:53:44 +00:00
interface Props {
items: Item[];
}
const props = defineProps<Props>();
2025-11-26 15:31:46 +00:00
defineEmits(['equip', 'unequip', 'use', 'delete', 'repair']);
2025-11-26 06:53:44 +00:00
const selectedItemId = ref<string | null>(null);
2025-11-27 08:42:55 +00:00
const hoveredItemIndex = ref<number | null>(null);
const hoveredEquippedSlot = ref<string | null>(null); // 新增:用於追蹤裝備槽的懸浮狀態
const isHoveringTooltip = ref<boolean>(false);
const hideTooltipTimeout = ref<number | null>(null);
2025-11-26 06:53:44 +00:00
const selectedItem = computed(() => props.items.find(i => i.id === selectedItemId.value));
2025-11-27 08:42:55 +00:00
// 计算总格子数量基础30格有道具时自动扩展
const totalSlots = computed(() => {
const unequippedItems = props.items.filter(i => !i.isEquipped);
const minSlots = 30;
const itemCount = unequippedItems.length;
// 如果道具數量超過30則自動擴展到下一個6的倍數
if (itemCount > minSlots) {
return Math.ceil(itemCount / 6) * 6;
}
return minSlots;
});
2025-11-26 15:31:46 +00:00
const setSelectedItemId = (id: string | undefined) => {
if (id) selectedItemId.value = id;
};
2025-11-27 08:42:55 +00:00
// 處理裝備槽的滑鼠進入事件
const onEquippedItemMouseEnter = (slotKey: string) => {
// 清除任何待處理的隱藏 timeout
if (hideTooltipTimeout.value) {
clearTimeout(hideTooltipTimeout.value);
hideTooltipTimeout.value = null;
}
// 設置當前懸停的裝備槽
hoveredEquippedSlot.value = slotKey;
// 清除背包道具的懸停狀態
hoveredItemIndex.value = null;
};
// 處理背包道具的滑鼠進入事件
const onItemMouseEnter = (itemIndex: number) => {
// 清除任何待處理的隱藏 timeout
if (hideTooltipTimeout.value) {
clearTimeout(hideTooltipTimeout.value);
hideTooltipTimeout.value = null;
}
// 設置當前懸停的道具索引
hoveredItemIndex.value = itemIndex;
// 清除裝備槽的懸停狀態
hoveredEquippedSlot.value = null;
};
const onItemMouseLeave = () => {
// 清除之前的timeout如果有
if (hideTooltipTimeout.value) {
clearTimeout(hideTooltipTimeout.value);
}
// 延遲較長時間再檢查給使用者足夠時間移動到tooltip上
hideTooltipTimeout.value = setTimeout(() => {
if (!isHoveringTooltip.value) {
hoveredItemIndex.value = null;
hoveredEquippedSlot.value = null;
}
}, 300); // 增加到 300ms
};
const onTooltipMouseEnter = () => {
// 取消隱藏的timeout
if (hideTooltipTimeout.value) {
clearTimeout(hideTooltipTimeout.value);
hideTooltipTimeout.value = null;
}
isHoveringTooltip.value = true;
};
const onTooltipMouseLeave = () => {
// 滑鼠離開 tooltip立即隱藏
isHoveringTooltip.value = false;
hoveredItemIndex.value = null;
hoveredEquippedSlot.value = null;
if (hideTooltipTimeout.value) {
clearTimeout(hideTooltipTimeout.value);
hideTooltipTimeout.value = null;
}
};
2025-11-26 09:53:03 +00:00
// Map data constants to local helpers for template compatibility
const ItemType = {
Equipment: ITEM_TYPE.EQUIPMENT,
Consumable: ITEM_TYPE.CONSUMABLE,
Talisman: ITEM_TYPE.TALISMAN,
Special: ITEM_TYPE.SPECIAL,
Appearance: ITEM_TYPE.APPEARANCE
};
2025-11-26 15:31:46 +00:00
const SLOT_ICONS: Record<string, any> = {
weapon: Sword,
armor: Shield,
hat: Crown,
accessory: Gem,
talisman: Sparkles,
special: Star,
2025-11-26 09:53:03 +00:00
};
2025-11-26 15:31:46 +00:00
const getEquippedItem = (slot: string, isAppearance: boolean) => {
return props.items.find(i => i.isEquipped && i.slot === slot && !!i.isAppearance === isAppearance);
2025-11-26 06:53:44 +00:00
};
2025-11-26 15:31:46 +00:00
const getInventorySlotItem = (index: number) => {
const unequippedItems = props.items.filter(i => !i.isEquipped);
return unequippedItems[index] || null;
2025-11-26 06:53:44 +00:00
};
2025-11-26 15:31:46 +00:00
const getItemTypeName = (type: string) => {
return ITEM_TYPES[type]?.name || type;
2025-11-26 06:53:44 +00:00
};
</script>