/** * Galaxy Strike Online - Server Crafting System * Manages crafting recipes, materials, and item creation */ class CraftingSystem { constructor() { this.recipes = new Map(); this.playerCrafting = new Map(); // userId -> crafting data this.initializeRecipes(); } initializeRecipes() { // Basic weapon recipes this.addRecipe('basic_blaster', { name: 'Basic Blaster', type: 'weapon', rarity: 'common', description: 'A simple blaster for beginners', materials: { 'iron_ore': 5, 'copper_wire': 3, 'energy_crystal': 1 }, results: { 'basic_blaster': 1, 'experience': 25 }, skillRequired: 1, craftingTime: 5000 // 5 seconds }); // Advanced weapon recipes this.addRecipe('plasma_cannon', { name: 'Plasma Cannon', type: 'weapon', rarity: 'rare', description: 'A powerful plasma-based weapon', materials: { 'iron_ore': 15, 'copper_wire': 10, 'energy_crystal': 5, 'rare_metal': 3 }, results: { 'plasma_cannon': 1, 'experience': 100 }, skillRequired: 10, craftingTime: 15000 // 15 seconds }); // Armor recipes this.addRecipe('basic_armor', { name: 'Basic Armor', type: 'armor', rarity: 'common', description: 'Light protection for beginners', materials: { 'iron_ore': 8, 'copper_wire': 2 }, results: { 'basic_armor': 1, 'experience': 30 }, skillRequired: 2, craftingTime: 8000 // 8 seconds }); // Consumable recipes this.addRecipe('health_kit', { name: 'Health Kit', type: 'consumable', rarity: 'common', description: 'Restores health when used', materials: { 'iron_ore': 2, 'energy_crystal': 1 }, results: { 'health_kit': 3, 'experience': 10 }, skillRequired: 1, craftingTime: 2000 // 2 seconds }); } addRecipe(id, recipe) { this.recipes.set(id, { id, ...recipe, createdAt: new Date().toISOString() }); } getRecipe(id) { return this.recipes.get(id); } getAllRecipes() { return Array.from(this.recipes.values()); } getRecipesByType(type) { return Array.from(this.recipes.values()).filter(recipe => recipe.type === type); } getRecipesByRarity(rarity) { return Array.from(this.recipes.values()).filter(recipe => recipe.rarity === rarity); } initializePlayerData(userId) { if (!this.playerCrafting.has(userId)) { this.playerCrafting.set(userId, { skill: 1, experience: 0, knownRecipes: new Set(['basic_blaster', 'health_kit']), // Start with basic recipes craftingHistory: [], totalCrafted: 0 }); } return this.playerCrafting.get(userId); } getPlayerData(userId) { return this.playerCrafting.get(userId) || this.initializePlayerData(userId); } canCraft(userId, recipeId, playerInventory) { const recipe = this.getRecipe(recipeId); if (!recipe) { return { canCraft: false, reason: 'Recipe not found' }; } const playerData = this.getPlayerData(userId); // Check skill requirement if (playerData.skill < recipe.skillRequired) { return { canCraft: false, reason: 'Insufficient crafting skill' }; } // Check materials for (const [material, amount] of Object.entries(recipe.materials)) { const playerAmount = playerInventory[material] || 0; if (playerAmount < amount) { return { canCraft: false, reason: `Insufficient ${material}` }; } } return { canCraft: true }; } async craftItem(userId, recipeId, playerInventory) { const canCraftResult = this.canCraft(userId, recipeId, playerInventory); if (!canCraftResult.canCraft) { throw new Error(canCraftResult.reason); } const recipe = this.getRecipe(recipeId); const playerData = this.getPlayerData(userId); // Remove materials from inventory for (const [material, amount] of Object.entries(recipe.materials)) { playerInventory[material] = (playerInventory[material] || 0) - amount; } // Add results to inventory for (const [item, amount] of Object.entries(recipe.results)) { if (item !== 'experience') { playerInventory[item] = (playerInventory[item] || 0) + amount; } } // Add experience and update stats const experienceGained = recipe.results.experience || 0; playerData.experience += experienceGained; playerData.totalCrafted += 1; // Check for skill up const oldSkill = playerData.skill; const newSkill = this.calculateSkillLevel(playerData.experience); playerData.skill = newSkill; // Record crafting history playerData.craftingHistory.push({ recipeId, timestamp: new Date().toISOString(), experienceGained, skillUp: newSkill > oldSkill }); // Keep only last 100 crafting records if (playerData.craftingHistory.length > 100) { playerData.craftingHistory = playerData.craftingHistory.slice(-100); } return { success: true, recipe, results: recipe.results, experienceGained, newSkill, skillUp: newSkill > oldSkill, playerInventory }; } calculateSkillLevel(experience) { // Simple skill progression: 100 XP per level return Math.floor(experience / 100) + 1; } learnRecipe(userId, recipeId) { const recipe = this.getRecipe(recipeId); if (!recipe) { throw new Error('Recipe not found'); } const playerData = this.getPlayerData(userId); playerData.knownRecipes.add(recipeId); return { success: true, recipeId, recipeName: recipe.name }; } getPlayerKnownRecipes(userId) { const playerData = this.getPlayerData(userId); return Array.from(playerData.knownRecipes).map(recipeId => this.getRecipe(recipeId)); } getCraftingStats(userId) { const playerData = this.getPlayerData(userId); return { skill: playerData.skill, experience: playerData.experience, totalCrafted: playerData.totalCrafted, knownRecipesCount: playerData.knownRecipes.size, recentCrafting: playerData.craftingHistory.slice(-10) }; } discoverRecipe(userId, recipeId) { const recipe = this.getRecipe(recipeId); if (!recipe) { throw new Error('Recipe not found'); } const playerData = this.getPlayerData(userId); if (playerData.knownRecipes.has(recipeId)) { return { success: false, reason: 'Recipe already known' }; } // Chance to discover based on skill level const discoveryChance = Math.min(0.1 + (playerData.skill * 0.05), 0.5); const discovered = Math.random() < discoveryChance; if (discovered) { playerData.knownRecipes.add(recipeId); return { success: true, recipeId, recipeName: recipe.name, discovered: true }; } return { success: false, discovered: false }; } } module.exports = CraftingSystem;