API/GameServer/systems/CraftingSystem.js
2026-01-24 21:39:56 -04:00

278 lines
8.4 KiB
JavaScript

/**
* 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;