#include "wave.h" #include "game_state.h" #include "components.h" #include "entity_factory.h" #include "utils.h" #define NUM_WAVES 14 EnemyWaves getDefaultWaves() { static WaveData waves[NUM_WAVES] = { { 0, 0.0f, 5, 1.0f, 0, 5 * 60 }, { 0, 0.0f, 20, 2.0f, 0, 1.5f * 60 }, { 5, 0.2f, 30, 2.2f, 0, 30 }, { 10, 0.5f, 40, 2.4f, 0, 20 }, { 20, 1.0f, 60, 2.6f, 0, 20 }, { 40, 1.4f, 80, 2.8f, 0, 10 }, { 60, 1.5f, 100, 3.0f, 0, 10 }, { 80, 1.6f, 120, 3.2f, 0, 10 }, { 100, 1.8f, 160, 3.4f, 0, 5 }, { 120, 2.0f, 200, 3.5f, 0, 5 }, { 180, 2.2f, 250, 3.8f, 0, 5 }, { 220, 2.5f, 300, 4.0f, 0, 5 }, { 250, 3.0f, 350, 4.2f, 0, 5 }, { 300, 4.0f, 400, 4.5f, 0, 5 }, }; return (EnemyWaves) { .numWaves = NUM_WAVES, .waves = waves }; } EnemyWaves getMainMenuWaves() { static WaveData waves[1] = { { 100000, 0.2f, 2000000, 0.8f, 0, 0 } }; return (EnemyWaves) { .numWaves = 1, .waves = waves }; } WaveInfo getWaveInfo(const EnemyWaves *waves, i32 idx) { BZ_ASSERT(idx >= 0); WaveData waveData; if (idx >= waves->numWaves) { waveData = waves->waves[waves->numWaves - 1]; waveData.difficultyScale += (idx - waves->numWaves) * 0.1f; } else { waveData = waves->waves[idx]; waveData.timeBeforeStart = waves->waves[idx].timeBeforeStart; } WaveInfo info = { .number = idx, .data = waveData, .orcsToSend = waveData.numOrcs, .goblinsToSend = waveData.numGoblins, }; return info; } static Vector2 randomizeSpawnPos(Vector2 spawnPoint, i32 range) { spawnPoint.x += randFloatRange(-range, range); spawnPoint.y += randFloatRange(-range, range); return spawnPoint; } void updateWave(WaveInfo *wave, Game *game, f32 dt) { wave->elapsed += dt; if (wave->elapsed < wave->data.timeBeforeStart) return; wave->started = true; wave->orcsElapsed += dt; wave->goblinsElapsed += dt; f32 timeForGoblin = 1.0f / wave->data.goblinSendRate; while (wave->goblinsElapsed >= timeForGoblin) { Vector2 spawnPos = randomizeSpawnPos(game->swarmSpawn, 20); entityCreate(ENTITY_GOBLIN, spawnPos, PLAYER_ENEMY, game); wave->goblinsElapsed -= timeForGoblin; wave->goblinsToSend--; } f32 timeForOrc = 1.0f / wave->data.orcSendRate; while (wave->orcsElapsed >= timeForOrc) { Vector2 spawnPos = randomizeSpawnPos(game->swarmSpawn, 20); entityCreate(ENTITY_ORC, spawnPos, PLAYER_ENEMY, game); wave->orcsElapsed -= timeForOrc; wave->orcsToSend--; } } bool isWaveSendingOver(const WaveInfo *wave) { return wave->orcsToSend == 0 && wave->goblinsToSend == 0; } bool isWaveOver(const WaveInfo *wave) { if (!isWaveSendingOver(wave)) return false; return wave->started && ecs_count_id(ECS, ecs_id(Swarm)) == 0; }