Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/FarmRaidSystem.js
2026-01-16 02:43:46 +01:00

393 lines
11 KiB
JavaScript

/**
* FARM RAID SYSTEM
* Spawn raider waves, defend farm, rewards
* Integrates with DefenseSystem and NomadRaiderAI
*/
export class FarmRaidSystem {
constructor(scene) {
this.scene = scene;
// Raid state
this.isRaidActive = false;
this.currentWave = 0;
this.totalWaves = 0;
this.raidDifficulty = 1;
// Spawn management
this.activeRaiders = [];
this.spawnPoints = [];
// Raid triggers
this.fameThreshold = 500; // Trigger raid at 500 fame
this.resourceThreshold = 5000; // Or 5000 resources
this.timeBetweenRaids = 600000; // 10 minutes minimum
this.lastRaidTime = 0;
// Rewards
this.defenseRewards = new Map();
this.init();
}
init() {
this.initializeSpawnPoints();
this.initializeRewards();
// Check for raid triggers periodically
this.scene.time.addEvent({
delay: 30000, // Check every 30s
callback: () => this.checkRaidTriggers(),
loop: true
});
}
/**
* Initialize raid spawn points around farm
*/
initializeSpawnPoints() {
const farmCenter = { x: 400, y: 300 }; // Adjust to actual farm center
const spawnDistance = 400;
// 8 spawn points around farm (N, NE, E, SE, S, SW, W, NW)
for (let angle = 0; angle < 360; angle += 45) {
const rad = Phaser.Math.DegToRad(angle);
this.spawnPoints.push({
x: farmCenter.x + Math.cos(rad) * spawnDistance,
y: farmCenter.y + Math.sin(rad) * spawnDistance,
angle: angle
});
}
}
/**
* Initialize defense rewards
*/
initializeRewards() {
this.defenseRewards.set(1, { xp: 200, currency: 500, items: ['raider_loot_common'] });
this.defenseRewards.set(2, { xp: 400, currency: 1000, items: ['raider_loot_common', 'raider_weapon'] });
this.defenseRewards.set(3, { xp: 800, currency: 2000, items: ['raider_loot_rare', 'raider_armor'] });
}
/**
* Check if raid should trigger
*/
checkRaidTriggers() {
if (this.isRaidActive) return;
const now = Date.now();
const timeSinceLastRaid = now - this.lastRaidTime;
// Cooldown check
if (timeSinceLastRaid < this.timeBetweenRaids) return;
const fame = this.scene.gameState?.fame || 0;
const totalResources = this.scene.inventorySystem?.getTotalResourceValue() || 0;
// Trigger conditions
if (fame >= this.fameThreshold || totalResources >= this.resourceThreshold) {
this.startRaid();
}
}
/**
* Start a raid
*/
startRaid(difficulty = null) {
if (this.isRaidActive) return;
this.isRaidActive = true;
this.currentWave = 0;
this.raidDifficulty = difficulty || this.calculateDifficulty();
this.totalWaves = 2 + this.raidDifficulty; // 3-5 waves
this.lastRaidTime = Date.now();
// Notification
this.scene.uiSystem?.showNotification(
`RAID INCOMING! ${this.totalWaves} waves approaching!`,
'danger',
{ priority: 'high' }
);
// SFX: Raid horn
this.scene.soundSystem?.play('raid_horn');
// VFX: Red screen flash
this.scene.cameras.main.flash(1000, 255, 0, 0);
// Start first wave
this.scene.time.delayedCall(3000, () => this.spawnWave());
console.log(`🚨 RAID STARTED: Difficulty ${this.raidDifficulty}, ${this.totalWaves} waves`);
}
/**
* Calculate raid difficulty based on game progress
*/
calculateDifficulty() {
const fame = this.scene.gameState?.fame || 0;
const population = this.scene.gameState?.population || 0;
// Scale difficulty
return Math.min(5, Math.floor((fame / 500) + (population / 20)));
}
/**
* Spawn a wave of raiders
*/
spawnWave() {
this.currentWave++;
const raiderCount = 3 + (this.raidDifficulty * 2); // 5-13 raiders
const waveRaiders = [];
// Spawn raiders
for (let i = 0; i < raiderCount; i++) {
const spawnPoint = Phaser.Utils.Array.GetRandom(this.spawnPoints);
const raider = this.spawnRaider(spawnPoint.x, spawnPoint.y);
waveRaiders.push(raider);
}
this.activeRaiders.push(...waveRaiders);
// Notification
this.scene.uiSystem?.showNotification(
`Wave ${this.currentWave}/${this.totalWaves}: ${raiderCount} raiders!`,
'warning'
);
console.log(`🔥 Wave ${this.currentWave}: Spawned ${raiderCount} raiders`);
// Check for next wave
this.scene.time.delayedCall(5000, () => this.checkWaveProgress());
}
/**
* Spawn individual raider
*/
spawnRaider(x, y) {
// Create raider sprite
const raider = this.scene.physics.add.sprite(x, y, 'nomad_raider');
// Stats based on difficulty
raider.maxHealth = 50 + (this.raidDifficulty * 20);
raider.health = raider.maxHealth;
raider.attackDamage = 10 + (this.raidDifficulty * 5);
raider.active = true;
// Add AI
raider.ai = new NomadRaiderAI(this.scene, raider);
// Collisions
this.scene.physics.add.collider(raider, this.scene.player);
this.scene.physics.add.collider(raider, this.scene.zombieScout);
// Health bar
raider.healthBar = this.scene.add.graphics();
// Death handler
raider.takeDamage = (amount) => this.raiderTakeDamage(raider, amount);
return raider;
}
/**
* Raider takes damage
*/
raiderTakeDamage(raider, amount) {
raider.health -= amount;
// Update health bar
this.updateRaiderHealthBar(raider);
// VFX
raider.setTint(0xff0000);
this.scene.time.delayedCall(100, () => raider.clearTint());
// Death
if (raider.health <= 0) {
this.raiderDeath(raider);
}
}
/**
* Raider death
*/
raiderDeath(raider) {
raider.active = false;
// Drop loot
this.dropRaiderLoot(raider.x, raider.y);
// VFX
this.scene.vfxSystem?.playEffect('raider_death', raider.x, raider.y);
// Remove from active list
const index = this.activeRaiders.indexOf(raider);
if (index > -1) {
this.activeRaiders.splice(index, 1);
}
// Cleanup
raider.ai?.destroy();
raider.healthBar?.destroy();
raider.destroy();
// Check if wave complete
this.checkWaveProgress();
}
/**
* Update raider health bar
*/
updateRaiderHealthBar(raider) {
if (!raider.healthBar) return;
raider.healthBar.clear();
const barWidth = 40;
const barHeight = 4;
const healthPercent = raider.health / raider.maxHealth;
// Background
raider.healthBar.fillStyle(0x000000);
raider.healthBar.fillRect(raider.x - barWidth / 2, raider.y - 30, barWidth, barHeight);
// Health
raider.healthBar.fillStyle(0xff0000);
raider.healthBar.fillRect(raider.x - barWidth / 2, raider.y - 30, barWidth * healthPercent, barHeight);
}
/**
* Drop loot from raider
*/
dropRaiderLoot(x, y) {
const lootTable = ['wood', 'stone', 'metal', 'raider_weapon', 'medicine'];
const drop = Phaser.Utils.Array.GetRandom(lootTable);
const amount = Phaser.Math.Between(1, 5);
// Create loot drop
this.scene.lootSystem?.createDrop(x, y, drop, amount);
}
/**
* Check if wave is complete
*/
checkWaveProgress() {
if (!this.isRaidActive) return;
const aliveRaiders = this.activeRaiders.filter(r => r.active);
if (aliveRaiders.length === 0) {
// Wave complete
if (this.currentWave < this.totalWaves) {
// Next wave
this.scene.uiSystem?.showNotification(
`Wave ${this.currentWave} cleared! Next wave incoming...`,
'success'
);
this.scene.time.delayedCall(5000, () => this.spawnWave());
} else {
// Raid complete
this.endRaid(true);
}
}
}
/**
* End raid (success or failure)
*/
endRaid(success) {
this.isRaidActive = false;
if (success) {
// Victory!
const rewards = this.defenseRewards.get(this.raidDifficulty) || this.defenseRewards.get(1);
this.scene.uiSystem?.showNotification(
`RAID DEFENDED! +${rewards.xp} XP, +${rewards.currency} coins`,
'victory',
{ priority: 'high' }
);
// Grant rewards
this.scene.zombieScoutLeveling?.awardXP(rewards.xp, 'raid_defense');
this.scene.economySystem?.addCurrency(rewards.currency);
rewards.items.forEach(item => {
this.scene.inventorySystem?.addItem(item, 1);
});
// VFX
this.scene.vfxSystem?.playEffect('victory', 400, 300);
this.scene.cameras.main.flash(1000, 0, 255, 0);
console.log(`✅ RAID DEFENDED! Rewards granted.`);
} else {
// Defeat
this.scene.uiSystem?.showNotification(
'RAID DEFEATED YOU! Farm damaged.',
'defeat',
{ priority: 'high' }
);
// Damage farm buildings
this.damageFarm();
console.log(`❌ RAID FAILED! Farm damaged.`);
}
// Cleanup remaining raiders
this.activeRaiders.forEach(raider => {
raider.ai?.destroy();
raider.healthBar?.destroy();
raider.destroy();
});
this.activeRaiders = [];
}
/**
* Damage farm on raid failure
*/
damageFarm() {
// Damage random buildings
const buildings = this.scene.buildingSystem?.getAllBuildings() || [];
const damagedCount = Math.min(3, buildings.length);
for (let i = 0; i < damagedCount; i++) {
const building = Phaser.Utils.Array.GetRandom(buildings);
building.takeDamage?.(50);
}
// Destroy random crops
const crops = this.scene.crops || [];
const destroyedCrops = Math.min(10, crops.length);
for (let i = 0; i < destroyedCrops; i++) {
const crop = Phaser.Utils.Array.GetRandom(crops);
crop.destroy?.();
}
}
/**
* Manual raid trigger (for testing/quests)
*/
triggerRaid(difficulty = 1) {
this.startRaid(difficulty);
}
/**
* Get raid state
*/
getRaidState() {
return {
isActive: this.isRaidActive,
currentWave: this.currentWave,
totalWaves: this.totalWaves,
difficulty: this.raidDifficulty,
activeRaiders: this.activeRaiders.filter(r => r.active).length
};
}
}