114 lines
3.5 KiB
C
114 lines
3.5 KiB
C
#include "wave.h"
|
|
#include "game_state.h"
|
|
#include "components.h"
|
|
#include "entity_factory.h"
|
|
#include "utils.h"
|
|
|
|
#define NUM_WAVES 15
|
|
|
|
EnemyWaves getDefaultWaves() {
|
|
static WaveData waves[NUM_WAVES] = {
|
|
{ 0, 0.0f, 0, 0.0f, 0, 0}, // Dummy wave
|
|
{ 0, 0.0f, 5, 1.0f, 0, 8 * 60},
|
|
{ 0, 0.0f, 20, 2.0f, 0, 3 * 60 },
|
|
{ 5, 0.2f, 30, 2.2f, 0, 60 },
|
|
{ 10, 0.5f, 40, 2.4f, 0, 40 },
|
|
{ 20, 1.0f, 60, 2.6f, 0, 30 },
|
|
{ 40, 1.4f, 80, 2.8f, 0, 20 },
|
|
{ 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.25f;
|
|
|
|
} 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->goblinsToSend > 0 && wave->goblinsElapsed >= timeForGoblin) {
|
|
Vector2 spawnPos = randomizeSpawnPos(game->swarmSpawn, 20);
|
|
ecs_entity_t e = entityCreate(ENTITY_GOBLIN, spawnPos, PLAYER_ENEMY, game);
|
|
ecs_set(ECS, e, Health, {
|
|
.startHP = 40.0f * (1 + wave->data.difficultyScale),
|
|
.hp = 40.0f * (1 + wave->data.difficultyScale),
|
|
.lastChanged = -1000.0f,
|
|
});
|
|
wave->goblinsElapsed -= timeForGoblin;
|
|
wave->goblinsToSend--;
|
|
}
|
|
|
|
f32 timeForOrc = 1.0f / wave->data.orcSendRate;
|
|
while (wave->orcsToSend > 0 && wave->orcsElapsed >= timeForOrc) {
|
|
Vector2 spawnPos = randomizeSpawnPos(game->swarmSpawn, 20);
|
|
ecs_entity_t e = entityCreate(ENTITY_ORC, spawnPos, PLAYER_ENEMY, game);
|
|
ecs_set(ECS, e, Health, {
|
|
.startHP = 80.0f * (1 + wave->data.difficultyScale),
|
|
.hp = 80.0f * (1 + wave->data.difficultyScale),
|
|
.lastChanged = -1000.0f,
|
|
});
|
|
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;
|
|
}
|
|
|