diff --git a/src/components/game/tabs/EquipmentTab.tsx b/src/components/game/tabs/EquipmentTab.tsx index d089f5c..cb3dbb5 100755 --- a/src/components/game/tabs/EquipmentTab.tsx +++ b/src/components/game/tabs/EquipmentTab.tsx @@ -103,8 +103,20 @@ export function EquipmentTab({ store }: EquipmentTabProps) { return unequippedItems.filter((inst) => typeIds.has(inst.typeId)); }; + // Check if a slot is blocked by a 2-handed weapon + const isSlotBlocked = (slot: EquipmentSlot): boolean => { + if (slot === 'offHand' && store.equippedInstances.mainHand) { + const mainHandType = EQUIPMENT_TYPES[store.equippedInstances.mainHand]; + return mainHandType?.twoHanded === true; + } + return false; + }; + // Get all items that can go in a slot (including accessories that can go in either accessory slot) const getItemsForSlot = (slot: EquipmentSlot): EquipmentInstance[] => { + // Don't show items for blocked slots + if (isSlotBlocked(slot)) return []; + if (slot === 'accessory1' || slot === 'accessory2') { // Accessories can go in either slot const accessoryTypes = EQUIPMENT_TYPES; @@ -114,6 +126,15 @@ export function EquipmentTab({ store }: EquipmentTabProps) { return unequippedItems.filter((inst) => accessoryTypeIds.includes(inst.typeId)); } + + // For offhand, don't show 2-handed weapons (they can only go in main hand) + if (slot === 'offHand') { + return getEquippableItems(slot).filter((inst) => { + const type = EQUIPMENT_TYPES[inst.typeId]; + return !type?.twoHanded; + }); + } + return getEquippableItems(slot); }; @@ -132,24 +153,34 @@ export function EquipmentTab({ store }: EquipmentTabProps) { const instanceId = store.equippedInstances[slot]; const instance = instanceId ? store.equipmentInstances[instanceId] : null; const equipmentType = instance ? EQUIPMENT_TYPES[instance.typeId] : null; + const blocked = isSlotBlocked(slot); return (
{SLOT_ICONS[slot]} - + {SLOT_NAMES[slot]} + {blocked && ( + + Blocked + + )}
- {instance && ( + {instance && !blocked && (
+ ) : blocked ? ( +
+ Blocked by 2-handed weapon +
) : (
Empty diff --git a/src/lib/game/crafting-slice.ts b/src/lib/game/crafting-slice.ts index f81c79a..0fcf802 100755 --- a/src/lib/game/crafting-slice.ts +++ b/src/lib/game/crafting-slice.ts @@ -1,8 +1,8 @@ // ─── Crafting Store Slice ───────────────────────────────────────────────────────── // Handles equipment and enchantment system: design, prepare, apply stages -import type { GameState, EquipmentInstance, AppliedEnchantment, EnchantmentDesign, DesignEffect, EquipmentSlot, EquipmentCraftingProgress, LootInventory, AttunementState } from './types'; -import { EQUIPMENT_TYPES, type EquipmentCategory } from './data/equipment'; +import type { GameState, EquipmentInstance, AppliedEnchantment, EnchantmentDesign, DesignEffect, EquipmentCraftingProgress, LootInventory, AttunementState } from './types'; +import { EQUIPMENT_TYPES, type EquipmentCategory, type EquipmentSlot } from './data/equipment'; import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from './data/enchantment-effects'; import { CRAFTING_RECIPES, canCraftRecipe, type CraftingRecipe } from './data/crafting-recipes'; import { SPELLS_DEF } from './constants'; @@ -221,6 +221,34 @@ export function createCraftingSlice( const currentEquipped = state.equippedInstances[slot]; if (currentEquipped === instanceId) return true; // Already equipped here + // 2-handed weapon checks + const isTwoHanded = type.twoHanded === true; + + if (isTwoHanded) { + // Cannot equip 2-handed weapon if main hand or offhand is occupied + if (state.equippedInstances.mainHand || state.equippedInstances.offHand) { + return false; + } + // 2-handed weapons can only be equipped to main hand + if (slot !== 'mainHand') return false; + } + + // If equipping to main hand, check if a 2-handed weapon is in main hand (block offhand) + if (slot === 'offHand' && state.equippedInstances.mainHand) { + const mainHandType = EQUIPMENT_TYPES[state.equippedInstances.mainHand]; + if (mainHandType?.twoHanded) { + return false; // Cannot equip offhand when 2-handed weapon is equipped + } + } + + // If equipping to offhand, check if a 2-handed weapon is in main hand + if (slot === 'offHand' && state.equippedInstances.mainHand) { + const mainHandType = EQUIPMENT_TYPES[state.equippedInstances.mainHand]; + if (mainHandType?.twoHanded) { + return false; // Cannot equip offhand when 2-handed weapon is in main hand + } + } + // If this item is equipped elsewhere, unequip it first let newEquipped = { ...state.equippedInstances }; for (const [s, id] of Object.entries(newEquipped)) { @@ -232,6 +260,11 @@ export function createCraftingSlice( // Equip to new slot newEquipped[slot] = instanceId; + // If 2-handed weapon, also clear offhand slot (should already be null from check above) + if (isTwoHanded && slot === 'mainHand') { + newEquipped.offHand = null; + } + set(() => ({ equippedInstances: newEquipped })); return true; }, diff --git a/src/lib/game/data/equipment.ts b/src/lib/game/data/equipment.ts index 7a4a329..efc32c2 100755 --- a/src/lib/game/data/equipment.ts +++ b/src/lib/game/data/equipment.ts @@ -15,6 +15,7 @@ export interface EquipmentType { description: string; baseDamage?: number; // For swords baseCastSpeed?: number; // For swords (higher = faster) + twoHanded?: boolean; // If true, weapon occupies both main hand and offhand slots } // ─── Equipment Types Definition ───────────────────────────────────────────── @@ -28,6 +29,7 @@ export const EQUIPMENT_TYPES: Record = { slot: 'mainHand', baseCapacity: 50, description: 'A simple wooden staff, basic but reliable for channeling mana.', + twoHanded: true, }, apprenticeWand: { id: 'apprenticeWand', @@ -44,6 +46,7 @@ export const EQUIPMENT_TYPES: Record = { slot: 'mainHand', baseCapacity: 65, description: 'A sturdy oak staff with decent mana capacity.', + twoHanded: true, }, crystalWand: { id: 'crystalWand', @@ -60,6 +63,7 @@ export const EQUIPMENT_TYPES: Record = { slot: 'mainHand', baseCapacity: 80, description: 'A staff designed for advanced spellcasters. High capacity for complex enchantments.', + twoHanded: true, }, battlestaff: { id: 'battlestaff', @@ -68,6 +72,7 @@ export const EQUIPMENT_TYPES: Record = { slot: 'mainHand', baseCapacity: 70, description: 'A reinforced staff suitable for both casting and combat.', + twoHanded: true, }, // ─── Main Hand - Catalysts ──────────────────────────────────────────────── @@ -438,6 +443,7 @@ export function getAllEquipmentTypes(): EquipmentType[] { } // Get valid slots for a category +// Note: For 2-handed weapons, use getValidSlotsForEquipmentType instead export function getValidSlotsForCategory(category: EquipmentCategory): EquipmentSlot[] { switch (category) { case 'caster': @@ -461,6 +467,17 @@ export function getValidSlotsForCategory(category: EquipmentCategory): Equipment } } +// Get valid slots for a specific equipment type (considers 2-handed weapons) +export function getValidSlotsForEquipmentType(equipType: EquipmentType): EquipmentSlot[] { + // 2-handed weapons occupy both main hand and offhand + if (equipType.twoHanded) { + return ['mainHand', 'offHand']; + } + + // Otherwise use category-based slots + return getValidSlotsForCategory(equipType.category); +} + // Check if an equipment type can be equipped in a specific slot export function canEquipInSlot(equipmentType: EquipmentType, slot: EquipmentSlot): boolean { const validSlots = getValidSlotsForCategory(equipmentType.category);