/** * Galaxy Strike Online - Item System * Centralized item management for shop, inventory, dungeons, and all game systems */ class ItemSystem { constructor() { // Server configuration - will be set dynamically this.serverUrl = process.env.SERVER_URL || 'http://localhost:3002'; // Master item catalog - single source of truth this.itemCatalog = { // Ships ships: [ { id: 'starter_cruiser_common', name: 'Starter Cruiser', type: 'ship', rarity: 'common', price: 5000, currency: 'credits', description: 'Reliable starter cruiser for new pilots', texturePath: 'images/ships/starter_cruiser_common.png', stats: { attack: 15, speed: 10, defense: 12, hull: 100 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 1 }, stackable: false }, { id: 'starter_cruiser_uncommon', name: 'Starter Cruiser II', type: 'ship', rarity: 'uncommon', price: 12000, currency: 'credits', description: 'Upgraded starter cruiser with enhanced systems', texturePath: 'images/ships/starter_cruiser_uncommon.png', stats: { attack: 18, speed: 12, defense: 15, hull: 120 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 5 }, stackable: false }, { id: 'starter_cruiser_rare', name: 'Starter Cruiser III', type: 'ship', rarity: 'rare', price: 25000, currency: 'credits', description: 'Elite starter cruiser with maximum upgrades', texturePath: 'images/ships/starter_cruiser_rare.png', stats: { attack: 22, speed: 15, defense: 18, hull: 150 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 10 }, stackable: false }, { id: 'interceptor_common', name: 'Interceptor', type: 'ship', rarity: 'common', price: 8000, currency: 'credits', description: 'Fast attack ship for hit-and-run tactics', texturePath: 'images/ships/interceptor_common.png', stats: { attack: 12, speed: 18, defense: 8, hull: 80 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 3 }, stackable: false }, { id: 'interceptor_uncommon', name: 'Interceptor II', type: 'ship', rarity: 'uncommon', price: 18000, currency: 'credits', description: 'Enhanced interceptor with improved weapons', texturePath: 'images/ships/interceptor_uncommon.png', stats: { attack: 15, speed: 22, defense: 10, hull: 95 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 7 }, stackable: false } ], // Materials materials: [ { id: 'steel_plating', name: 'Steel Plating', type: 'material', rarity: 'common', price: 100, currency: 'credits', description: 'Basic armor material for ship upgrades', texture: 'http://localhost:3002/images/items/materials/steel_plating.png', categories: ['shop', 'dungeon_loot', 'crafting'], requirements: { level: 1 }, stackable: true, maxStack: 99, effects: { defense: 5 } }, { id: 'energy_core', name: 'Energy Core', type: 'material', rarity: 'uncommon', price: 250, currency: 'credits', description: 'Power source for advanced upgrades', texture: 'http://localhost:3002/images/items/materials/energy_crystal.png', categories: ['shop', 'dungeon_loot', 'crafting'], requirements: { level: 5 }, stackable: true, maxStack: 50, effects: { energy: 10 } }, { id: 'quantum_fuel', name: 'Quantum Fuel', type: 'material', rarity: 'rare', price: 500, currency: 'credits', description: 'Advanced fuel for long-range travel', texture: 'http://localhost:3002/images/items/materials/quantum_core.png', categories: ['shop', 'dungeon_loot', 'crafting'], requirements: { level: 10 }, stackable: true, maxStack: 25, effects: { speed: 15 } }, { id: 'dark_matter', name: 'Dark Matter', type: 'material', rarity: 'legendary', price: 2000, currency: 'gems', description: 'Exotic matter for ultimate upgrades', texture: 'http://localhost:3002/images/items/materials/dark_matter_fragment.png', categories: ['shop', 'dungeon_loot', 'crafting'], requirements: { level: 15 }, stackable: true, maxStack: 10, effects: { attack: 20, defense: 20 } } ], // Consumables consumables: [ { id: 'repair_kit', name: 'Repair Kit', type: 'consumable', rarity: 'common', price: 50, currency: 'credits', description: 'Instantly repairs ship damage', texture: 'http://localhost:3002/images/items/consumables/repair_kit.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 1 }, stackable: true, maxStack: 20, effects: { hull_repair: 50 }, consumable: true, cooldown: 30000 // 30 seconds }, { id: 'energy_boost', name: 'Energy Boost', type: 'consumable', rarity: 'common', price: 75, currency: 'credits', description: 'Temporary energy increase', texture: 'http://localhost:3002/images/items/consumables/energy_boost.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 1 }, stackable: true, maxStack: 15, effects: { energy_boost: 25, duration: 60000 }, // 1 minute consumable: true, cooldown: 45000 // 45 seconds }, { id: 'shield_booster', name: 'Shield Booster', type: 'consumable', rarity: 'uncommon', price: 150, currency: 'credits', description: 'Temporary shield enhancement', texture: 'http://localhost:3002/images/items/consumables/shield_recharge.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 5 }, stackable: true, maxStack: 10, effects: { shield_boost: 50, duration: 90000 }, // 1.5 minutes consumable: true, cooldown: 60000 // 1 minute }, { id: 'damage_amplifier', name: 'Damage Amplifier', type: 'consumable', rarity: 'rare', price: 300, currency: 'credits', description: 'Increases damage output temporarily', texture: 'http://localhost:3002/images/items/consumables/ammo_pack.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 8 }, stackable: true, maxStack: 5, effects: { damage_multiplier: 1.5, duration: 45000 }, // 45 seconds consumable: true, cooldown: 120000 // 2 minutes } ], // Cosmetics cosmetics: [ { id: 'red_paint', name: 'Red Paint Job', type: 'cosmetic', rarity: 'common', price: 500, currency: 'credits', description: 'Red color scheme for your ship', texture: 'http://localhost:3002/images/items/cosmetics/cool_paint_job.png', categories: ['shop'], requirements: { level: 1 }, stackable: false, cosmetic: true, slot: 'paint' }, { id: 'blue_paint', name: 'Blue Paint Job', type: 'cosmetic', rarity: 'common', price: 500, currency: 'credits', description: 'Blue color scheme for your ship', texture: 'http://localhost:3002/images/items/cosmetics/neon_lights.png', categories: ['shop'], requirements: { level: 1 }, stackable: false, cosmetic: true, slot: 'paint' }, { id: 'gold_trim', name: 'Gold Trim', type: 'cosmetic', rarity: 'uncommon', price: 1000, currency: 'credits', description: 'Gold accent trim for your ship', texture: 'http://localhost:3002/images/items/cosmetics/golden_trim.png', categories: ['shop'], requirements: { level: 5 }, stackable: false, cosmetic: true, slot: 'trim' }, { id: 'rainbow_effect', name: 'Rainbow Engine Effect', type: 'cosmetic', rarity: 'rare', price: 2500, currency: 'credits', description: 'Colorful engine trail effect', texture: 'http://localhost:3002/images/items/cosmetics/custom_decal.png', categories: ['shop'], requirements: { level: 10 }, stackable: false, cosmetic: true, slot: 'engine' } ], // Weapons weapons: [ { id: 'laser_cannon_common', name: 'Laser Cannon', type: 'weapon', rarity: 'common', price: 1000, currency: 'credits', description: 'Basic laser weapon for beginners', texture: 'http://localhost:3002/images/weapons/laser_pistol_common.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 1 }, stackable: false, stats: { attack: 10, range: 100, fire_rate: 2 } }, { id: 'plasma_rifle_uncommon', name: 'Plasma Rifle', type: 'weapon', rarity: 'uncommon', price: 2500, currency: 'credits', description: 'Plasma-based weapon with increased damage', texture: 'http://localhost:3002/images/weapons/plasma_rifle_uncommon.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 5 }, stackable: false, stats: { attack: 18, range: 120, fire_rate: 1.5 } }, { id: 'quantum_blaster_rare', name: 'Quantum Blaster', type: 'weapon', rarity: 'rare', price: 6000, currency: 'credits', description: 'Advanced quantum weapon with high damage output', texture: 'http://localhost:3002/images/weapons/plasma_rifle_rare.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 10 }, stackable: false, stats: { attack: 30, range: 150, fire_rate: 1 } } ], // Armors armors: [ { id: 'basic_shield_common', name: 'Basic Shield Generator', type: 'armor', rarity: 'common', price: 800, currency: 'credits', description: 'Basic shield protection for beginners', texture: 'http://localhost:3002/images/armors/light_armor_common.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 1 }, stackable: false, stats: { defense: 8, shield_capacity: 50, recharge_rate: 5 } }, { id: 'energy_armor_uncommon', name: 'Energy Armor', type: 'armor', rarity: 'uncommon', price: 2000, currency: 'credits', description: 'Energy-based armor with enhanced protection', texture: 'http://localhost:3002/images/armors/light_armor_uncommon.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 5 }, stackable: false, stats: { defense: 15, shield_capacity: 100, recharge_rate: 8 } }, { id: 'quantum_deflector_rare', name: 'Quantum Deflector', type: 'armor', rarity: 'rare', price: 5000, currency: 'credits', description: 'Advanced quantum armor with maximum protection', texture: 'http://localhost:3002/images/armors/light_armor_rare.png', categories: ['shop', 'dungeon_loot'], requirements: { level: 10 }, stackable: false, stats: { defense: 25, shield_capacity: 200, recharge_rate: 12 } } ], // Dungeon-specific rewards dungeon_rewards: [ { id: 'dungeon_key_basic', name: 'Basic Dungeon Key', type: 'key', rarity: 'common', price: 200, currency: 'credits', description: 'Key to enter basic dungeons', categories: ['shop', 'dungeon_loot'], requirements: { level: 1 }, stackable: true, maxStack: 10, consumable: true, dungeon_access: ['basic_dungeon', 'mines'] }, { id: 'dungeon_key_advanced', name: 'Advanced Dungeon Key', type: 'key', rarity: 'uncommon', price: 800, currency: 'credits', description: 'Key to enter advanced dungeons', categories: ['shop', 'dungeon_loot'], requirements: { level: 8 }, stackable: true, maxStack: 5, consumable: true, dungeon_access: ['advanced_dungeon', 'fortress'] }, { id: 'treasure_chest', name: 'Treasure Chest', type: 'container', rarity: 'rare', price: 0, currency: 'credits', description: 'Contains random valuable items', categories: ['dungeon_loot'], requirements: { level: 1 }, stackable: true, maxStack: 5, consumable: true, loot_table: 'treasure_chest_common' } ] }; // Initialize item lookup maps for performance this.itemLookup = new Map(); this.categoryLookup = new Map(); this.rarityLookup = new Map(); this.buildLookupMaps(); } /** * Build lookup maps for efficient item retrieval */ buildLookupMaps() { // Build ID lookup for (const [category, items] of Object.entries(this.itemCatalog)) { for (const item of items) { this.itemLookup.set(item.id, item); // Build category lookup if (!this.categoryLookup.has(category)) { this.categoryLookup.set(category, []); } this.categoryLookup.get(category).push(item); // Build rarity lookup if (!this.rarityLookup.has(item.rarity)) { this.rarityLookup.set(item.rarity, []); } this.rarityLookup.get(item.rarity).push(item); } } } /** * Get item by ID */ getItem(itemId) { return this.itemLookup.get(itemId) || null; } /** * Get all items in a category */ getItemsByCategory(category) { return this.categoryLookup.get(category) || []; } /** * Get items by rarity */ getItemsByRarity(rarity) { return this.rarityLookup.get(rarity) || []; } /** * Get items available for specific context (shop, dungeon, etc.) */ getItemsByContext(context) { const results = []; for (const item of this.itemLookup.values()) { if (item.categories && item.categories.includes(context)) { results.push(item); } } return results; } /** * Get shop items (items available in shop) */ getShopItems() { return this.getItemsByContext('shop'); } /** * Get dungeon loot items */ getDungeonLootItems() { return this.getItemsByContext('dungeon_loot'); } /** * Get dungeon reward items */ getDungeonRewardItems() { return this.getItemsByContext('dungeon_reward'); } /** * Get crafting materials */ getCraftingMaterials() { return this.getItemsByContext('crafting'); } /** * Check if player meets item requirements */ canPlayerUseItem(playerData, item) { if (!item.requirements) return true; // Check level requirement if (item.requirements.level && playerData.stats.level < item.requirements.level) { return false; } // Add other requirement checks here (skills, quests, etc.) return true; } /** * Get filtered items for player (based on requirements) */ getAvailableItemsForPlayer(playerData, context = null) { let items = context ? this.getItemsByContext(context) : Array.from(this.itemLookup.values()); return items.filter(item => this.canPlayerUseItem(playerData, item)); } /** * Generate random loot based on rarity weights */ generateLoot(rarityWeights = null, context = null) { const defaultWeights = { common: 50, uncommon: 30, rare: 15, legendary: 5 }; const weights = rarityWeights || defaultWeights; const availableItems = context ? this.getItemsByContext(context) : Array.from(this.itemLookup.values()); // Filter by rarity weights const weightedItems = []; for (const item of availableItems) { const weight = weights[item.rarity] || 0; for (let i = 0; i < weight; i++) { weightedItems.push(item); } } if (weightedItems.length === 0) return null; // Random selection const randomIndex = Math.floor(Math.random() * weightedItems.length); return weightedItems[randomIndex]; } /** * Get item statistics */ getItemStats() { const stats = { totalItems: this.itemLookup.size, byCategory: {}, byRarity: {}, byType: {} }; for (const item of this.itemLookup.values()) { // Count by category for (const category of item.categories || []) { stats.byCategory[category] = (stats.byCategory[category] || 0) + 1; } // Count by rarity stats.byRarity[item.rarity] = (stats.byRarity[item.rarity] || 0) + 1; // Count by type stats.byType[item.type] = (stats.byType[item.type] || 0) + 1; } return stats; } /** * Validate item data structure */ validateItem(item) { const required = ['id', 'name', 'type', 'rarity']; const missing = required.filter(field => !item[field]); if (missing.length > 0) { return { valid: false, errors: [`Missing required fields: ${missing.join(', ')}`] }; } const errors = []; // Validate type if (!['ship', 'material', 'consumable', 'cosmetic', 'key', 'container'].includes(item.type)) { errors.push(`Invalid item type: ${item.type}`); } // Validate rarity if (!['common', 'uncommon', 'rare', 'legendary'].includes(item.rarity)) { errors.push(`Invalid rarity: ${item.rarity}`); } // Validate stackable items if (item.stackable && (!item.maxStack || item.maxStack < 1)) { errors.push('Stackable items must have maxStack >= 1'); } return { valid: errors.length === 0, errors }; } /** * Set server URL dynamically */ setServerUrl(url) { this.serverUrl = url; console.log(`[ITEM SYSTEM] Server URL set to: ${this.serverUrl}`); } /** * Process item to add full texture URL */ processItem(item) { const processedItem = { ...item }; // Add full texture URL if texturePath exists if (item.texturePath) { processedItem.texture = `${this.serverUrl}/${item.texturePath}`; } // Fallback to old texture field if exists else if (item.texture) { processedItem.texture = item.texture; } // Default placeholder else { processedItem.texture = `${this.serverUrl}/images/ui/placeholder.png`; } return processedItem; } /** * Get items with processed URLs */ getItemsByType(type) { const items = this.itemCatalog[type] || []; return items.map(item => this.processItem(item)); } /** * Get all items with processed URLs */ getAllItems() { const allItems = {}; Object.keys(this.itemCatalog).forEach(type => { allItems[type] = this.getItemsByType(type); }); return allItems; } /** * Get random shop items with processed URLs */ getRandomShopItems(count = 8) { const allItems = Object.values(this.itemCatalog).flat(); const selectedItems = []; // Randomly select items const shuffled = [...allItems].sort(() => Math.random() - 0.5); for (let i = 0; i < Math.min(count, shuffled.length); i++) { selectedItems.push(this.processItem(shuffled[i])); } return selectedItems; } } module.exports = ItemSystem;