Client/Galaxy-Strike-Online-main/GameServer/systems/ResearchSystem.js

111 lines
8.6 KiB
JavaScript

/**
* Galaxy Strike Online - Research System
* Manages the research tree and player tech progress
*/
const RESEARCH_TREE = {
// ── Weapons ─────────────────────────────────────────────────────────────
basic_lasers: { id:'basic_lasers', name:'Basic Lasers', branch:'weapons', tier:1, cost:{credits:500, gems:0}, time:60, effects:{weaponDamage:10}, requires:[] },
pulse_lasers: { id:'pulse_lasers', name:'Pulse Lasers', branch:'weapons', tier:2, cost:{credits:1200, gems:0}, time:180, effects:{weaponDamage:25}, requires:['basic_lasers'] },
advanced_lasers: { id:'advanced_lasers', name:'Advanced Lasers', branch:'weapons', tier:3, cost:{credits:3000, gems:5}, time:600, effects:{weaponDamage:50}, requires:['pulse_lasers'] },
railgun_tech: { id:'railgun_tech', name:'Railgun Tech', branch:'weapons', tier:2, cost:{credits:2000, gems:0}, time:240, effects:{armorPierce:20}, requires:['basic_lasers'] },
smart_warheads: { id:'smart_warheads', name:'Smart Warheads', branch:'weapons', tier:4, cost:{credits:9000, gems:10},time:1200, effects:{missileBonus:30}, requires:['railgun_tech'] },
emp_technology: { id:'emp_technology', name:'EMP Technology', branch:'weapons', tier:3, cost:{credits:4000, gems:5}, time:720, effects:{empChance:15}, requires:['pulse_lasers'] },
// ── Engineering ─────────────────────────────────────────────────────────
structural_analysis:{ id:'structural_analysis', name:'Structural Analysis', branch:'engineering', tier:1, cost:{credits:400, gems:0}, time:60, effects:{hullBonus:10}, requires:[] },
nano_composites: { id:'nano_composites', name:'Nano-Composites', branch:'engineering',tier:2, cost:{credits:1000, gems:0}, time:180, effects:{hullBonus:25}, requires:['structural_analysis'] },
reactive_armor: { id:'reactive_armor', name:'Reactive Armor', branch:'engineering',tier:3, cost:{credits:3500, gems:5}, time:600, effects:{armorBonus:40}, requires:['nano_composites'] },
improved_engines: { id:'improved_engines', name:'Improved Engines', branch:'engineering',tier:1, cost:{credits:300, gems:0}, time:60, effects:{speedBonus:10}, requires:[] },
warp_drive: { id:'warp_drive', name:'Warp Drive', branch:'engineering',tier:5, cost:{credits:20000,gems:20},time:3600, effects:{travelSpeed:60}, requires:['improved_engines'] },
shield_matrix: { id:'shield_matrix', name:'Shield Matrix', branch:'engineering',tier:2, cost:{credits:1200, gems:0}, time:180, effects:{shieldRegen:50}, requires:[] },
// ── Economy ─────────────────────────────────────────────────────────────
enhanced_mining: { id:'enhanced_mining', name:'Enhanced Mining', branch:'economy', tier:1, cost:{credits:200, gems:0}, time:60, effects:{miningBonus:15}, requires:[] },
deep_core_drills: { id:'deep_core_drills', name:'Deep-Core Drills', branch:'economy', tier:3, cost:{credits:2500, gems:5}, time:600, effects:{miningBonus:35}, requires:['enhanced_mining'] },
trade_protocols: { id:'trade_protocols', name:'Trade Protocols', branch:'economy', tier:2, cost:{credits:600, gems:0}, time:120, effects:{tradeFeeReduction:10}, requires:[] },
construction_eff: { id:'construction_eff', name:'Construction Efficiency', branch:'economy', tier:1, cost:{credits:350, gems:0}, time:60, effects:{buildTimeReduction:10}, requires:[] },
mass_production: { id:'mass_production', name:'Mass Production', branch:'economy', tier:4, cost:{credits:10000,gems:10},time:1800, effects:{buildTimeReduction:35}, requires:['construction_eff'] },
// ── Exploration ─────────────────────────────────────────────────────────
long_range_sensors:{ id:'long_range_sensors',name:'Long Range Sensors',branch:'exploration',tier:1, cost:{credits:300, gems:0}, time:60, effects:{sensorRange:2}, requires:[] },
stealth_systems: { id:'stealth_systems', name:'Stealth Systems', branch:'exploration',tier:3, cost:{credits:5000, gems:10},time:900, effects:{stealthRating:30}, requires:['long_range_sensors'] },
wormhole_nav: { id:'wormhole_nav', name:'Wormhole Navigation',branch:'exploration',tier:4, cost:{credits:8000, gems:15},time:1200, effects:{warpCooldown:50}, requires:['long_range_sensors'] },
// ── Defense ─────────────────────────────────────────────────────────────
point_defense: { id:'point_defense', name:'Point Defense', branch:'defense', tier:1, cost:{credits:400, gems:0}, time:60, effects:{missileDefense:20}, requires:[] },
heavy_armor_plating:{ id:'heavy_armor_plating', name:'Heavy Armor Plating', branch:'defense', tier:4, cost:{credits:12000,gems:15},time:1800, effects:{armorBonus:80}, requires:['reactive_armor'] },
auto_repair: { id:'auto_repair', name:'Auto-Repair Drones', branch:'defense', tier:3, cost:{credits:4000, gems:5}, time:720, effects:{hullRegen:2}, requires:['shield_matrix'] },
};
class ResearchSystem {
constructor() {
this.tree = RESEARCH_TREE;
}
getTree() { return Object.values(this.tree); }
/** Return what a player can currently research */
getAvailableResearch(playerData) {
const completed = new Set(playerData.research?.completed || []);
const inProgress = playerData.research?.inProgress || null;
return Object.values(this.tree).map(tech => ({
...tech,
status: completed.has(tech.id) ? 'completed'
: inProgress?.techId === tech.id ? 'in_progress'
: tech.requires.every(r => completed.has(r)) ? 'available'
: 'locked',
progressPercent: inProgress?.techId === tech.id
? Math.floor(((Date.now() - inProgress.startedAt) / (tech.time * 1000)) * 100)
: 0,
}));
}
/** Start researching a technology */
startResearch(playerData, techId) {
const tech = this.tree[techId];
if (!tech) throw new Error('Unknown technology');
const completed = new Set(playerData.research?.completed || []);
if (completed.has(techId)) throw new Error('Already researched');
if (playerData.research?.inProgress) throw new Error('Research already in progress');
if (!tech.requires.every(r => completed.has(r))) throw new Error('Prerequisites not met');
const stats = playerData.stats || {};
if ((stats.credits || 0) < tech.cost.credits) throw new Error(`Need ${tech.cost.credits} credits`);
if ((stats.gems || 0) < tech.cost.gems) throw new Error(`Need ${tech.cost.gems} gems`);
stats.credits = (stats.credits || 0) - tech.cost.credits;
stats.gems = (stats.gems || 0) - tech.cost.gems;
playerData.stats = stats;
playerData.research = playerData.research || { completed: [], inProgress: null, effects: {} };
playerData.research.inProgress = { techId, startedAt: Date.now(), completesAt: Date.now() + tech.time * 1000 };
return { tech, completesAt: playerData.research.inProgress.completesAt };
}
/** Check and resolve completed research — call on tick or on request */
checkCompletion(playerData) {
const ip = playerData.research?.inProgress;
if (!ip || Date.now() < ip.completesAt) return null;
const tech = this.tree[ip.techId];
playerData.research.completed = playerData.research.completed || [];
playerData.research.completed.push(ip.techId);
playerData.research.inProgress = null;
// Apply effects
playerData.research.effects = playerData.research.effects || {};
for (const [k, v] of Object.entries(tech.effects || {})) {
playerData.research.effects[k] = (playerData.research.effects[k] || 0) + v;
}
return tech;
}
/** Cancel in-progress research — refund 75% */
cancelResearch(playerData) {
const ip = playerData.research?.inProgress;
if (!ip) throw new Error('No research in progress');
const tech = this.tree[ip.techId];
playerData.stats.credits += Math.floor(tech.cost.credits * 0.75);
playerData.stats.gems += Math.floor(tech.cost.gems * 0.75);
playerData.research.inProgress = null;
return tech;
}
}
module.exports = { ResearchSystem, RESEARCH_TREE };