Files
PixelDefense/game/wave.c

92 lines
2.5 KiB
C

#include "wave.h"
#include "game_state.h"
#include "components.h"
#include "entity_factory.h"
#include "utils.h"
#define NUM_WAVES 5
EnemyWaves getDefaultWaves() {
static WaveData waves[NUM_WAVES] = {
{ 10, 1.0f, 20, 2.0f, 0, 5 * 60 },
{ 20, 1.0f, 40, 2.0f, 0, 2 * 60 },
{ 25, 1.0f, 80, 2.2f, 0, 2 * 60 },
{ 50, 1.2f, 120, 3.0f, 0, 1.5f * 60 },
{ 100, 2.0f, 220, 4.0f, 0, 1.0f * 60 },
};
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];
}
WaveInfo info = {
.number = idx,
.data = waveData,
.orcsToSend = waveData.numOrcs,
.goblinsToSend = waveData.numGoblins,
};
info.data.timeBeforeStart /= 60;
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;
if (wave->goblinsElapsed >= timeForGoblin) {
Vector2 spawnPos = randomizeSpawnPos(game->swarmSpawn, 20);
entityCreate(ENTITY_GOBLIN, spawnPos, PLAYER_ENEMY, game);
wave->goblinsElapsed -= timeForGoblin;
}
f32 timeForOrc = 1.0f / wave->data.orcSendRate;
if (wave->orcsElapsed >= timeForOrc) {
Vector2 spawnPos = randomizeSpawnPos(game->swarmSpawn, 20);
entityCreate(ENTITY_ORC, spawnPos, PLAYER_ENEMY, game);
wave->orcsElapsed -= timeForOrc;
}
}
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;
}