102 lines
3.1 KiB
C
102 lines
3.1 KiB
C
struct LevelDef {
|
|
u8 drones, gunners, hunters, builders;
|
|
u8 bossHp;
|
|
u8 humans;
|
|
u8 gunnerPattern; // 0=radial, 1=aimed fan, 2=mix
|
|
bool dronesShoot;
|
|
};
|
|
|
|
// dr gn hn bl boss hum pat shoot
|
|
const struct LevelDef levels[30] = {
|
|
// Phase 1: "Immediate danger" (L1-L6)
|
|
{ 8, 1, 0, 0, 0, 8, 0, FALSE }, // L1
|
|
{ 10, 2, 0, 0, 0, 8, 0, TRUE }, // L2
|
|
{ 12, 2, 0, 0, 0, 8, 0, TRUE }, // L3
|
|
{ 10, 3, 0, 0, 0, 8, 1, TRUE }, // L4
|
|
{ 14, 3, 0, 0, 0, 8, 1, TRUE }, // L5
|
|
{ 8, 0, 0, 0, 8, 8, 0, TRUE }, // L6 BOSS
|
|
|
|
// Phase 2: "You can't save everything" (L7-L12)
|
|
{ 10, 0, 0, 1, 0, 8, 0, TRUE }, // L7
|
|
{ 10, 2, 0, 1, 0, 8, 0, TRUE }, // L8
|
|
{ 12, 0, 0, 2, 0, 8, 0, TRUE }, // L9
|
|
{ 14, 3, 0, 1, 0, 8, 1, TRUE }, // L10 WALL
|
|
{ 10, 2, 0, 2, 0, 8, 2, TRUE }, // L11
|
|
{ 8, 0, 0, 1, 12, 8, 0, TRUE }, // L12 BOSS
|
|
|
|
// Phase 3: "Geometry matters" (L13-L18)
|
|
{ 8, 0, 4, 0, 0, 8, 0, TRUE }, // L13
|
|
{ 8, 3, 2, 0, 0, 8, 1, TRUE }, // L14
|
|
{ 16, 0, 0, 0, 0, 8, 0, TRUE }, // L15 FARM
|
|
{ 10, 2, 4, 0, 0, 8, 2, TRUE }, // L16
|
|
{ 12, 3, 3, 0, 0, 8, 1, TRUE }, // L17
|
|
{ 0, 2, 2, 0, 15, 8, 2, TRUE }, // L18 BOSS
|
|
|
|
// Phase 4: "Suffocation" (L19-L24)
|
|
{ 12, 4, 0, 0, 0, 8, 2, TRUE }, // L19
|
|
{ 14, 4, 0, 2, 0, 8, 2, TRUE }, // L20 WALL
|
|
{ 10, 0, 6, 0, 0, 8, 0, TRUE }, // L21
|
|
{ 12, 4, 2, 0, 0, 8, 1, TRUE }, // L22
|
|
{ 14, 4, 0, 2, 0, 8, 2, TRUE }, // L23
|
|
{ 0, 3, 0, 1, 20, 8, 2, TRUE }, // L24 BOSS
|
|
|
|
// Phase 5: "Arcade cruelty" (L25-L30)
|
|
{ 16, 0, 4, 0, 0, 8, 0, TRUE }, // L25
|
|
{ 12, 6, 0, 0, 0, 8, 2, TRUE }, // L26
|
|
{ 14, 2, 4, 0, 0, 8, 1, TRUE }, // L27
|
|
{ 16, 4, 0, 2, 0, 8, 2, TRUE }, // L28
|
|
{ 6, 2, 2, 1, 10, 8, 2, TRUE }, // L29 MINI-BOSS
|
|
{ 4, 2, 2, 1, 30, 8, 2, TRUE }, // L30 FINAL
|
|
};
|
|
|
|
#define LEVEL_COUNT 30
|
|
|
|
static void distributeEnemies(u8 type, u8 count){
|
|
for(u8 i = 0; i < count; i++){
|
|
u8 zone = i % 4;
|
|
spawnEnemy(type, zone);
|
|
}
|
|
}
|
|
|
|
void loadLevel(u8 lvl){
|
|
if(lvl >= LEVEL_COUNT) lvl = LEVEL_COUNT - 1;
|
|
level = lvl;
|
|
const struct LevelDef* def = &levels[lvl];
|
|
|
|
distributeEnemies(ENEMY_TYPE_DRONE, def->drones);
|
|
distributeEnemies(ENEMY_TYPE_GUNNER, def->gunners);
|
|
distributeEnemies(ENEMY_TYPE_HUNTER, def->hunters);
|
|
distributeEnemies(ENEMY_TYPE_BUILDER, def->builders);
|
|
|
|
// set gunner pattern based on level def
|
|
for(s16 i = 0; i < ENEMY_COUNT; i++){
|
|
if(enemies[i].active && enemies[i].type == ENEMY_TYPE_GUNNER){
|
|
if(def->gunnerPattern == 2)
|
|
enemies[i].ints[0] = random() % 2;
|
|
else
|
|
enemies[i].ints[0] = def->gunnerPattern;
|
|
}
|
|
}
|
|
|
|
if(def->bossHp > 0){
|
|
pendingBossHp = def->bossHp;
|
|
spawnEnemy(ENEMY_TYPE_BOSS, 1);
|
|
}
|
|
|
|
// spawn humans
|
|
u8 humansToSpawn = def->humans;
|
|
for(u8 zone = 0; zone < 4 && humansToSpawn > 0; zone++){
|
|
u8 perZone = humansToSpawn >= 4 ? 2 : 1;
|
|
for(u8 h = 0; h < perZone && humansToSpawn > 0; h++){
|
|
spawnHuman(zone);
|
|
humansToSpawn--;
|
|
}
|
|
}
|
|
|
|
loadMap();
|
|
}
|
|
|
|
// legacy test stage
|
|
void loadStage(){
|
|
loadLevel(0);
|
|
}
|