feat: implement comprehensive combat system with plugin architecture
- Complete combat system with instant, turn-based, and tactical combat - Plugin-based architecture with CombatPluginManager for extensibility - Real-time combat events via WebSocket - Fleet vs fleet and fleet vs colony combat support - Comprehensive combat statistics and history tracking - Admin panel for combat management and configuration - Database migrations for combat tables and fleet system - Complete test suite for combat functionality - Combat middleware for validation and logging - Service locator pattern for dependency management Combat system features: • Multiple combat resolution types with plugin support • Real-time combat events and spectator support • Detailed combat logs and casualty calculations • Experience gain and veterancy system for ships • Fleet positioning and tactical formations • Combat configurations and modifiers • Queue system for battle processing • Comprehensive admin controls and monitoring 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1a60cf55a3
commit
8d9ef427be
37 changed files with 13302 additions and 26 deletions
314
scripts/setup-combat.js
Normal file
314
scripts/setup-combat.js
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Combat System Setup Script
|
||||
* Initializes combat configurations and sample data
|
||||
*/
|
||||
|
||||
const db = require('../src/database/connection');
|
||||
const logger = require('../src/utils/logger');
|
||||
|
||||
async function setupCombatSystem() {
|
||||
try {
|
||||
console.log('🚀 Setting up combat system...');
|
||||
|
||||
// Insert default combat configurations
|
||||
console.log('📝 Adding default combat configurations...');
|
||||
|
||||
const existingConfigs = await db('combat_configurations').select('id');
|
||||
if (existingConfigs.length === 0) {
|
||||
await db('combat_configurations').insert([
|
||||
{
|
||||
config_name: 'instant_combat',
|
||||
combat_type: 'instant',
|
||||
config_data: JSON.stringify({
|
||||
auto_resolve: true,
|
||||
preparation_time: 5,
|
||||
damage_variance: 0.15,
|
||||
experience_gain: 1.0,
|
||||
casualty_rate_min: 0.05,
|
||||
casualty_rate_max: 0.75,
|
||||
loot_multiplier: 1.0,
|
||||
spectator_limit: 50,
|
||||
priority: 100
|
||||
}),
|
||||
description: 'Standard instant combat resolution with quick results',
|
||||
is_active: true,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
},
|
||||
{
|
||||
config_name: 'turn_based_combat',
|
||||
combat_type: 'turn_based',
|
||||
config_data: JSON.stringify({
|
||||
auto_resolve: true,
|
||||
preparation_time: 10,
|
||||
max_rounds: 15,
|
||||
round_duration: 3,
|
||||
damage_variance: 0.2,
|
||||
experience_gain: 1.5,
|
||||
casualty_rate_min: 0.1,
|
||||
casualty_rate_max: 0.8,
|
||||
loot_multiplier: 1.2,
|
||||
spectator_limit: 100,
|
||||
priority: 150
|
||||
}),
|
||||
description: 'Detailed turn-based combat with round-by-round resolution',
|
||||
is_active: true,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
},
|
||||
{
|
||||
config_name: 'tactical_combat',
|
||||
combat_type: 'tactical',
|
||||
config_data: JSON.stringify({
|
||||
auto_resolve: true,
|
||||
preparation_time: 15,
|
||||
max_rounds: 20,
|
||||
round_duration: 4,
|
||||
damage_variance: 0.25,
|
||||
experience_gain: 2.0,
|
||||
casualty_rate_min: 0.15,
|
||||
casualty_rate_max: 0.85,
|
||||
loot_multiplier: 1.5,
|
||||
spectator_limit: 200,
|
||||
priority: 200
|
||||
}),
|
||||
description: 'Advanced tactical combat with positioning and formations',
|
||||
is_active: true,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('✅ Combat configurations added successfully');
|
||||
} else {
|
||||
console.log('ℹ️ Combat configurations already exist, skipping...');
|
||||
}
|
||||
|
||||
// Update combat types table with default plugin reference
|
||||
console.log('📝 Updating combat types...');
|
||||
|
||||
const existingCombatTypes = await db('combat_types').select('id');
|
||||
if (existingCombatTypes.length === 0) {
|
||||
await db('combat_types').insert([
|
||||
{
|
||||
name: 'instant_resolution',
|
||||
description: 'Basic instant combat resolution with detailed logs',
|
||||
plugin_name: 'instant_combat',
|
||||
config: JSON.stringify({
|
||||
calculate_experience: true,
|
||||
detailed_logs: true,
|
||||
enable_spectators: true
|
||||
}),
|
||||
is_active: true
|
||||
},
|
||||
{
|
||||
name: 'turn_based_resolution',
|
||||
description: 'Turn-based combat with round-by-round progression',
|
||||
plugin_name: 'turn_based_combat',
|
||||
config: JSON.stringify({
|
||||
calculate_experience: true,
|
||||
detailed_logs: true,
|
||||
enable_spectators: true,
|
||||
show_round_details: true
|
||||
}),
|
||||
is_active: true
|
||||
},
|
||||
{
|
||||
name: 'tactical_resolution',
|
||||
description: 'Advanced tactical combat with formations and positioning',
|
||||
plugin_name: 'tactical_combat',
|
||||
config: JSON.stringify({
|
||||
calculate_experience: true,
|
||||
detailed_logs: true,
|
||||
enable_spectators: true,
|
||||
enable_formations: true,
|
||||
enable_positioning: true
|
||||
}),
|
||||
is_active: true
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('✅ Combat types added successfully');
|
||||
} else {
|
||||
console.log('ℹ️ Combat types already exist, skipping...');
|
||||
}
|
||||
|
||||
// Ensure combat plugins are properly registered
|
||||
console.log('📝 Checking combat plugins...');
|
||||
|
||||
const combatPlugins = await db('plugins').where('plugin_type', 'combat');
|
||||
const pluginNames = combatPlugins.map(p => p.name);
|
||||
|
||||
const requiredPlugins = [
|
||||
{
|
||||
name: 'instant_combat',
|
||||
version: '1.0.0',
|
||||
description: 'Basic instant combat resolution system',
|
||||
plugin_type: 'combat',
|
||||
is_active: true,
|
||||
config: JSON.stringify({
|
||||
damage_variance: 0.15,
|
||||
experience_gain: 1.0
|
||||
}),
|
||||
dependencies: JSON.stringify([]),
|
||||
hooks: JSON.stringify(['pre_combat', 'post_combat', 'damage_calculation'])
|
||||
},
|
||||
{
|
||||
name: 'turn_based_combat',
|
||||
version: '1.0.0',
|
||||
description: 'Turn-based combat resolution system with detailed rounds',
|
||||
plugin_type: 'combat',
|
||||
is_active: true,
|
||||
config: JSON.stringify({
|
||||
max_rounds: 15,
|
||||
damage_variance: 0.2,
|
||||
experience_gain: 1.5
|
||||
}),
|
||||
dependencies: JSON.stringify([]),
|
||||
hooks: JSON.stringify(['pre_combat', 'post_combat', 'round_start', 'round_end', 'damage_calculation'])
|
||||
},
|
||||
{
|
||||
name: 'tactical_combat',
|
||||
version: '1.0.0',
|
||||
description: 'Advanced tactical combat with formations and positioning',
|
||||
plugin_type: 'combat',
|
||||
is_active: true,
|
||||
config: JSON.stringify({
|
||||
enable_formations: true,
|
||||
enable_positioning: true,
|
||||
damage_variance: 0.25,
|
||||
experience_gain: 2.0
|
||||
}),
|
||||
dependencies: JSON.stringify([]),
|
||||
hooks: JSON.stringify(['pre_combat', 'post_combat', 'formation_change', 'position_update', 'damage_calculation'])
|
||||
}
|
||||
];
|
||||
|
||||
for (const plugin of requiredPlugins) {
|
||||
if (!pluginNames.includes(plugin.name)) {
|
||||
await db('plugins').insert(plugin);
|
||||
console.log(`✅ Added combat plugin: ${plugin.name}`);
|
||||
} else {
|
||||
console.log(`ℹ️ Combat plugin ${plugin.name} already exists`);
|
||||
}
|
||||
}
|
||||
|
||||
// Add sample ship designs if none exist (for testing)
|
||||
console.log('📝 Checking for sample ship designs...');
|
||||
|
||||
const existingDesigns = await db('ship_designs').where('is_public', true);
|
||||
if (existingDesigns.length === 0) {
|
||||
await db('ship_designs').insert([
|
||||
{
|
||||
name: 'Basic Fighter',
|
||||
ship_class: 'fighter',
|
||||
hull_type: 'light',
|
||||
components: JSON.stringify({
|
||||
weapons: ['laser_cannon'],
|
||||
shields: ['basic_shield'],
|
||||
engines: ['ion_drive']
|
||||
}),
|
||||
stats: JSON.stringify({
|
||||
hp: 75,
|
||||
attack: 12,
|
||||
defense: 8,
|
||||
speed: 6
|
||||
}),
|
||||
cost: JSON.stringify({
|
||||
scrap: 80,
|
||||
energy: 40
|
||||
}),
|
||||
build_time: 20,
|
||||
is_public: true,
|
||||
is_active: true,
|
||||
hull_points: 75,
|
||||
shield_points: 20,
|
||||
armor_points: 5,
|
||||
attack_power: 12,
|
||||
attack_speed: 1.2,
|
||||
movement_speed: 6,
|
||||
cargo_capacity: 0,
|
||||
special_abilities: JSON.stringify([]),
|
||||
damage_resistances: JSON.stringify({}),
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
},
|
||||
{
|
||||
name: 'Heavy Cruiser',
|
||||
ship_class: 'cruiser',
|
||||
hull_type: 'heavy',
|
||||
components: JSON.stringify({
|
||||
weapons: ['plasma_cannon', 'missile_launcher'],
|
||||
shields: ['reinforced_shield'],
|
||||
engines: ['fusion_drive']
|
||||
}),
|
||||
stats: JSON.stringify({
|
||||
hp: 200,
|
||||
attack: 25,
|
||||
defense: 18,
|
||||
speed: 3
|
||||
}),
|
||||
cost: JSON.stringify({
|
||||
scrap: 300,
|
||||
energy: 180,
|
||||
rare_elements: 5
|
||||
}),
|
||||
build_time: 120,
|
||||
is_public: true,
|
||||
is_active: true,
|
||||
hull_points: 200,
|
||||
shield_points: 60,
|
||||
armor_points: 25,
|
||||
attack_power: 25,
|
||||
attack_speed: 0.8,
|
||||
movement_speed: 3,
|
||||
cargo_capacity: 50,
|
||||
special_abilities: JSON.stringify(['heavy_armor', 'shield_boost']),
|
||||
damage_resistances: JSON.stringify({
|
||||
kinetic: 0.1,
|
||||
energy: 0.05
|
||||
}),
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
}
|
||||
]);
|
||||
|
||||
console.log('✅ Added sample ship designs');
|
||||
} else {
|
||||
console.log('ℹ️ Ship designs already exist, skipping...');
|
||||
}
|
||||
|
||||
console.log('🎉 Combat system setup completed successfully!');
|
||||
console.log('');
|
||||
console.log('Combat system is now ready for use with:');
|
||||
console.log('- 3 combat configurations (instant, turn-based, tactical)');
|
||||
console.log('- 3 combat resolution plugins');
|
||||
console.log('- Sample ship designs for testing');
|
||||
console.log('');
|
||||
console.log('You can now:');
|
||||
console.log('• Create fleets and initiate combat via /api/combat/initiate');
|
||||
console.log('• View combat history via /api/combat/history');
|
||||
console.log('• Manage combat system via admin endpoints');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Combat system setup failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Main execution
|
||||
if (require.main === module) {
|
||||
setupCombatSystem()
|
||||
.then(() => {
|
||||
console.log('✨ Setup completed successfully');
|
||||
process.exit(0);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('💥 Setup failed:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { setupCombatSystem };
|
||||
Loading…
Add table
Add a link
Reference in a new issue