From 6db6e1ebdb75fc8a465b245d66f75bdbb0b52010 Mon Sep 17 00:00:00 2001 From: Robert MacRae Date: Mon, 26 Jan 2026 18:46:53 -0400 Subject: [PATCH] moved the items call from the client to the server --- Client/js/GameInitializer.js | 3 +- Client/js/core/Economy.js | 89 ++++++-- Client/js/systems/ItemSystem.js | 4 + Client/js/systems/ShipSystem.js | 42 +++- Client/js/ui/LiveMainMenu.js | 2 +- .../assets/images}/armors/basic_armor.png | Bin .../assets/images}/armors/heavy_armor.png | Bin .../assets/images}/armors/medium_armor.png | Bin .../assets/images}/base/command_center.png | Bin .../assets/images}/base/mining_facility.png | Bin .../images/items/consumables}/bandages.png | Bin .../images/items/consumables}/health_pack.png | Bin .../items/consumables}/mega_health_pack.png | Bin GameServer/assets/images/items/cosmetics/temp | 0 .../materials}/advanced_circuitboard.png | Bin .../items/materials}/advanced_component.png | Bin .../items/materials}/advanced_components.png | Bin .../items/materials}/basic_circuitboard.png | Bin .../images/items/materials}/battery.png | Bin .../items/materials}/common_circuitboard.png | Bin .../images/items/materials}/copper_ore.png | Bin .../images/items/materials}/copper_wire.png | Bin .../items/materials}/energy_crystal.png | Bin .../assets/images/items/materials}/herbs.png | Bin .../images/items/materials}/iron_ore.png | Bin .../images/items/materials}/leather.png | Bin .../images/items/materials}/stell_plate.png | Bin .../images/items/materials}/tin_bar.png | Bin .../assets/images}/ships/heavy_cruiser.png | Bin .../assets/images}/ships/heavy_destroyer.png | Bin .../assets/images}/ships/light_destroyer.png | Bin .../assets/images}/ships/starter_cruiser.png | Bin GameServer/assets/images/ui/icons/temp | 0 .../assets/images/ui/placeholder.png | Bin .../assets/images}/weapons/laser_pistol.png | Bin .../images}/weapons/laser_sniper_rifle.png | Bin .../images}/weapons/starter_blaster.png | Bin GameServer/create_placeholders.js | 191 ++++++++++++++++ GameServer/generate_assets.js | 209 ++++++++++++++++++ GameServer/server.js | 134 +++++++++-- GameServer/systems/ItemSystem.js | 101 ++++++++- 41 files changed, 725 insertions(+), 50 deletions(-) rename {Client/assets/textures => GameServer/assets/images}/armors/basic_armor.png (100%) rename {Client/assets/textures => GameServer/assets/images}/armors/heavy_armor.png (100%) rename {Client/assets/textures => GameServer/assets/images}/armors/medium_armor.png (100%) rename {Client/assets/textures => GameServer/assets/images}/base/command_center.png (100%) rename {Client/assets/textures => GameServer/assets/images}/base/mining_facility.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/consumables}/bandages.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/consumables}/health_pack.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/consumables}/mega_health_pack.png (100%) create mode 100644 GameServer/assets/images/items/cosmetics/temp rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/advanced_circuitboard.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/advanced_component.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/advanced_components.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/basic_circuitboard.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/battery.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/common_circuitboard.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/copper_ore.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/copper_wire.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/energy_crystal.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/herbs.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/iron_ore.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/leather.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/stell_plate.png (100%) rename {Client/assets/textures/items => GameServer/assets/images/items/materials}/tin_bar.png (100%) rename {Client/assets/textures => GameServer/assets/images}/ships/heavy_cruiser.png (100%) rename {Client/assets/textures => GameServer/assets/images}/ships/heavy_destroyer.png (100%) rename {Client/assets/textures => GameServer/assets/images}/ships/light_destroyer.png (100%) rename {Client/assets/textures => GameServer/assets/images}/ships/starter_cruiser.png (100%) create mode 100644 GameServer/assets/images/ui/icons/temp rename Client/assets/textures/missing-texture.png => GameServer/assets/images/ui/placeholder.png (100%) rename {Client/assets/textures => GameServer/assets/images}/weapons/laser_pistol.png (100%) rename {Client/assets/textures => GameServer/assets/images}/weapons/laser_sniper_rifle.png (100%) rename {Client/assets/textures => GameServer/assets/images}/weapons/starter_blaster.png (100%) create mode 100644 GameServer/create_placeholders.js create mode 100644 GameServer/generate_assets.js diff --git a/Client/js/GameInitializer.js b/Client/js/GameInitializer.js index 1dbf404..c4e6517 100644 --- a/Client/js/GameInitializer.js +++ b/Client/js/GameInitializer.js @@ -14,7 +14,7 @@ class GameInitializer { this.currentUser = null; this.socket = null; this.apiBaseUrl = 'https://api.korvarix.com/api'; // API Server - this.gameServerUrl = 'https://dev.gameserver.galaxystrike.online'; // Game Server for Socket.IO (local dev server) + this.gameServerUrl = 'https://dev.gameserver.galaxystrike.online'; // Game Server for Socket.IO console.log('[GAME INITIALIZER] Constructor - gameServerUrl set to:', this.gameServerUrl); } @@ -74,6 +74,7 @@ class GameInitializer { const FORCED_URL = 'https://dev.gameserver.galaxystrike.online'; console.log('[GAME INITIALIZER] FORCING URL to:', FORCED_URL); console.log('[GAME INITIALIZER] Original this.gameServerUrl:', this.gameServerUrl); + console.log('[GAME INITIALIZER] Using remote development server'); // Connect to the game server with FORCED URL this.socket = io(FORCED_URL, { diff --git a/Client/js/core/Economy.js b/Client/js/core/Economy.js index d9a3f52..963f784 100644 --- a/Client/js/core/Economy.js +++ b/Client/js/core/Economy.js @@ -547,25 +547,36 @@ class Economy { const canAfford = this.canAfford(item.price, item.currency); const isOwned = item.type === 'cosmetic' && this.ownedCosmetics.includes(item.id); + // Generate image URL - server will serve images + const imageUrl = this.getItemImageUrl(item); + const placeholderUrl = 'https://dev.gameserver.galaxystrike.online/images/ui/placeholder.png'; + return `
-
-

${item.name}

- ${item.rarity} +
+ ${item.name}
-
-

${item.description}

-
- ${this.formatPrice(item)} +
+
+

${item.name}

+ ${item.rarity} +
+
+

${item.description}

+
+ ${this.formatPrice(item)} +
+
+ -
-
@@ -582,6 +593,56 @@ class Economy { return `${price} ${currency}`; } + /** + * Get image URL for an item from server + */ + getItemImageUrl(item) { + if (!item) return 'https://dev.gameserver.galaxystrike.online/images/ui/placeholder.png'; + + // For multiplayer, ALWAYS get from server + if (window.smartSaveManager?.isMultiplayer && this.game.socket) { + const serverUrl = this.getServerUrl(); + + // Map item types to proper server paths + switch (item.type) { + case 'ship': + return `${serverUrl}/images/ships/${item.id}.png`; + case 'weapon': + return `${serverUrl}/images/weapons/${item.id}.png`; + case 'armor': + return `${serverUrl}/images/armors/${item.id}.png`; + case 'material': + return `${serverUrl}/images/items/materials/${item.id}.png`; + case 'consumable': + return `${serverUrl}/images/items/consumables/${item.id}.png`; + case 'cosmetic': + return `${serverUrl}/images/items/cosmetics/${item.id}.png`; + default: + return `${serverUrl}/images/ui/placeholder.png`; + } + } + + // For singleplayer, use local texture path (if available) + if (item.texture) { + return item.texture; + } + + // Fallback to server placeholder + return 'https://dev.gameserver.galaxystrike.online/images/ui/placeholder.png'; + } + + /** + * Get server URL for image requests + */ + getServerUrl() { + // Get server URL from socket connection + if (this.game.socket && this.game.socket.io && this.game.socket.io.uri) { + return this.game.socket.io.uri.replace('/socket.io', ''); + } + // Fallback to environment variable or production server + return process.env.SERVER_URL || 'https://dev.gameserver.galaxystrike.online'; + } + // Save/Load functionality save() { return { diff --git a/Client/js/systems/ItemSystem.js b/Client/js/systems/ItemSystem.js index 7caaf30..0c15b49 100644 --- a/Client/js/systems/ItemSystem.js +++ b/Client/js/systems/ItemSystem.js @@ -123,9 +123,13 @@ class ItemSystem { clearTimeout(timeout); window.game.socket.off('shopItemsReceived', handleResponse); + console.log('[ITEM SYSTEM] Response success:', data.success); + console.log('[ITEM SYSTEM] Response items count:', data.items?.length || 0); + if (data.success) { console.log('[ITEM SYSTEM] Successfully received', data.items?.length || 0, 'items'); console.log('[ITEM SYSTEM] Response timestamp:', data.timestamp); + console.log('[ITEM SYSTEM] Sample item:', data.items?.[0]); resolve(data.items || []); } else { console.error('[ITEM SYSTEM] Server returned error:', data.error); diff --git a/Client/js/systems/ShipSystem.js b/Client/js/systems/ShipSystem.js index e3dcb7e..fc05106 100644 --- a/Client/js/systems/ShipSystem.js +++ b/Client/js/systems/ShipSystem.js @@ -60,6 +60,22 @@ class ShipSystem { shipGrid.appendChild(shipCard); }); } + + /** + * Get ship image URL from server or local + */ + getShipImageUrl(ship) { + if (!ship) return 'https://dev.gameserver.galaxystrike.online/images/ui/placeholder.png'; + + // For multiplayer, get from server + if (window.smartSaveManager?.isMultiplayer && window.game?.socket) { + const serverUrl = window.game.socket.io?.uri?.replace('/socket.io', '') || process.env.SERVER_URL || 'https://dev.gameserver.galaxystrike.online'; + return `${serverUrl}/images/ships/${ship.id}.png`; + } + + // For singleplayer, use local path + return ship.image || ship.texture || 'assets/textures/ships/starter_cruiser.png'; + } createShipCard(ship) { const card = document.createElement('div'); @@ -68,17 +84,13 @@ class ShipSystem { card.innerHTML = `
- ${ship.name} + ${ship.name}
${ship.rarity}
-
- -
`; return card; @@ -106,10 +118,22 @@ class ShipSystem { const ship = player.ship; if (elements.currentShipImage) { - // Use the ship's texture if available, otherwise fallback - const imagePath = ship.texture || `assets/textures/ships/starter_cruiser.png`; + // Use server image for multiplayer, local for singleplayer + let imagePath; + if (window.smartSaveManager?.isMultiplayer && window.game?.socket) { + const serverUrl = window.game.socket.io?.uri?.replace('/socket.io', '') || 'http://localhost:3002'; + imagePath = `${serverUrl}/images/ships/${ship.class || 'starter_cruiser'}.png`; + } else { + imagePath = ship.texture || `assets/textures/ships/starter_cruiser.png`; + } + elements.currentShipImage.src = imagePath; elements.currentShipImage.alt = ship.name; + elements.currentShipImage.onerror = function() { + this.src = window.smartSaveManager?.isMultiplayer ? + 'https://dev.gameserver.galaxystrike.online/images/ui/placeholder.png' : + 'assets/textures/missing-texture.png'; + }; } if (elements.currentShipName) elements.currentShipName.textContent = ship.name; if (elements.currentShipClass) elements.currentShipClass.textContent = ship.class || 'Unknown'; diff --git a/Client/js/ui/LiveMainMenu.js b/Client/js/ui/LiveMainMenu.js index b18d573..5994b0f 100644 --- a/Client/js/ui/LiveMainMenu.js +++ b/Client/js/ui/LiveMainMenu.js @@ -24,7 +24,7 @@ class LiveMainMenu { this.currentUser = null; this.servers = []; // Renamed from serverList to avoid conflict with DOM element this.apiBaseUrl = 'https://api.korvarix.com/api'; // API Server URL - this.gameServerUrl = 'https://dev.gameserver.galaxystrike.online'; // Game Server URL for Socket.IO (local dev server) + this.gameServerUrl = 'https://dev.gameserver.galaxystrike.online'; // Game Server URL for Socket.IO this.localGameServerUrl = 'http://localhost:3002'; // Local Game Server URL this.isLocalMode = false; // Track if we're in local mode diff --git a/Client/assets/textures/armors/basic_armor.png b/GameServer/assets/images/armors/basic_armor.png similarity index 100% rename from Client/assets/textures/armors/basic_armor.png rename to GameServer/assets/images/armors/basic_armor.png diff --git a/Client/assets/textures/armors/heavy_armor.png b/GameServer/assets/images/armors/heavy_armor.png similarity index 100% rename from Client/assets/textures/armors/heavy_armor.png rename to GameServer/assets/images/armors/heavy_armor.png diff --git a/Client/assets/textures/armors/medium_armor.png b/GameServer/assets/images/armors/medium_armor.png similarity index 100% rename from Client/assets/textures/armors/medium_armor.png rename to GameServer/assets/images/armors/medium_armor.png diff --git a/Client/assets/textures/base/command_center.png b/GameServer/assets/images/base/command_center.png similarity index 100% rename from Client/assets/textures/base/command_center.png rename to GameServer/assets/images/base/command_center.png diff --git a/Client/assets/textures/base/mining_facility.png b/GameServer/assets/images/base/mining_facility.png similarity index 100% rename from Client/assets/textures/base/mining_facility.png rename to GameServer/assets/images/base/mining_facility.png diff --git a/Client/assets/textures/items/bandages.png b/GameServer/assets/images/items/consumables/bandages.png similarity index 100% rename from Client/assets/textures/items/bandages.png rename to GameServer/assets/images/items/consumables/bandages.png diff --git a/Client/assets/textures/items/health_pack.png b/GameServer/assets/images/items/consumables/health_pack.png similarity index 100% rename from Client/assets/textures/items/health_pack.png rename to GameServer/assets/images/items/consumables/health_pack.png diff --git a/Client/assets/textures/items/mega_health_pack.png b/GameServer/assets/images/items/consumables/mega_health_pack.png similarity index 100% rename from Client/assets/textures/items/mega_health_pack.png rename to GameServer/assets/images/items/consumables/mega_health_pack.png diff --git a/GameServer/assets/images/items/cosmetics/temp b/GameServer/assets/images/items/cosmetics/temp new file mode 100644 index 0000000..e69de29 diff --git a/Client/assets/textures/items/advanced_circuitboard.png b/GameServer/assets/images/items/materials/advanced_circuitboard.png similarity index 100% rename from Client/assets/textures/items/advanced_circuitboard.png rename to GameServer/assets/images/items/materials/advanced_circuitboard.png diff --git a/Client/assets/textures/items/advanced_component.png b/GameServer/assets/images/items/materials/advanced_component.png similarity index 100% rename from Client/assets/textures/items/advanced_component.png rename to GameServer/assets/images/items/materials/advanced_component.png diff --git a/Client/assets/textures/items/advanced_components.png b/GameServer/assets/images/items/materials/advanced_components.png similarity index 100% rename from Client/assets/textures/items/advanced_components.png rename to GameServer/assets/images/items/materials/advanced_components.png diff --git a/Client/assets/textures/items/basic_circuitboard.png b/GameServer/assets/images/items/materials/basic_circuitboard.png similarity index 100% rename from Client/assets/textures/items/basic_circuitboard.png rename to GameServer/assets/images/items/materials/basic_circuitboard.png diff --git a/Client/assets/textures/items/battery.png b/GameServer/assets/images/items/materials/battery.png similarity index 100% rename from Client/assets/textures/items/battery.png rename to GameServer/assets/images/items/materials/battery.png diff --git a/Client/assets/textures/items/common_circuitboard.png b/GameServer/assets/images/items/materials/common_circuitboard.png similarity index 100% rename from Client/assets/textures/items/common_circuitboard.png rename to GameServer/assets/images/items/materials/common_circuitboard.png diff --git a/Client/assets/textures/items/copper_ore.png b/GameServer/assets/images/items/materials/copper_ore.png similarity index 100% rename from Client/assets/textures/items/copper_ore.png rename to GameServer/assets/images/items/materials/copper_ore.png diff --git a/Client/assets/textures/items/copper_wire.png b/GameServer/assets/images/items/materials/copper_wire.png similarity index 100% rename from Client/assets/textures/items/copper_wire.png rename to GameServer/assets/images/items/materials/copper_wire.png diff --git a/Client/assets/textures/items/energy_crystal.png b/GameServer/assets/images/items/materials/energy_crystal.png similarity index 100% rename from Client/assets/textures/items/energy_crystal.png rename to GameServer/assets/images/items/materials/energy_crystal.png diff --git a/Client/assets/textures/items/herbs.png b/GameServer/assets/images/items/materials/herbs.png similarity index 100% rename from Client/assets/textures/items/herbs.png rename to GameServer/assets/images/items/materials/herbs.png diff --git a/Client/assets/textures/items/iron_ore.png b/GameServer/assets/images/items/materials/iron_ore.png similarity index 100% rename from Client/assets/textures/items/iron_ore.png rename to GameServer/assets/images/items/materials/iron_ore.png diff --git a/Client/assets/textures/items/leather.png b/GameServer/assets/images/items/materials/leather.png similarity index 100% rename from Client/assets/textures/items/leather.png rename to GameServer/assets/images/items/materials/leather.png diff --git a/Client/assets/textures/items/stell_plate.png b/GameServer/assets/images/items/materials/stell_plate.png similarity index 100% rename from Client/assets/textures/items/stell_plate.png rename to GameServer/assets/images/items/materials/stell_plate.png diff --git a/Client/assets/textures/items/tin_bar.png b/GameServer/assets/images/items/materials/tin_bar.png similarity index 100% rename from Client/assets/textures/items/tin_bar.png rename to GameServer/assets/images/items/materials/tin_bar.png diff --git a/Client/assets/textures/ships/heavy_cruiser.png b/GameServer/assets/images/ships/heavy_cruiser.png similarity index 100% rename from Client/assets/textures/ships/heavy_cruiser.png rename to GameServer/assets/images/ships/heavy_cruiser.png diff --git a/Client/assets/textures/ships/heavy_destroyer.png b/GameServer/assets/images/ships/heavy_destroyer.png similarity index 100% rename from Client/assets/textures/ships/heavy_destroyer.png rename to GameServer/assets/images/ships/heavy_destroyer.png diff --git a/Client/assets/textures/ships/light_destroyer.png b/GameServer/assets/images/ships/light_destroyer.png similarity index 100% rename from Client/assets/textures/ships/light_destroyer.png rename to GameServer/assets/images/ships/light_destroyer.png diff --git a/Client/assets/textures/ships/starter_cruiser.png b/GameServer/assets/images/ships/starter_cruiser.png similarity index 100% rename from Client/assets/textures/ships/starter_cruiser.png rename to GameServer/assets/images/ships/starter_cruiser.png diff --git a/GameServer/assets/images/ui/icons/temp b/GameServer/assets/images/ui/icons/temp new file mode 100644 index 0000000..e69de29 diff --git a/Client/assets/textures/missing-texture.png b/GameServer/assets/images/ui/placeholder.png similarity index 100% rename from Client/assets/textures/missing-texture.png rename to GameServer/assets/images/ui/placeholder.png diff --git a/Client/assets/textures/weapons/laser_pistol.png b/GameServer/assets/images/weapons/laser_pistol.png similarity index 100% rename from Client/assets/textures/weapons/laser_pistol.png rename to GameServer/assets/images/weapons/laser_pistol.png diff --git a/Client/assets/textures/weapons/laser_sniper_rifle.png b/GameServer/assets/images/weapons/laser_sniper_rifle.png similarity index 100% rename from Client/assets/textures/weapons/laser_sniper_rifle.png rename to GameServer/assets/images/weapons/laser_sniper_rifle.png diff --git a/Client/assets/textures/weapons/starter_blaster.png b/GameServer/assets/images/weapons/starter_blaster.png similarity index 100% rename from Client/assets/textures/weapons/starter_blaster.png rename to GameServer/assets/images/weapons/starter_blaster.png diff --git a/GameServer/create_placeholders.js b/GameServer/create_placeholders.js new file mode 100644 index 0000000..cf7989d --- /dev/null +++ b/GameServer/create_placeholders.js @@ -0,0 +1,191 @@ +/** + * Create placeholder images for existing items in ItemSystem + */ + +const fs = require('fs'); +const path = require('path'); + +// Create directories if they don't exist +const directories = [ + 'assets/images/ships', + 'assets/images/weapons', + 'assets/images/armors', + 'assets/images/items/materials', + 'assets/images/items/consumables', + 'assets/images/items/cosmetics', + 'assets/images/ui' +]; + +directories.forEach(dir => { + const fullPath = path.join(__dirname, dir); + if (!fs.existsSync(fullPath)) { + fs.mkdirSync(fullPath, { recursive: true }); + console.log(`Created directory: ${dir}`); + } +}); + +// Create a simple colored rectangle as placeholder +function createPlaceholder(width, height, color, text) { + // Create a simple 1x1 pixel colored PNG (base64 encoded) + // This is a minimal PNG with transparency + const createColorPNG = (r, g, b) => { + return Buffer.from([ + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, // PNG signature + 0x00, 0x00, 0x00, 0x0D, // IHDR chunk length + 0x49, 0x48, 0x44, 0x52, // IHDR + width >> 24, width >> 16, width >> 8, width, // width + height >> 24, height >> 16, height >> 8, height, // height + 0x08, 0x02, 0x00, 0x00, 0x00, // bit depth, color type, compression, filter, interlace + 0x4B, 0x6D, 0x29, 0xDC, // CRC + 0x00, 0x00, 0x00, 0x0C, // IDAT chunk length + 0x49, 0x44, 0x41, 0x54, // IDAT + 0x08, 0x99, 0x01, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, // compressed data + 0x00, 0x00, 0x00, 0x00, // IEND chunk length + 0x49, 0x45, 0x4E, 0x44, // IEND + 0xAE, 0x42, 0x60, 0x82 // CRC + ]); + }; + + // For simplicity, let's copy existing images or create basic placeholders + return createColorPNG( + color === 'blue' ? 52 : color === 'red' ? 231 : color === 'green' ? 39 : 149, + color === 'blue' ? 152 : color === 'red' ? 76 : color === 'green' ? 174 : 165, + color === 'blue' ? 219 : color === 'red' ? 60 : color === 'green' ? 96 : 166 + ); +} + +// Items from your ItemSystem +const items = { + ships: [ + 'starter_cruiser_common', + 'starter_cruiser_uncommon', + 'starter_cruiser_rare', + 'interceptor_common', + 'interceptor_uncommon' + ], + weapons: [ + 'laser_pistol_common', + 'laser_pistol_uncommon', + 'laser_pistol_rare', + 'plasma_rifle_common', + 'plasma_rifle_uncommon', + 'plasma_rifle_rare' + ], + armors: [ + 'light_armor_common', + 'light_armor_uncommon', + 'light_armor_rare', + 'medium_armor_common', + 'medium_armor_uncommon', + 'medium_armor_rare' + ], + materials: [ + 'steel_plating', + 'energy_crystal', + 'rare_metal', + 'quantum_core', + 'nanomaterials', + 'dark_matter_fragment' + ], + consumables: [ + 'health_pack', + 'energy_boost', + 'shield_recharge', + 'repair_kit', + 'ammo_pack', + 'experience_boost' + ], + cosmetics: [ + 'cool_paint_job', + 'neon_lights', + 'custom_decal', + 'golden_trim', + 'carbon_fiber', + 'chrome_finish' + ] +}; + +// Copy existing images or create placeholders +console.log('Creating placeholder images...'); + +// For ships - copy existing or create placeholder +items.ships.forEach(shipId => { + const existingPath = path.join(__dirname, `assets/images/ships/starter_cruiser.png`); + const targetPath = path.join(__dirname, `assets/images/ships/${shipId}.png`); + + if (fs.existsSync(existingPath) && !fs.existsSync(targetPath)) { + fs.copyFileSync(existingPath, targetPath); + console.log(`Copied ship: ${shipId}.png`); + } else if (!fs.existsSync(targetPath)) { + const placeholder = createPlaceholder(80, 80, 'blue', shipId); + fs.writeFileSync(targetPath, placeholder); + console.log(`Created ship placeholder: ${shipId}.png`); + } +}); + +// For weapons - copy existing or create placeholder +items.weapons.forEach(weaponId => { + const existingPath = path.join(__dirname, `assets/images/weapons/starter_blaster.png`); + const targetPath = path.join(__dirname, `assets/images/weapons/${weaponId}.png`); + + if (fs.existsSync(existingPath) && !fs.existsSync(targetPath)) { + fs.copyFileSync(existingPath, targetPath); + console.log(`Copied weapon: ${weaponId}.png`); + } else if (!fs.existsSync(targetPath)) { + const placeholder = createPlaceholder(64, 64, 'red', weaponId); + fs.writeFileSync(targetPath, placeholder); + console.log(`Created weapon placeholder: ${weaponId}.png`); + } +}); + +// For armors - create placeholders +items.armors.forEach(armorId => { + const targetPath = path.join(__dirname, `assets/images/armors/${armorId}.png`); + if (!fs.existsSync(targetPath)) { + const placeholder = createPlaceholder(64, 64, 'green', armorId); + fs.writeFileSync(targetPath, placeholder); + console.log(`Created armor placeholder: ${armorId}.png`); + } +}); + +// For materials - create placeholders +items.materials.forEach(materialId => { + const targetPath = path.join(__dirname, `assets/images/items/materials/${materialId}.png`); + if (!fs.existsSync(targetPath)) { + const placeholder = createPlaceholder(48, 48, 'gray', materialId); + fs.writeFileSync(targetPath, placeholder); + console.log(`Created material placeholder: ${materialId}.png`); + } +}); + +// For consumables - create placeholders +items.consumables.forEach(consumableId => { + const targetPath = path.join(__dirname, `assets/images/items/consumables/${consumableId}.png`); + if (!fs.existsSync(targetPath)) { + const placeholder = createPlaceholder(48, 48, 'purple', consumableId); + fs.writeFileSync(targetPath, placeholder); + console.log(`Created consumable placeholder: ${consumableId}.png`); + } +}); + +// For cosmetics - create placeholders +items.cosmetics.forEach(cosmeticId => { + const targetPath = path.join(__dirname, `assets/images/items/cosmetics/${cosmeticId}.png`); + if (!fs.existsSync(targetPath)) { + const placeholder = createPlaceholder(64, 64, 'gold', cosmeticId); + fs.writeFileSync(targetPath, placeholder); + console.log(`Created cosmetic placeholder: ${cosmeticId}.png`); + } +}); + +// Create UI placeholder +const placeholderPath = path.join(__dirname, 'assets/images/ui/placeholder.png'); +if (!fs.existsSync(placeholderPath)) { + const placeholder = createPlaceholder(80, 80, 'gray', 'placeholder'); + fs.writeFileSync(placeholderPath, placeholder); + console.log('Created UI placeholder.png'); +} + +console.log('\nšŸŽ‰ Placeholder images created successfully!'); +console.log('šŸ“¦ Your shop should now display items with placeholder images!'); +console.log('šŸ”„ Replace these with actual images as you create them.'); diff --git a/GameServer/generate_assets.js b/GameServer/generate_assets.js new file mode 100644 index 0000000..ecb0bbf --- /dev/null +++ b/GameServer/generate_assets.js @@ -0,0 +1,209 @@ +/** + * Generate temporary placeholder images for all item types + * Run this script with: node generate_assets.js + */ + +const fs = require('fs'); +const path = require('path'); + +// Create directories +const directories = [ + 'assets/images/ships', + 'assets/images/weapons', + 'assets/images/armors', + 'assets/images/items/materials', + 'assets/images/items/consumables', + 'assets/images/items/cosmetics', + 'assets/images/ui/icons' +]; + +directories.forEach(dir => { + const fullPath = path.join(__dirname, dir); + if (!fs.existsSync(fullPath)) { + fs.mkdirSync(fullPath, { recursive: true }); + console.log(`Created directory: ${dir}`); + } +}); + +// Generate simple SVG placeholder +function generateSVG(width, height, color, text, filename) { + const svg = ` + + + + ${text} + +`; + + return svg; +} + +// Ships - Blue theme +const ships = [ + 'starter_cruiser_common', + 'starter_cruiser_uncommon', + 'starter_cruiser_rare', + 'advanced_fighter_common', + 'advanced_fighter_uncommon', + 'advanced_fighter_rare', + 'heavy_battleship_common', + 'heavy_battleship_uncommon', + 'heavy_battleship_rare', + 'stealth_ship_common', + 'stealth_ship_uncommon', + 'stealth_ship_rare' +]; + +// Weapons - Red theme +const weapons = [ + 'laser_cannon_common', + 'laser_cannon_uncommon', + 'laser_cannon_rare', + 'plasma_rifle_common', + 'plasma_rifle_uncommon', + 'plasma_rifle_rare', + 'missile_launcher_common', + 'missile_launcher_uncommon', + 'missile_launcher_rare', + 'railgun_common', + 'railgun_uncommon', + 'railgun_rare' +]; + +// Armors - Green theme +const armors = [ + 'light_armor_common', + 'light_armor_uncommon', + 'light_armor_rare', + 'medium_armor_common', + 'medium_armor_uncommon', + 'medium_armor_rare', + 'heavy_armor_common', + 'heavy_armor_uncommon', + 'heavy_armor_rare', + 'energy_shield_common', + 'energy_shield_uncommon', + 'energy_shield_rare' +]; + +// Materials - Gray theme +const materials = [ + 'metal_scraps', + 'energy_crystal', + 'plastic_parts', + 'electronic_components', + 'rare_earth_metal', + 'quantum_core', + 'nanomaterials', + 'dark_matter_fragment', + 'solar_panel', + 'cooling_system', + 'power_cell', + 'hull_plating' +]; + +// Consumables - Purple theme +const consumables = [ + 'health_pack', + 'energy_boost', + 'shield_recharge', + 'speed_boost', + 'repair_kit', + 'ammo_pack', + 'stealth_device', + 'scanner_boost', + 'experience_boost', + 'credit_multiplier', + 'lucky_charm', + 'emergency_beacon' +]; + +// Cosmetics - Gold theme +const cosmetics = [ + 'cool_paint_job', + 'neon_lights', + 'custom_decal', + 'golden_trim', + 'carbon_fiber', + 'chrome_finish', + 'matte_black', + 'camo_pattern', + 'flame_design', + 'electric_aura', + 'ice_effect', + 'rainbow_sparkle' +]; + +// Generate all images +console.log('Generating ship images...'); +ships.forEach(shipId => { + const rarity = shipId.split('_').pop(); + const color = rarity === 'common' ? '#3498db' : rarity === 'uncommon' ? '#2ecc71' : '#f39c12'; + const svg = generateSVG(80, 80, color, shipId.replace(/_/g, ' ').toUpperCase(), shipId); + fs.writeFileSync(path.join(__dirname, `assets/images/ships/${shipId}.png`), svg); + console.log(`Created: ${shipId}.png`); +}); + +console.log('Generating weapon images...'); +weapons.forEach(weaponId => { + const rarity = weaponId.split('_').pop(); + const color = rarity === 'common' ? '#e74c3c' : rarity === 'uncommon' ? '#c0392b' : '#8e44ad'; + const svg = generateSVG(64, 64, color, weaponId.replace(/_/g, ' ').toUpperCase(), weaponId); + fs.writeFileSync(path.join(__dirname, `assets/images/weapons/${weaponId}.png`), svg); + console.log(`Created: ${weaponId}.png`); +}); + +console.log('Generating armor images...'); +armors.forEach(armorId => { + const rarity = armorId.split('_').pop(); + const color = rarity === 'common' ? '#27ae60' : rarity === 'uncommon' ? '#16a085' : '#2c3e50'; + const svg = generateSVG(64, 64, color, armorId.replace(/_/g, ' ').toUpperCase(), armorId); + fs.writeFileSync(path.join(__dirname, `assets/images/armors/${armorId}.png`), svg); + console.log(`Created: ${armorId}.png`); +}); + +console.log('Generating material images...'); +materials.forEach(materialId => { + const svg = generateSVG(48, 48, '#7f8c8d', materialId.replace(/_/g, ' ').toUpperCase(), materialId); + fs.writeFileSync(path.join(__dirname, `assets/images/items/materials/${materialId}.png`), svg); + console.log(`Created: ${materialId}.png`); +}); + +console.log('Generating consumable images...'); +consumables.forEach(consumableId => { + const svg = generateSVG(48, 48, '#9b59b6', consumableId.replace(/_/g, ' ').toUpperCase(), consumableId); + fs.writeFileSync(path.join(__dirname, `assets/images/items/consumables/${consumableId}.png`), svg); + console.log(`Created: ${consumableId}.png`); +}); + +console.log('Generating cosmetic images...'); +cosmetics.forEach(cosmeticId => { + const svg = generateSVG(64, 64, '#f1c40f', cosmeticId.replace(/_/g, ' ').toUpperCase(), cosmeticId); + fs.writeFileSync(path.join(__dirname, `assets/images/items/cosmetics/${cosmeticId}.png`), svg); + console.log(`Created: ${cosmeticId}.png`); +}); + +// Generate UI placeholder +console.log('Generating UI placeholder...'); +const placeholderSvg = generateSVG(80, 80, '#95a5a6', 'PLACEHOLDER', 'placeholder'); +fs.writeFileSync(path.join(__dirname, 'assets/images/ui/placeholder.png'), placeholderSvg); + +// Generate some UI icons +const icons = ['coin', 'gem', 'heart', 'shield', 'star', 'lock', 'unlock', 'settings']; +icons.forEach(iconId => { + const svg = generateSVG(32, 32, '#34495e', iconId.toUpperCase(), iconId); + fs.writeFileSync(path.join(__dirname, `assets/images/ui/icons/${iconId}.png`), svg); + console.log(`Created icon: ${iconId}.png`); +}); + +console.log('\nšŸŽ‰ All placeholder images generated successfully!'); +console.log('šŸ“ Total images created:'); +console.log(` Ships: ${ships.length}`); +console.log(` Weapons: ${weapons.length}`); +console.log(` Armors: ${armors.length}`); +console.log(` Materials: ${materials.length}`); +console.log(` Consumables: ${consumables.length}`); +console.log(` Cosmetics: ${cosmetics.length}`); +console.log(` UI Icons: ${icons.length + 1} (including placeholder)`); +console.log('\nšŸš€ Your shop should now display all items with placeholder images!'); diff --git a/GameServer/server.js b/GameServer/server.js index eab0cd8..3efe609 100644 --- a/GameServer/server.js +++ b/GameServer/server.js @@ -10,6 +10,8 @@ const cors = require('cors'); const helmet = require('helmet'); const compression = require('compression'); const mongoose = require('mongoose'); +const fs = require('fs'); +const path = require('path'); require('dotenv').config(); const logger = require('./utils/logger'); @@ -32,6 +34,10 @@ const craftingSystem = new CraftingSystem(); const idleSystem = new IdleSystem(); const itemSystem = new ItemSystem(); +// Set server URL for ItemSystem +const SERVER_URL = process.env.SERVER_URL || 'https://dev.gameserver.galaxystrike.online'; +itemSystem.setServerUrl(SERVER_URL); + const app = express(); const server = http.createServer(app); const io = socketIo(server, { @@ -69,6 +75,81 @@ app.use(cors({ credentials: true })); app.use(express.json({ limit: '10mb' })); + +// Serve static files from the client directory +app.use(express.static(path.join(__dirname, '../Client'))); + +// Serve ships from server-side storage +app.use('/images/ships', (req, res, next) => { + const requestedPath = req.path; + const serverImagePath = path.join(__dirname, 'assets/images/ships', requestedPath); + + console.log('[IMAGE SERVER] Ship requested:', requestedPath); + + if (fs.existsSync(serverImagePath)) { + res.sendFile(serverImagePath); + } else { + const placeholderPath = path.join(__dirname, 'assets/images/ui/placeholder.png'); + res.sendFile(placeholderPath); + } +}); + +// Serve weapons from server-side storage +app.use('/images/weapons', (req, res, next) => { + const requestedPath = req.path; + const serverImagePath = path.join(__dirname, 'assets/images/weapons', requestedPath); + + console.log('[IMAGE SERVER] Weapon requested:', requestedPath); + + if (fs.existsSync(serverImagePath)) { + res.sendFile(serverImagePath); + } else { + const placeholderPath = path.join(__dirname, 'assets/images/ui/placeholder.png'); + res.sendFile(placeholderPath); + } +}); + +// Serve armors from server-side storage +app.use('/images/armors', (req, res, next) => { + const requestedPath = req.path; + const serverImagePath = path.join(__dirname, 'assets/images/armors', requestedPath); + + console.log('[IMAGE SERVER] Armor requested:', requestedPath); + + if (fs.existsSync(serverImagePath)) { + res.sendFile(serverImagePath); + } else { + const placeholderPath = path.join(__dirname, 'assets/images/ui/placeholder.png'); + res.sendFile(placeholderPath); + } +}); + +// Serve other items (materials, consumables, cosmetics) from server-side storage +app.use('/images/items', (req, res, next) => { + const requestedPath = req.path; + const serverImagePath = path.join(__dirname, 'assets/images/items', requestedPath); + + console.log('[IMAGE SERVER] Item requested:', requestedPath); + + if (fs.existsSync(serverImagePath)) { + res.sendFile(serverImagePath); + } else { + const placeholderPath = path.join(__dirname, 'assets/images/ui/placeholder.png'); + res.sendFile(placeholderPath); + } +}); + +// Serve UI elements and icons from server-side storage +app.use('/images/ui', (req, res, next) => { + const requestedPath = req.path; + const serverImagePath = path.join(__dirname, 'assets/images/ui', requestedPath); + + if (fs.existsSync(serverImagePath)) { + res.sendFile(serverImagePath); + } else { + res.status(404).send('UI asset not found'); + } +}); app.use(express.urlencoded({ extended: true })); // Health check endpoint @@ -96,7 +177,7 @@ app.get('/api/ssc/version', (req, res) => { // Shop API endpoints app.get('/api/shop/items', (req, res) => { try { - const shopItems = itemSystem.getShopItems(); + const shopItems = itemSystem.getRandomShopItems(); res.status(200).json({ success: true, items: shopItems, @@ -114,19 +195,19 @@ app.get('/api/shop/items', (req, res) => { app.get('/api/shop/items/:category', (req, res) => { try { const { category } = req.params; - const items = itemSystem.getItemsByCategory(category); + const items = itemSystem.getItemsByType(category); res.status(200).json({ success: true, - category: category, items: items, + category: category, timestamp: new Date().toISOString() }); } catch (error) { - console.error('[GAME SERVER] Error fetching shop category:', error); + console.error('[GAME SERVER] Error fetching category items:', error); res.status(500).json({ success: false, - error: 'Failed to fetch shop category' + error: 'Failed to fetch category items' }); } }); @@ -134,7 +215,15 @@ app.get('/api/shop/items/:category', (req, res) => { app.get('/api/items/:itemId', (req, res) => { try { const { itemId } = req.params; - const item = itemSystem.getItem(itemId); + + // Find item across all categories + const allItems = itemSystem.getAllItems(); + let item = null; + + for (const [category, items] of Object.entries(allItems)) { + item = items.find(i => i.id === itemId); + if (item) break; + } if (!item) { return res.status(404).json({ @@ -145,13 +234,14 @@ app.get('/api/items/:itemId', (req, res) => { res.status(200).json({ success: true, - item: item + item: item, + timestamp: new Date().toISOString() }); } catch (error) { - console.error('[GAME SERVER] Error fetching item:', error); + console.error('[GAME SERVER] Error fetching item details:', error); res.status(500).json({ success: false, - error: 'Failed to fetch item' + error: 'Failed to fetch item details' }); } }); @@ -371,17 +461,27 @@ io.on('connection', (socket) => { // Shop and item system events socket.on('getShopItems', (data) => { - console.log('[GAME SERVER] Sending shop items to:', socket.id); + console.log('[GAME SERVER] getShopItems request received from:', socket.id); + console.log('[GAME SERVER] Request data:', data); try { - const shopItems = itemSystem.getShopItems(); - socket.emit('shopItemsReceived', { + console.log('[GAME SERVER] Getting shop items from ItemSystem...'); + const shopItems = itemSystem.getRandomShopItems(); + console.log('[GAME SERVER] Got shop items:', shopItems.length, 'items'); + console.log('[GAME SERVER] Sample item:', shopItems[0]); + + const response = { success: true, items: shopItems, timestamp: new Date().toISOString() - }); + }; + + console.log('[GAME SERVER] Sending response:', response); + socket.emit('shopItemsReceived', response); + console.log('[GAME SERVER] Response sent successfully'); } catch (error) { console.error('[GAME SERVER] Error sending shop items:', error); + console.error('[GAME SERVER] Error stack:', error.stack); socket.emit('shopItemsReceived', { success: false, error: 'Failed to load shop items' @@ -726,13 +826,7 @@ io.on('connection', (socket) => { socket.on('get_dungeons', () => { console.log('[GAME SERVER] Sending dungeons data to:', socket.id); const dungeons = dungeonSystem.getDungeonsGroupedByDifficulty(); - socket.emit('dungeons_data', { dungeons }); - }); - - socket.on('get_room_types', () => { - console.log('[GAME SERVER] Sending room types to:', socket.id); - const roomTypes = dungeonSystem.getRoomTypes(); - socket.emit('room_types_data', roomTypes); + socket.emit('dungeons_data', dungeons); }); socket.on('get_enemy_templates', () => { diff --git a/GameServer/systems/ItemSystem.js b/GameServer/systems/ItemSystem.js index 7c6c9a0..54e236d 100644 --- a/GameServer/systems/ItemSystem.js +++ b/GameServer/systems/ItemSystem.js @@ -5,6 +5,9 @@ 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 @@ -17,7 +20,7 @@ class ItemSystem { price: 5000, currency: 'credits', description: 'Reliable starter cruiser for new pilots', - texture: 'assets/textures/ships/starter_cruiser.png', + texturePath: 'images/ships/starter_cruiser_common.png', stats: { attack: 15, speed: 10, defense: 12, hull: 100 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 1 }, @@ -31,7 +34,7 @@ class ItemSystem { price: 12000, currency: 'credits', description: 'Upgraded starter cruiser with enhanced systems', - texture: 'assets/textures/ships/starter_cruiser.png', + texturePath: 'images/ships/starter_cruiser_uncommon.png', stats: { attack: 18, speed: 12, defense: 15, hull: 120 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 5 }, @@ -45,7 +48,7 @@ class ItemSystem { price: 25000, currency: 'credits', description: 'Elite starter cruiser with maximum upgrades', - texture: 'assets/textures/ships/starter_cruiser.png', + texturePath: 'images/ships/starter_cruiser_rare.png', stats: { attack: 22, speed: 15, defense: 18, hull: 150 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 10 }, @@ -59,7 +62,7 @@ class ItemSystem { price: 8000, currency: 'credits', description: 'Fast attack ship for hit-and-run tactics', - texture: 'assets/textures/ships/interceptor.png', + texturePath: 'images/ships/interceptor_common.png', stats: { attack: 12, speed: 18, defense: 8, hull: 80 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 3 }, @@ -73,7 +76,7 @@ class ItemSystem { price: 18000, currency: 'credits', description: 'Enhanced interceptor with improved weapons', - texture: 'assets/textures/ships/interceptor.png', + texturePath: 'images/ships/interceptor_uncommon.png', stats: { attack: 15, speed: 22, defense: 10, hull: 95 }, categories: ['shop', 'dungeon_reward'], requirements: { level: 7 }, @@ -91,6 +94,7 @@ class ItemSystem { 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, @@ -105,6 +109,7 @@ class ItemSystem { 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, @@ -119,6 +124,7 @@ class ItemSystem { 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, @@ -133,6 +139,7 @@ class ItemSystem { 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, @@ -151,6 +158,7 @@ class ItemSystem { 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, @@ -167,6 +175,7 @@ class ItemSystem { 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, @@ -183,6 +192,7 @@ class ItemSystem { 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, @@ -199,6 +209,7 @@ class ItemSystem { 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, @@ -219,6 +230,7 @@ class ItemSystem { 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, @@ -233,6 +245,7 @@ class ItemSystem { 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, @@ -247,6 +260,7 @@ class ItemSystem { 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, @@ -261,6 +275,7 @@ class ItemSystem { 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, @@ -279,6 +294,7 @@ class ItemSystem { 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, @@ -292,6 +308,7 @@ class ItemSystem { 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, @@ -305,6 +322,7 @@ class ItemSystem { 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, @@ -322,6 +340,7 @@ class ItemSystem { 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, @@ -335,6 +354,7 @@ class ItemSystem { 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, @@ -348,6 +368,7 @@ class ItemSystem { 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, @@ -613,6 +634,76 @@ class ItemSystem { 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;