diff --git a/Makefile b/Makefile
index 4b488eb..b71aece 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
CXXFLAGS ?= -O2 -Wall -g
CXXFLAGS += `pkg-config --cflags sdl2 SDL2_image SDL2_mixer` -DLINUX
LIBS = `pkg-config --libs sdl2 SDL2_image SDL2_mixer`
-OBJS = ai.o aliens.o audio.o bullets.o cargo.o collectable.o comms.o debris.o events.o explosions.o game.o globals.o graphics.o init.o intermission.o loadSave.o messages.o misc.o missions.o player.o resources.o script.o shop.o Starfighter.o title.o weapons.o
+OBJS = aliens.o audio.o bullets.o cargo.o collectable.o comms.o debris.o events.o explosions.o game.o globals.o graphics.o init.o intermission.o loadSave.o messages.o misc.o missions.o player.o resources.o script.o shop.o Starfighter.o title.o weapons.o
VERSION = 1.3-dev
PROG = starfighter
diff --git a/src/Starfighter.cpp b/src/Starfighter.cpp
index cb2691f..52d4777 100644
--- a/src/Starfighter.cpp
+++ b/src/Starfighter.cpp
@@ -112,7 +112,683 @@ int main(int argc, char **argv)
initWeapons();
initVars();
- defineAliens();
+
+ // Dual Plasma Fighter.
+ defEnemy[CD_DUALFIGHTER].classDef = CD_DUALFIGHTER;
+ defEnemy[CD_DUALFIGHTER].AIType = AI_NORMAL;
+ defEnemy[CD_DUALFIGHTER].speed = 4;
+ defEnemy[CD_DUALFIGHTER].maxShield = 5;
+ defEnemy[CD_DUALFIGHTER].shield = 5;
+ defEnemy[CD_DUALFIGHTER].imageIndex[0] = 2;
+ defEnemy[CD_DUALFIGHTER].imageIndex[1] = 3;
+ defEnemy[CD_DUALFIGHTER].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_DUALFIGHTER].weaponType[1] = W_ROCKETS;
+ defEnemy[CD_DUALFIGHTER].chance[0] = 100;
+ defEnemy[CD_DUALFIGHTER].chance[1] = 1;
+ defEnemy[CD_DUALFIGHTER].score = 25;
+ defEnemy[CD_DUALFIGHTER].collectChance = 50;
+ defEnemy[CD_DUALFIGHTER].collectType = P_ANYTHING;
+ defEnemy[CD_DUALFIGHTER].collectValue = 50;
+ defEnemy[CD_DUALFIGHTER].flags = FL_WEAPCO;
+
+ // Missile Boat
+ defEnemy[CD_MISSILEBOAT].classDef = CD_MISSILEBOAT;
+ defEnemy[CD_MISSILEBOAT].AIType = AI_DEFENSIVE;
+ defEnemy[CD_MISSILEBOAT].speed = 2;
+ defEnemy[CD_MISSILEBOAT].maxShield = 50;
+ defEnemy[CD_MISSILEBOAT].shield = 50;
+ defEnemy[CD_MISSILEBOAT].imageIndex[0] = 4;
+ defEnemy[CD_MISSILEBOAT].imageIndex[1] = 5;
+ defEnemy[CD_MISSILEBOAT].weaponType[0] = W_ROCKETS;
+ defEnemy[CD_MISSILEBOAT].weaponType[1] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_MISSILEBOAT].chance[0] = 25;
+ defEnemy[CD_MISSILEBOAT].chance[1] = 4;
+ defEnemy[CD_MISSILEBOAT].score = 250;
+ defEnemy[CD_MISSILEBOAT].collectChance = 25;
+ defEnemy[CD_MISSILEBOAT].collectType = P_ANYTHING;
+ defEnemy[CD_MISSILEBOAT].collectValue = 75;
+ defEnemy[CD_MISSILEBOAT].flags = FL_WEAPCO;
+
+ //Prototype fighter
+ defEnemy[CD_PROTOFIGHTER].classDef = CD_PROTOFIGHTER;
+ defEnemy[CD_PROTOFIGHTER].AIType = AI_DEFENSIVE;
+ defEnemy[CD_PROTOFIGHTER].speed = 5;
+ defEnemy[CD_PROTOFIGHTER].maxShield = 15;
+ defEnemy[CD_PROTOFIGHTER].shield = 15;
+ defEnemy[CD_PROTOFIGHTER].imageIndex[0] = 6;
+ defEnemy[CD_PROTOFIGHTER].imageIndex[1] = 7;
+ defEnemy[CD_PROTOFIGHTER].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_PROTOFIGHTER].weaponType[1] = P_ANYTHING;
+ defEnemy[CD_PROTOFIGHTER].chance[0] = 100;
+ defEnemy[CD_PROTOFIGHTER].chance[1] = 1;
+ defEnemy[CD_PROTOFIGHTER].score = 50;
+ defEnemy[CD_PROTOFIGHTER].collectChance = 50;
+ defEnemy[CD_PROTOFIGHTER].collectType = P_ANYTHING;
+ defEnemy[CD_PROTOFIGHTER].collectValue = 50;
+ defEnemy[CD_PROTOFIGHTER].flags = FL_WEAPCO;
+
+ // Phoebe and Ursula
+ defEnemy[CD_FRIEND].classDef = CD_FRIEND;
+ defEnemy[CD_FRIEND].AIType = AI_OFFENSIVE;
+ defEnemy[CD_FRIEND].speed = 3;
+ defEnemy[CD_FRIEND].maxShield = 50;
+ defEnemy[CD_FRIEND].shield = 50;
+ defEnemy[CD_FRIEND].imageIndex[0] = 20;
+ defEnemy[CD_FRIEND].imageIndex[1] = 21;
+ defEnemy[CD_FRIEND].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_FRIEND].weaponType[1] = W_HOMING_MISSILE;
+ defEnemy[CD_FRIEND].chance[0] = 100;
+ defEnemy[CD_FRIEND].chance[1] = 5;
+ defEnemy[CD_FRIEND].score = 0;
+ defEnemy[CD_FRIEND].collectChance = 0;
+ defEnemy[CD_FRIEND].collectType = P_CASH;
+ defEnemy[CD_FRIEND].collectValue = 0;
+ defEnemy[CD_FRIEND].flags = FL_FRIEND;
+
+ // Boss 1
+ defEnemy[CD_FRIGATE].classDef = CD_BOSS;
+ defEnemy[CD_FRIGATE].AIType = AI_NORMAL;
+ defEnemy[CD_FRIGATE].speed = 2;
+ defEnemy[CD_FRIGATE].maxShield = 550;
+ defEnemy[CD_FRIGATE].shield = 550;
+ defEnemy[CD_FRIGATE].imageIndex[0] = 8;
+ defEnemy[CD_FRIGATE].imageIndex[1] = 9;
+ defEnemy[CD_FRIGATE].weaponType[0] = W_MICRO_ROCKETS;
+ defEnemy[CD_FRIGATE].weaponType[1] = W_ENERGYRAY;
+ defEnemy[CD_FRIGATE].chance[0] = 100;
+ defEnemy[CD_FRIGATE].chance[1] = 85;
+ defEnemy[CD_FRIGATE].score = 500;
+ defEnemy[CD_FRIGATE].collectChance = 100;
+ defEnemy[CD_FRIGATE].collectType = P_CASH;
+ defEnemy[CD_FRIGATE].collectValue = 250;
+ defEnemy[CD_FRIGATE].flags = FL_WEAPCO;
+
+ defEnemy[CD_FRIGATE_WING1].classDef = CD_FRIGATE_WING1;
+ defEnemy[CD_FRIGATE_WING1].AIType = AI_NORMAL;
+ defEnemy[CD_FRIGATE_WING1].speed = 2;
+ defEnemy[CD_FRIGATE_WING1].maxShield = 100;
+ defEnemy[CD_FRIGATE_WING1].shield = 100;
+ defEnemy[CD_FRIGATE_WING1].imageIndex[0] = 10;
+ defEnemy[CD_FRIGATE_WING1].imageIndex[1] = 11;
+ defEnemy[CD_FRIGATE_WING1].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_FRIGATE_WING1].weaponType[1] = W_ROCKETS;
+ defEnemy[CD_FRIGATE_WING1].chance[0] = 100;
+ defEnemy[CD_FRIGATE_WING1].chance[1] = 10;
+ defEnemy[CD_FRIGATE_WING1].score = 500;
+ defEnemy[CD_FRIGATE_WING1].collectChance = 100;
+ defEnemy[CD_FRIGATE_WING1].collectType = P_ANYTHING;
+ defEnemy[CD_FRIGATE_WING1].collectValue = 250;
+ defEnemy[CD_FRIGATE_WING1].flags = FL_WEAPCO | FL_DAMAGEOWNER;
+
+ defEnemy[CD_FRIGATE_WING2].classDef = CD_FRIGATE_WING2;
+ defEnemy[CD_FRIGATE_WING2].AIType = AI_NORMAL;
+ defEnemy[CD_FRIGATE_WING2].speed = 2;
+ defEnemy[CD_FRIGATE_WING2].maxShield = 100;
+ defEnemy[CD_FRIGATE_WING2].shield = 100;
+ defEnemy[CD_FRIGATE_WING2].imageIndex[0] = 12;
+ defEnemy[CD_FRIGATE_WING2].imageIndex[1] = 13;
+ defEnemy[CD_FRIGATE_WING2].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_FRIGATE_WING2].weaponType[1] = W_ROCKETS;
+ defEnemy[CD_FRIGATE_WING2].chance[0] = 100;
+ defEnemy[CD_FRIGATE_WING2].chance[1] = 10;
+ defEnemy[CD_FRIGATE_WING2].score = 500;
+ defEnemy[CD_FRIGATE_WING2].collectChance = 100;
+ defEnemy[CD_FRIGATE_WING2].collectType = P_ANYTHING;
+ defEnemy[CD_FRIGATE_WING2].collectValue = 250;
+ defEnemy[CD_FRIGATE_WING2].flags = FL_WEAPCO | FL_DAMAGEOWNER;
+
+ // Transport ship
+ defEnemy[CD_TRANSPORTSHIP].classDef = CD_TRANSPORTSHIP;
+ defEnemy[CD_TRANSPORTSHIP].AIType = AI_EVASIVE;
+ defEnemy[CD_TRANSPORTSHIP].speed = 4;
+ defEnemy[CD_TRANSPORTSHIP].maxShield = 10;
+ defEnemy[CD_TRANSPORTSHIP].shield = 10;
+ defEnemy[CD_TRANSPORTSHIP].imageIndex[0] = 14;
+ defEnemy[CD_TRANSPORTSHIP].imageIndex[1] = 15;
+ defEnemy[CD_TRANSPORTSHIP].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_TRANSPORTSHIP].weaponType[1] = W_DOUBLE_SHOT;
+ defEnemy[CD_TRANSPORTSHIP].chance[0] = 0;
+ defEnemy[CD_TRANSPORTSHIP].chance[1] = 0;
+ defEnemy[CD_TRANSPORTSHIP].score = 25;
+ defEnemy[CD_TRANSPORTSHIP].collectChance = 100;
+ defEnemy[CD_TRANSPORTSHIP].collectType = P_WEAPONS;
+ defEnemy[CD_TRANSPORTSHIP].collectValue = 30;
+ defEnemy[CD_TRANSPORTSHIP].flags = FL_WEAPCO | FL_NOFIRE;
+
+ // Cargo ship
+ defEnemy[CD_CARGOSHIP].classDef = CD_CARGOSHIP;
+ defEnemy[CD_CARGOSHIP].AIType = AI_EVASIVE;
+ defEnemy[CD_CARGOSHIP].speed = 4;
+ defEnemy[CD_CARGOSHIP].maxShield = 10;
+ defEnemy[CD_CARGOSHIP].shield = 10;
+ defEnemy[CD_CARGOSHIP].imageIndex[0] = 22;
+ defEnemy[CD_CARGOSHIP].imageIndex[1] = 23;
+ defEnemy[CD_CARGOSHIP].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_CARGOSHIP].weaponType[1] = W_DOUBLE_SHOT;
+ defEnemy[CD_CARGOSHIP].chance[0] = 0;
+ defEnemy[CD_CARGOSHIP].chance[1] = 0;
+ defEnemy[CD_CARGOSHIP].score = 25;
+ defEnemy[CD_CARGOSHIP].collectChance = 50;
+ defEnemy[CD_CARGOSHIP].collectType = P_ANYTHING;
+ defEnemy[CD_CARGOSHIP].collectValue = 100;
+ defEnemy[CD_CARGOSHIP].flags = FL_WEAPCO | FL_NOFIRE;
+
+ // Weapco Miner
+ defEnemy[CD_MINER].classDef = CD_MINER;
+ defEnemy[CD_MINER].AIType = AI_EVASIVE;
+ defEnemy[CD_MINER].speed = 4;
+ defEnemy[CD_MINER].maxShield = 25;
+ defEnemy[CD_MINER].shield = 25;
+ defEnemy[CD_MINER].imageIndex[0] = 16;
+ defEnemy[CD_MINER].imageIndex[1] = 17;
+ defEnemy[CD_MINER].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_MINER].weaponType[1] = W_DOUBLE_SHOT;
+ defEnemy[CD_MINER].chance[0] = 0;
+ defEnemy[CD_MINER].chance[1] = 0;
+ defEnemy[CD_MINER].score = 100;
+ defEnemy[CD_MINER].collectChance = 100;
+ defEnemy[CD_MINER].collectType = P_ANYTHING;
+ defEnemy[CD_MINER].collectValue = 30;
+ defEnemy[CD_MINER].flags = FL_WEAPCO | FL_NOFIRE | FL_DROPMINES;
+
+ // Kline
+ defEnemy[CD_KLINE].classDef = CD_KLINE;
+ defEnemy[CD_KLINE].AIType = AI_OFFENSIVE;
+ defEnemy[CD_KLINE].speed = 5;
+ defEnemy[CD_KLINE].maxShield = 750;
+ defEnemy[CD_KLINE].shield = 750;
+ defEnemy[CD_KLINE].imageIndex[0] = 18;
+ defEnemy[CD_KLINE].imageIndex[1] = 19;
+ defEnemy[CD_KLINE].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_KLINE].weaponType[1] = W_MICRO_ROCKETS;
+ defEnemy[CD_KLINE].chance[0] = 100;
+ defEnemy[CD_KLINE].chance[1] = 2;
+ defEnemy[CD_KLINE].score = 0;
+ defEnemy[CD_KLINE].collectChance = 0;
+ defEnemy[CD_KLINE].collectType = P_ANYTHING;
+ defEnemy[CD_KLINE].collectValue = 0;
+ defEnemy[CD_KLINE].flags = FL_WEAPCO | FL_CANNOTDIE | FL_ALWAYSFACE | FL_CIRCLES;
+
+ // Aim Fighter
+ defEnemy[CD_AIMFIGHTER].classDef = CD_AIMFIGHTER;
+ defEnemy[CD_AIMFIGHTER].AIType = AI_NORMAL;
+ defEnemy[CD_AIMFIGHTER].speed = 3;
+ defEnemy[CD_AIMFIGHTER].maxShield = 15;
+ defEnemy[CD_AIMFIGHTER].shield = 15;
+ defEnemy[CD_AIMFIGHTER].imageIndex[0] = 8;
+ defEnemy[CD_AIMFIGHTER].imageIndex[1] = 9;
+ defEnemy[CD_AIMFIGHTER].weaponType[0] = W_AIMED_SHOT;
+ defEnemy[CD_AIMFIGHTER].weaponType[1] = W_AIMED_SHOT;
+ defEnemy[CD_AIMFIGHTER].chance[0] = 7;
+ defEnemy[CD_AIMFIGHTER].chance[1] = 1;
+ defEnemy[CD_AIMFIGHTER].score = 50;
+ defEnemy[CD_AIMFIGHTER].collectChance = 75;
+ defEnemy[CD_AIMFIGHTER].collectType = P_ANYTHING;
+ defEnemy[CD_AIMFIGHTER].collectValue = 100;
+ defEnemy[CD_AIMFIGHTER].flags = FL_WEAPCO | FL_AIMS;
+
+ // Slave ship
+ defEnemy[CD_SLAVETRANSPORT].classDef = CD_SLAVETRANSPORT;
+ defEnemy[CD_SLAVETRANSPORT].AIType = AI_EVASIVE;
+ defEnemy[CD_SLAVETRANSPORT].speed = 2;
+ defEnemy[CD_SLAVETRANSPORT].maxShield = 10;
+ defEnemy[CD_SLAVETRANSPORT].shield = 20;
+ defEnemy[CD_SLAVETRANSPORT].imageIndex[0] = 10;
+ defEnemy[CD_SLAVETRANSPORT].imageIndex[1] = 11;
+ defEnemy[CD_SLAVETRANSPORT].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_SLAVETRANSPORT].weaponType[1] = W_DOUBLE_SHOT;
+ defEnemy[CD_SLAVETRANSPORT].chance[0] = 0;
+ defEnemy[CD_SLAVETRANSPORT].chance[1] = 0;
+ defEnemy[CD_SLAVETRANSPORT].score = 25;
+ defEnemy[CD_SLAVETRANSPORT].collectChance = 100;
+ defEnemy[CD_SLAVETRANSPORT].collectType = P_SLAVES;
+ defEnemy[CD_SLAVETRANSPORT].collectValue = 25;
+ defEnemy[CD_SLAVETRANSPORT].flags = FL_WEAPCO | FL_NOFIRE;
+
+ // Good Transport
+ defEnemy[CD_GOODTRANSPORT].classDef = CD_GOODTRANSPORT;
+ defEnemy[CD_GOODTRANSPORT].AIType = AI_EVASIVE;
+ defEnemy[CD_GOODTRANSPORT].speed = 3;
+ defEnemy[CD_GOODTRANSPORT].maxShield = 75;
+ defEnemy[CD_GOODTRANSPORT].shield = 75;
+ defEnemy[CD_GOODTRANSPORT].imageIndex[0] = 12;
+ defEnemy[CD_GOODTRANSPORT].imageIndex[1] = 13;
+ defEnemy[CD_GOODTRANSPORT].weaponType[0] = W_AIMED_SHOT;
+ defEnemy[CD_GOODTRANSPORT].weaponType[1] = W_AIMED_SHOT;
+ defEnemy[CD_GOODTRANSPORT].chance[0] = 100;
+ defEnemy[CD_GOODTRANSPORT].chance[1] = 100;
+ defEnemy[CD_GOODTRANSPORT].score = 0;
+ defEnemy[CD_GOODTRANSPORT].collectChance = 0;
+ defEnemy[CD_GOODTRANSPORT].collectType = P_ANYTHING;
+ defEnemy[CD_GOODTRANSPORT].collectValue = 0;
+ defEnemy[CD_GOODTRANSPORT].flags = FL_FRIEND | FL_NOFIRE | FL_AIMS;
+
+ // Sid Wilson
+ defEnemy[CD_SID].classDef = CD_SID;
+ defEnemy[CD_SID].AIType = AI_NORMAL;
+ defEnemy[CD_SID].speed = 3;
+ defEnemy[CD_SID].maxShield = 50;
+ defEnemy[CD_SID].shield = 50;
+ defEnemy[CD_SID].imageIndex[0] = 24;
+ defEnemy[CD_SID].imageIndex[1] = 25;
+ defEnemy[CD_SID].weaponType[0] = W_IONCANNON;
+ defEnemy[CD_SID].weaponType[1] = W_IONCANNON;
+ defEnemy[CD_SID].chance[0] = 100;
+ defEnemy[CD_SID].chance[1] = 0;
+ defEnemy[CD_SID].score = 0;
+ defEnemy[CD_SID].collectChance = 0;
+ defEnemy[CD_SID].collectType = P_ANYTHING;
+ defEnemy[CD_SID].collectValue = 0;
+ defEnemy[CD_SID].flags = FL_FRIEND | FL_AIMS;
+
+ // Mining Vessel Boss
+ defEnemy[CD_MINEBOSS].classDef = CD_BOSS;
+ defEnemy[CD_MINEBOSS].AIType = AI_NORMAL;
+ defEnemy[CD_MINEBOSS].speed = 3;
+ defEnemy[CD_MINEBOSS].maxShield = 1000;
+ defEnemy[CD_MINEBOSS].shield = 1000;
+ defEnemy[CD_MINEBOSS].imageIndex[0] = 26;
+ defEnemy[CD_MINEBOSS].imageIndex[1] = 27;
+ defEnemy[CD_MINEBOSS].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_MINEBOSS].weaponType[1] = W_SPREADSHOT;
+ defEnemy[CD_MINEBOSS].chance[0] = 0;
+ defEnemy[CD_MINEBOSS].chance[1] = 0;
+ defEnemy[CD_MINEBOSS].score = 1000;
+ defEnemy[CD_MINEBOSS].collectChance = 100;
+ defEnemy[CD_MINEBOSS].collectType = P_ANYTHING;
+ defEnemy[CD_MINEBOSS].collectValue = 255;
+ defEnemy[CD_MINEBOSS].flags = FL_WEAPCO | FL_IMMORTAL;
+
+ defEnemy[CD_BOSS2_WING1].classDef = CD_BOSS2_WING1;
+ defEnemy[CD_BOSS2_WING1].AIType = AI_NORMAL;
+ defEnemy[CD_BOSS2_WING1].speed = 1;
+ defEnemy[CD_BOSS2_WING1].maxShield = 250;
+ defEnemy[CD_BOSS2_WING1].shield = 250;
+ defEnemy[CD_BOSS2_WING1].imageIndex[0] = 28;
+ defEnemy[CD_BOSS2_WING1].imageIndex[1] = 29;
+ defEnemy[CD_BOSS2_WING1].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_BOSS2_WING1].weaponType[1] = W_SPREADSHOT;
+ defEnemy[CD_BOSS2_WING1].chance[0] = 0;
+ defEnemy[CD_BOSS2_WING1].chance[1] = 0;
+ defEnemy[CD_BOSS2_WING1].score = 1000;
+ defEnemy[CD_BOSS2_WING1].collectChance = 100;
+ defEnemy[CD_BOSS2_WING1].collectType = P_ANYTHING;
+ defEnemy[CD_BOSS2_WING1].collectValue = 255;
+ defEnemy[CD_BOSS2_WING1].flags = FL_WEAPCO | FL_DAMAGEOWNER;
+
+ defEnemy[CD_BOSS2_WING2].classDef = CD_BOSS2_WING2;
+ defEnemy[CD_BOSS2_WING2].AIType = AI_NORMAL;
+ defEnemy[CD_BOSS2_WING2].speed = 1;
+ defEnemy[CD_BOSS2_WING2].maxShield = 500;
+ defEnemy[CD_BOSS2_WING2].shield = 500;
+ defEnemy[CD_BOSS2_WING2].imageIndex[0] = 30;
+ defEnemy[CD_BOSS2_WING2].imageIndex[1] = 31;
+ defEnemy[CD_BOSS2_WING2].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_BOSS2_WING2].weaponType[1] = W_SPREADSHOT;
+ defEnemy[CD_BOSS2_WING2].chance[0] = 0;
+ defEnemy[CD_BOSS2_WING2].chance[1] = 0;
+ defEnemy[CD_BOSS2_WING2].score = 1000;
+ defEnemy[CD_BOSS2_WING2].collectChance = 100;
+ defEnemy[CD_BOSS2_WING2].collectType = P_ANYTHING;
+ defEnemy[CD_BOSS2_WING2].collectValue = 255;
+ defEnemy[CD_BOSS2_WING2].flags = FL_WEAPCO | FL_DEPLOYDRONES | FL_DAMAGEOWNER;
+
+ defEnemy[CD_BOSS2_WING3].classDef = CD_BOSS2_WING3;
+ defEnemy[CD_BOSS2_WING3].AIType = AI_NORMAL;
+ defEnemy[CD_BOSS2_WING3].speed = 1;
+ defEnemy[CD_BOSS2_WING3].maxShield = 500;
+ defEnemy[CD_BOSS2_WING3].shield = 500;
+ defEnemy[CD_BOSS2_WING3].imageIndex[0] = 32;
+ defEnemy[CD_BOSS2_WING3].imageIndex[1] = 33;
+ defEnemy[CD_BOSS2_WING3].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_BOSS2_WING3].weaponType[1] = W_SPREADSHOT;
+ defEnemy[CD_BOSS2_WING3].chance[0] = 0;
+ defEnemy[CD_BOSS2_WING3].chance[1] = 0;
+ defEnemy[CD_BOSS2_WING3].score = 1000;
+ defEnemy[CD_BOSS2_WING3].collectChance = 100;
+ defEnemy[CD_BOSS2_WING3].collectType = P_ANYTHING;
+ defEnemy[CD_BOSS2_WING3].collectValue = 255;
+ defEnemy[CD_BOSS2_WING3].flags = FL_WEAPCO | FL_DEPLOYDRONES | FL_DAMAGEOWNER;
+
+ defEnemy[CD_BOSS2_WING4].classDef = CD_BOSS2_WING4;
+ defEnemy[CD_BOSS2_WING4].AIType = AI_NORMAL;
+ defEnemy[CD_BOSS2_WING4].speed = 1;
+ defEnemy[CD_BOSS2_WING4].maxShield = 250;
+ defEnemy[CD_BOSS2_WING4].shield = 250;
+ defEnemy[CD_BOSS2_WING4].imageIndex[0] = 34;
+ defEnemy[CD_BOSS2_WING4].imageIndex[1] = 35;
+ defEnemy[CD_BOSS2_WING4].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_BOSS2_WING4].weaponType[1] = W_SPREADSHOT;
+ defEnemy[CD_BOSS2_WING4].chance[0] = 0;
+ defEnemy[CD_BOSS2_WING4].chance[1] = 0;
+ defEnemy[CD_BOSS2_WING4].score = 1000;
+ defEnemy[CD_BOSS2_WING4].collectChance = 100;
+ defEnemy[CD_BOSS2_WING4].collectType = P_ANYTHING;
+ defEnemy[CD_BOSS2_WING4].collectValue = 255;
+ defEnemy[CD_BOSS2_WING4].flags = FL_WEAPCO | FL_DAMAGEOWNER;
+
+ // Drone
+ defEnemy[CD_DRONE].classDef = CD_DRONE;
+ defEnemy[CD_DRONE].AIType = AI_OFFENSIVE;
+ defEnemy[CD_DRONE].speed = 8;
+ defEnemy[CD_DRONE].maxShield = 5;
+ defEnemy[CD_DRONE].shield = 5;
+ defEnemy[CD_DRONE].imageIndex[0] = 36;
+ defEnemy[CD_DRONE].imageIndex[1] = 37;
+ defEnemy[CD_DRONE].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_DRONE].weaponType[1] = W_LASER;
+ defEnemy[CD_DRONE].chance[0] = 100;
+ defEnemy[CD_DRONE].chance[1] = 0;
+ defEnemy[CD_DRONE].score = 0;
+ defEnemy[CD_DRONE].collectChance = 10;
+ defEnemy[CD_DRONE].collectType = P_SHIELD;
+ defEnemy[CD_DRONE].collectValue = 1;
+ defEnemy[CD_DRONE].flags = FL_WEAPCO;
+
+ // Experimental Fighter
+ defEnemy[CD_CLOAKFIGHTER].classDef = CD_CLOAKFIGHTER;
+ defEnemy[CD_CLOAKFIGHTER].AIType = AI_OFFENSIVE;
+ defEnemy[CD_CLOAKFIGHTER].speed = 6;
+ defEnemy[CD_CLOAKFIGHTER].maxShield = 1000;
+ defEnemy[CD_CLOAKFIGHTER].shield = 1000;
+ defEnemy[CD_CLOAKFIGHTER].imageIndex[0] = 10;
+ defEnemy[CD_CLOAKFIGHTER].imageIndex[1] = 11;
+ defEnemy[CD_CLOAKFIGHTER].weaponType[0] = W_SPREADSHOT;
+ defEnemy[CD_CLOAKFIGHTER].weaponType[1] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_CLOAKFIGHTER].chance[0] = 100;
+ defEnemy[CD_CLOAKFIGHTER].chance[1] = 5;
+ defEnemy[CD_CLOAKFIGHTER].score = 550;
+ defEnemy[CD_CLOAKFIGHTER].collectChance = 100;
+ defEnemy[CD_CLOAKFIGHTER].collectType = P_CASH;
+ defEnemy[CD_CLOAKFIGHTER].collectValue = 255;
+ defEnemy[CD_CLOAKFIGHTER].flags = FL_WEAPCO | FL_CANCLOAK | FL_RUNSAWAY;
+
+ // Evil Ursula
+ defEnemy[CD_EVILURSULA].classDef = CD_EVILURSULA;
+ defEnemy[CD_EVILURSULA].AIType = AI_OFFENSIVE;
+ defEnemy[CD_EVILURSULA].speed = 5;
+ defEnemy[CD_EVILURSULA].maxShield = 500;
+ defEnemy[CD_EVILURSULA].shield = 500;
+ defEnemy[CD_EVILURSULA].imageIndex[0] = 12;
+ defEnemy[CD_EVILURSULA].imageIndex[1] = 13;
+ defEnemy[CD_EVILURSULA].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_EVILURSULA].weaponType[1] = W_HOMING_MISSILE;
+ defEnemy[CD_EVILURSULA].chance[0] = 100;
+ defEnemy[CD_EVILURSULA].chance[1] = 100;
+ defEnemy[CD_EVILURSULA].score = 500;
+ defEnemy[CD_EVILURSULA].collectChance = 100;
+ defEnemy[CD_EVILURSULA].collectType = P_ESCAPEPOD;
+ defEnemy[CD_EVILURSULA].collectValue = 1;
+ defEnemy[CD_EVILURSULA].flags = FL_WEAPCO;
+
+ // Mercenary
+ defEnemy[CD_KRASS].classDef = CD_KRASS;
+ defEnemy[CD_KRASS].AIType = AI_OFFENSIVE;
+ defEnemy[CD_KRASS].speed = 5;
+ defEnemy[CD_KRASS].maxShield = 1000;
+ defEnemy[CD_KRASS].shield = 1000;
+ defEnemy[CD_KRASS].imageIndex[0] = 26;
+ defEnemy[CD_KRASS].imageIndex[1] = 27;
+ defEnemy[CD_KRASS].weaponType[0] = W_SPREADSHOT;
+ defEnemy[CD_KRASS].weaponType[1] = W_CHARGER;
+ defEnemy[CD_KRASS].chance[0] = 100;
+ defEnemy[CD_KRASS].chance[1] = 0;
+ defEnemy[CD_KRASS].score = 2000;
+ defEnemy[CD_KRASS].collectChance = 100;
+ defEnemy[CD_KRASS].collectType = P_ANYTHING;
+ defEnemy[CD_KRASS].collectValue = 255;
+ defEnemy[CD_KRASS].flags = FL_FRIEND | FL_IMMORTAL;
+
+ // Executive Transport
+ defEnemy[CD_EXEC].classDef = CD_BOSS;
+ defEnemy[CD_EXEC].AIType = AI_NORMAL;
+ defEnemy[CD_EXEC].speed = 5;
+ defEnemy[CD_EXEC].maxShield = 1000;
+ defEnemy[CD_EXEC].shield = 1000;
+ defEnemy[CD_EXEC].imageIndex[0] = 28;
+ defEnemy[CD_EXEC].imageIndex[1] = 28;
+ defEnemy[CD_EXEC].weaponType[0] = W_SPREADSHOT;
+ defEnemy[CD_EXEC].weaponType[1] = W_HOMING_MISSILE;
+ defEnemy[CD_EXEC].chance[0] = 0;
+ defEnemy[CD_EXEC].chance[1] = 0;
+ defEnemy[CD_EXEC].score = 2000;
+ defEnemy[CD_EXEC].collectChance = 0;
+ defEnemy[CD_EXEC].collectType = P_ANYTHING;
+ defEnemy[CD_EXEC].collectValue = 0;
+ defEnemy[CD_EXEC].flags = FL_WEAPCO | FL_NOFIRE;
+
+ // Asteroid
+ defEnemy[CD_ASTEROID].classDef = CD_ASTEROID;
+ defEnemy[CD_ASTEROID].AIType = AI_WANDER;
+ defEnemy[CD_ASTEROID].speed = 1;
+ defEnemy[CD_ASTEROID].maxShield = 50;
+ defEnemy[CD_ASTEROID].shield = 50;
+ defEnemy[CD_ASTEROID].imageIndex[0] = 38;
+ defEnemy[CD_ASTEROID].imageIndex[1] = 38;
+ defEnemy[CD_ASTEROID].weaponType[0] = W_SPREADSHOT;
+ defEnemy[CD_ASTEROID].weaponType[1] = W_HOMING_MISSILE;
+ defEnemy[CD_ASTEROID].chance[0] = 0;
+ defEnemy[CD_ASTEROID].chance[1] = 0;
+ defEnemy[CD_ASTEROID].score = 0;
+ defEnemy[CD_ASTEROID].collectChance = 25;
+ defEnemy[CD_ASTEROID].collectType = P_ORE;
+ defEnemy[CD_ASTEROID].collectValue = 1;
+ defEnemy[CD_ASTEROID].flags = FL_WEAPCO;
+
+ defEnemy[CD_ASTEROID2].classDef = CD_ASTEROID2;
+ defEnemy[CD_ASTEROID2].AIType = AI_WANDER;
+ defEnemy[CD_ASTEROID2].speed = 1;
+ defEnemy[CD_ASTEROID2].maxShield = 10;
+ defEnemy[CD_ASTEROID2].shield = 10;
+ defEnemy[CD_ASTEROID2].imageIndex[0] = 39;
+ defEnemy[CD_ASTEROID2].imageIndex[1] = 40;
+ defEnemy[CD_ASTEROID2].weaponType[0] = W_SPREADSHOT;
+ defEnemy[CD_ASTEROID2].weaponType[1] = W_HOMING_MISSILE;
+ defEnemy[CD_ASTEROID2].chance[0] = 0;
+ defEnemy[CD_ASTEROID2].chance[1] = 0;
+ defEnemy[CD_ASTEROID2].score = 0;
+ defEnemy[CD_ASTEROID2].collectChance = 25;
+ defEnemy[CD_ASTEROID2].collectType = P_ORE;
+ defEnemy[CD_ASTEROID2].collectValue = 1;
+ defEnemy[CD_ASTEROID2].flags = FL_WEAPCO;
+
+ // Escort
+ defEnemy[CD_ESCORT].classDef = CD_ESCORT;
+ defEnemy[CD_ESCORT].AIType = AI_NORMAL;
+ defEnemy[CD_ESCORT].speed = 3;
+ defEnemy[CD_ESCORT].maxShield = 200;
+ defEnemy[CD_ESCORT].shield = 200;
+ defEnemy[CD_ESCORT].imageIndex[0] = 30;
+ defEnemy[CD_ESCORT].imageIndex[1] = 31;
+ defEnemy[CD_ESCORT].weaponType[0] = W_LASER;
+ defEnemy[CD_ESCORT].weaponType[1] = W_LASER;
+ defEnemy[CD_ESCORT].chance[0] = 25;
+ defEnemy[CD_ESCORT].chance[1] = 25;
+ defEnemy[CD_ESCORT].score = 450;
+ defEnemy[CD_ESCORT].collectChance = 100;
+ defEnemy[CD_ESCORT].collectType = P_ANYTHING;
+ defEnemy[CD_ESCORT].collectValue = 100;
+ defEnemy[CD_ESCORT].flags = FL_WEAPCO;
+
+ // Mobile Ray Cannon
+ defEnemy[CD_MOBILE_RAY].classDef = CD_MOBILE_RAY;
+ defEnemy[CD_MOBILE_RAY].AIType = AI_OFFENSIVE;
+ defEnemy[CD_MOBILE_RAY].speed = 5;
+ defEnemy[CD_MOBILE_RAY].maxShield = 250;
+ defEnemy[CD_MOBILE_RAY].shield = 250;
+ defEnemy[CD_MOBILE_RAY].imageIndex[0] = 10;
+ defEnemy[CD_MOBILE_RAY].imageIndex[1] = 11;
+ defEnemy[CD_MOBILE_RAY].weaponType[0] = W_ENERGYRAY;
+ defEnemy[CD_MOBILE_RAY].weaponType[1] = W_ENERGYRAY;
+ defEnemy[CD_MOBILE_RAY].chance[0] = 50;
+ defEnemy[CD_MOBILE_RAY].chance[1] = 50;
+ defEnemy[CD_MOBILE_RAY].score = 1000;
+ defEnemy[CD_MOBILE_RAY].collectChance = 75;
+ defEnemy[CD_MOBILE_RAY].collectType = P_SHIELD;
+ defEnemy[CD_MOBILE_RAY].collectValue = 2;
+ defEnemy[CD_MOBILE_RAY].flags = FL_WEAPCO;
+
+ // Rebel Carrier
+ defEnemy[CD_REBELCARRIER].classDef = CD_REBELCARRIER;
+ defEnemy[CD_REBELCARRIER].AIType = AI_OFFENSIVE;
+ defEnemy[CD_REBELCARRIER].speed = 2;
+ defEnemy[CD_REBELCARRIER].maxShield = 100;
+ defEnemy[CD_REBELCARRIER].shield = 100;
+ defEnemy[CD_REBELCARRIER].imageIndex[0] = 32;
+ defEnemy[CD_REBELCARRIER].imageIndex[1] = 33;
+ defEnemy[CD_REBELCARRIER].weaponType[0] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_REBELCARRIER].weaponType[1] = W_MICRO_ROCKETS;
+ defEnemy[CD_REBELCARRIER].chance[0] = 50;
+ defEnemy[CD_REBELCARRIER].chance[1] = 2;
+ defEnemy[CD_REBELCARRIER].score = 0;
+ defEnemy[CD_REBELCARRIER].collectChance = 0;
+ defEnemy[CD_REBELCARRIER].collectType = P_SHIELD;
+ defEnemy[CD_REBELCARRIER].collectValue = 0;
+ defEnemy[CD_REBELCARRIER].flags = FL_FRIEND;
+
+ // Pluto Boss
+ defEnemy[CD_PLUTOBOSS].classDef = CD_PLUTOBOSS;
+ defEnemy[CD_PLUTOBOSS].AIType = AI_OFFENSIVE;
+ defEnemy[CD_PLUTOBOSS].speed = 4;
+ defEnemy[CD_PLUTOBOSS].maxShield = 500;
+ defEnemy[CD_PLUTOBOSS].shield = 500;
+ defEnemy[CD_PLUTOBOSS].imageIndex[0] = 12;
+ defEnemy[CD_PLUTOBOSS].imageIndex[1] = 13;
+ defEnemy[CD_PLUTOBOSS].weaponType[0] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_PLUTOBOSS].weaponType[1] = W_MICRO_ROCKETS;
+ defEnemy[CD_PLUTOBOSS].chance[0] = 50;
+ defEnemy[CD_PLUTOBOSS].chance[1] = 2;
+ defEnemy[CD_PLUTOBOSS].score = 1000;
+ defEnemy[CD_PLUTOBOSS].collectChance = 0;
+ defEnemy[CD_PLUTOBOSS].collectType = P_SHIELD;
+ defEnemy[CD_PLUTOBOSS].collectValue = 0;
+ defEnemy[CD_PLUTOBOSS].flags = FL_WEAPCO;
+
+ // Pluto Boss Barrier
+ defEnemy[CD_BARRIER].classDef = CD_BARRIER;
+ defEnemy[CD_BARRIER].AIType = AI_OFFENSIVE;
+ defEnemy[CD_BARRIER].speed = 1;
+ defEnemy[CD_BARRIER].maxShield = 250;
+ defEnemy[CD_BARRIER].shield = 250;
+ defEnemy[CD_BARRIER].imageIndex[0] = 32;
+ defEnemy[CD_BARRIER].imageIndex[1] = 33;
+ defEnemy[CD_BARRIER].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_BARRIER].weaponType[1] = W_MICRO_ROCKETS;
+ defEnemy[CD_BARRIER].chance[0] = 0;
+ defEnemy[CD_BARRIER].chance[1] = 0;
+ defEnemy[CD_BARRIER].score = 1000;
+ defEnemy[CD_BARRIER].collectChance = 100;
+ defEnemy[CD_BARRIER].collectType = P_ANYTHING;
+ defEnemy[CD_BARRIER].collectValue = 25;
+ defEnemy[CD_BARRIER].flags = FL_WEAPCO | FL_NOFIRE;
+
+ // Neptune Boss
+ defEnemy[CD_NEPTUNEBOSS].classDef = CD_NEPTUNEBOSS;
+ defEnemy[CD_NEPTUNEBOSS].AIType = AI_OFFENSIVE;
+ defEnemy[CD_NEPTUNEBOSS].speed = 4;
+ defEnemy[CD_NEPTUNEBOSS].maxShield = 800;
+ defEnemy[CD_NEPTUNEBOSS].shield = 800;
+ defEnemy[CD_NEPTUNEBOSS].imageIndex[0] = 12;
+ defEnemy[CD_NEPTUNEBOSS].imageIndex[1] = 13;
+ defEnemy[CD_NEPTUNEBOSS].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_NEPTUNEBOSS].weaponType[1] = W_MICRO_ROCKETS;
+ defEnemy[CD_NEPTUNEBOSS].chance[0] = 100;
+ defEnemy[CD_NEPTUNEBOSS].chance[1] = 0;
+ defEnemy[CD_NEPTUNEBOSS].score = 1000;
+ defEnemy[CD_NEPTUNEBOSS].collectChance = 100;
+ defEnemy[CD_NEPTUNEBOSS].collectType = P_ANYTHING;
+ defEnemy[CD_NEPTUNEBOSS].collectValue = 25;
+ defEnemy[CD_NEPTUNEBOSS].flags = FL_WEAPCO;
+
+ // Mobile Shield
+ defEnemy[CD_MOBILESHIELD].classDef = CD_MOBILESHIELD;
+ defEnemy[CD_MOBILESHIELD].AIType = AI_EVASIVE;
+ defEnemy[CD_MOBILESHIELD].speed = 6;
+ defEnemy[CD_MOBILESHIELD].maxShield = 150;
+ defEnemy[CD_MOBILESHIELD].shield = 150;
+ defEnemy[CD_MOBILESHIELD].imageIndex[0] = 34;
+ defEnemy[CD_MOBILESHIELD].imageIndex[1] = 35;
+ defEnemy[CD_MOBILESHIELD].weaponType[0] = W_DOUBLE_SHOT;
+ defEnemy[CD_MOBILESHIELD].weaponType[1] = W_MICRO_ROCKETS;
+ defEnemy[CD_MOBILESHIELD].chance[0] = 0;
+ defEnemy[CD_MOBILESHIELD].chance[1] = 0;
+ defEnemy[CD_MOBILESHIELD].score = 250;
+ defEnemy[CD_MOBILESHIELD].collectChance = 100;
+ defEnemy[CD_MOBILESHIELD].collectType = P_ANYTHING;
+ defEnemy[CD_MOBILESHIELD].collectValue = 25;
+ defEnemy[CD_MOBILESHIELD].flags = FL_WEAPCO | FL_NOFIRE;
+
+ // Firefly
+ defEnemy[CD_FIREFLY].classDef = CD_FIREFLY;
+ defEnemy[CD_FIREFLY].AIType = AI_OFFENSIVE;
+ defEnemy[CD_FIREFLY].speed = 5;
+ defEnemy[CD_FIREFLY].maxShield = 250;
+ defEnemy[CD_FIREFLY].shield = 250;
+ defEnemy[CD_FIREFLY].imageIndex[0] = 0;
+ defEnemy[CD_FIREFLY].imageIndex[1] = 1;
+ defEnemy[CD_FIREFLY].weaponType[0] = W_TRIPLE_SHOT;
+ defEnemy[CD_FIREFLY].weaponType[1] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_FIREFLY].chance[0] = 100;
+ defEnemy[CD_FIREFLY].chance[1] = 5;
+ defEnemy[CD_FIREFLY].score = 500;
+ defEnemy[CD_FIREFLY].collectChance = 100;
+ defEnemy[CD_FIREFLY].collectType = P_ANYTHING;
+ defEnemy[CD_FIREFLY].collectValue = 250;
+ defEnemy[CD_FIREFLY].flags = FL_WEAPCO;
+
+ // Uranus Boss
+ defEnemy[CD_URANUSBOSS].classDef = CD_URANUSBOSS;
+ defEnemy[CD_URANUSBOSS].AIType = AI_OFFENSIVE;
+ defEnemy[CD_URANUSBOSS].speed = 4;
+ defEnemy[CD_URANUSBOSS].maxShield = 750;
+ defEnemy[CD_URANUSBOSS].shield = 750;
+ defEnemy[CD_URANUSBOSS].imageIndex[0] = 41;
+ defEnemy[CD_URANUSBOSS].imageIndex[1] = 42;
+ defEnemy[CD_URANUSBOSS].weaponType[0] = W_SPREADSHOT;
+ defEnemy[CD_URANUSBOSS].weaponType[1] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_URANUSBOSS].chance[0] = 100;
+ defEnemy[CD_URANUSBOSS].chance[1] = 5;
+ defEnemy[CD_URANUSBOSS].score = 500;
+ defEnemy[CD_URANUSBOSS].collectChance = 100;
+ defEnemy[CD_URANUSBOSS].collectType = P_ANYTHING;
+ defEnemy[CD_URANUSBOSS].collectValue = 250;
+ defEnemy[CD_URANUSBOSS].flags = FL_WEAPCO;
+
+ // Uranus Boss Wing 1
+ defEnemy[CD_URANUSBOSSWING1].classDef = CD_URANUSBOSSWING1;
+ defEnemy[CD_URANUSBOSSWING1].AIType = AI_OFFENSIVE;
+ defEnemy[CD_URANUSBOSSWING1].speed = 4;
+ defEnemy[CD_URANUSBOSSWING1].maxShield = 250;
+ defEnemy[CD_URANUSBOSSWING1].shield = 250;
+ defEnemy[CD_URANUSBOSSWING1].imageIndex[0] = 43;
+ defEnemy[CD_URANUSBOSSWING1].imageIndex[1] = 44;
+ defEnemy[CD_URANUSBOSSWING1].weaponType[0] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_URANUSBOSSWING1].weaponType[1] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_URANUSBOSSWING1].chance[0] = 5;
+ defEnemy[CD_URANUSBOSSWING1].chance[1] = 0;
+ defEnemy[CD_URANUSBOSSWING1].score = 500;
+ defEnemy[CD_URANUSBOSSWING1].collectChance = 100;
+ defEnemy[CD_URANUSBOSSWING1].collectType = P_ANYTHING;
+ defEnemy[CD_URANUSBOSSWING1].collectValue = 250;
+ defEnemy[CD_URANUSBOSSWING1].flags = FL_WEAPCO | FL_IMMORTAL;
+
+ // Uranus Boss Wing 2
+ defEnemy[CD_URANUSBOSSWING2].classDef = CD_URANUSBOSSWING2;
+ defEnemy[CD_URANUSBOSSWING2].AIType = AI_OFFENSIVE;
+ defEnemy[CD_URANUSBOSSWING2].speed = 4;
+ defEnemy[CD_URANUSBOSSWING2].maxShield = 250;
+ defEnemy[CD_URANUSBOSSWING2].shield = 250;
+ defEnemy[CD_URANUSBOSSWING2].imageIndex[0] = 45;
+ defEnemy[CD_URANUSBOSSWING2].imageIndex[1] = 46;
+ defEnemy[CD_URANUSBOSSWING2].weaponType[0] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_URANUSBOSSWING2].weaponType[1] = W_DOUBLE_ROCKETS;
+ defEnemy[CD_URANUSBOSSWING2].chance[0] = 5;
+ defEnemy[CD_URANUSBOSSWING2].chance[1] = 0;
+ defEnemy[CD_URANUSBOSSWING2].score = 500;
+ defEnemy[CD_URANUSBOSSWING2].collectChance = 100;
+ defEnemy[CD_URANUSBOSSWING2].collectType = P_ANYTHING;
+ defEnemy[CD_URANUSBOSSWING2].collectValue = 250;
+ defEnemy[CD_URANUSBOSSWING2].flags = FL_WEAPCO | FL_IMMORTAL;
setColorIndexes();
diff --git a/src/Starfighter.h b/src/Starfighter.h
index 764afb0..c2bc7fa 100644
--- a/src/Starfighter.h
+++ b/src/Starfighter.h
@@ -35,7 +35,6 @@ along with this program. If not, see .
#include "defs.h"
#include "structs.h"
-#include "ai.h"
#include "aliens.h"
#include "audio.h"
#include "bullets.h"
diff --git a/src/ai.cpp b/src/ai.cpp
deleted file mode 100644
index 6b19ea8..0000000
--- a/src/ai.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
-Copyright (C) 2003 Parallel Realities
-Copyright (C) 2011 Guus Sliepen
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 3
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#include "Starfighter.h"
-
-/*
-Some very simple artificial intelligence routines for the aliens.
-Shouldn't really be called AI since they just do things at random.
-Aliens are assigned various AI types and this routine makes use of them.
-Levels of aggression, defence and evasion are all here.
-*/
-
-void alien_setAI(object *alien)
-{
- // Make friendly craft generally concentrate on smaller fighters
- if ((alien->flags & FL_FRIEND) && (alien->target == &enemy[WC_BOSS]))
- {
- if ((rand() % 5) == 0)
- {
- alien->target = alien;
- alien->thinktime = 0;
- return;
- }
- }
-
- int i = rand() % 10;
- float tx = alien->target->x;
- float ty = alien->target->y;
-
- int chase = 0; // Chance in 10 of chasing player
- int area = 0; // Chance in 10 of moving to an area around the player
- int stop = 0; // Chance in 10 of hanging back
- int point = 0; // Size of area alien will move into
-
- switch (alien->AIType)
- {
- case AI_NORMAL:
- chase = 3;
- point = 6;
- stop = 9;
- area = 250;
- break;
- case AI_OFFENSIVE:
- chase = 7;
- point = 8;
- stop = 9;
- area = 50;
- break;
- case AI_DEFENSIVE:
- chase = 2;
- point = 6;
- stop = 8;
- area = 300;
- break;
- case AI_EVASIVE:
- chase = 1;
- point = 8;
- stop = 9;
- area = 600;
- break;
- case AI_WANDER:
- chase = -1;
- point = 0;
- stop = 10;
- area = 1200;
- break;
- }
-
- if (i <= chase)
- {
- // Chase the target
- alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
- alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
- return;
- }
- else if ((i >= point) && (i <= stop))
- {
- // Fly to a random point around the target
- tx += (rand() % area - (rand() % area * 2));
- ty += (rand() % area - (rand() % area * 2));
- alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
- alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
- return;
- }
- else
- {
- // Hang back
- alien->dx = 0;
- alien->dy = 0;
- return;
- }
-}
-
-void alien_setKlineAttackMethod(object *alien)
-{
- alien->maxShield -= 500;
- if (alien->maxShield == 0)
- alien->flags &= ~FL_CANNOTDIE;
-
- if (alien->maxShield == 1000)
- {
- setRadioMessage(FACE_KLINE, "Very good, Bainfield. Now let's get a little more serious...", 1);
- alien->weaponType[0] = W_SPREADSHOT;
- alien->chance[1] = 40;
- }
- else if (alien->maxShield == 500)
- {
- setRadioMessage(FACE_KLINE, "Your ability to stay alive irritates me!! Try dodging some of these!!", 1);
- alien->weaponType[0] = W_DIRSHOCKMISSILE;
- alien->weaponType[1] = W_DIRSHOCKMISSILE;
- alien->chance[0] = 2;
- alien->chance[1] = 2;
- alien->flags |= FL_AIMS;
- }
- else if (alien->maxShield == 0)
- {
- setRadioMessage(FACE_KLINE, "ENOUGH!! THIS ENDS NOW!!!", 1);
- alien->weaponType[0] = W_AIMED_SHOT;
- alien->weaponType[1] = W_MICRO_HOMING_MISSILES;
- alien->flags |= FL_CANCLOAK;
- alien->chance[0] = 100;
- alien->chance[1] = 2;
- }
-
- alien->shield = 500;
-}
-
-/*
-This AI is exclusively for Kline.
-*/
-void alien_setKlineAI(object *alien)
-{
- // Weapon type change
- if ((rand() % 3) == 0)
- {
- if (currentGame.area != 26)
- {
- alien->flags &= ~FL_AIMS;
-
- switch(rand() % 2)
- {
- case 0:
- alien->weaponType[0] = W_TRIPLE_SHOT;
- break;
- case 1:
- alien->weaponType[0] = W_AIMED_SHOT;
- alien->flags |= FL_AIMS;
- break;
- }
- }
- }
-
- alien->flags &= ~(FL_CIRCLES | FL_CONTINUOUS_FIRE | FL_DROPMINES);
-
- switch(rand() % 10)
- {
- case 0:
- if ((alien->weaponType[0] != W_DIRSHOCKMISSILE) && (alien->weaponType[1] != W_MICRO_HOMING_MISSILES))
- alien->flags |= FL_CONTINUOUS_FIRE;
- alien->dx = ((alien->x - alien->target->x) / ((300 / alien->speed) + rand() % 100));
- alien->dy = ((alien->y - alien->target->y) / ((300 / alien->speed) + rand() % 100));
- break;
- case 1:
- case 2:
- // Kline only attacks then he is ready!
- if ((!(alien->flags & FL_NOFIRE)) && (currentGame.area == 11))
- alien->flags |= FL_DROPMINES;
- break;
- case 3:
- case 4:
- alien->flags |= FL_CIRCLES;
- break;
- default:
- alien_setAI(alien);
- break;
- }
-}
diff --git a/src/ai.h b/src/ai.h
deleted file mode 100644
index a6519e0..0000000
--- a/src/ai.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-Copyright (C) 2003 Parallel Realities
-Copyright (C) 2011 Guus Sliepen
-Copyright (C) 2015 Julian Marchant
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 3
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#ifndef AI_H
-#define AI_H
-
-void alien_setAI(object *alien);
-void alien_setKlineAttackMethod(object *alien);
-void alien_setKlineAI(object *alien);
-
-#endif
diff --git a/src/aliens.cpp b/src/aliens.cpp
index 05042ae..749bea7 100644
--- a/src/aliens.cpp
+++ b/src/aliens.cpp
@@ -40,36 +40,6 @@ static int alien_getFreeIndex()
return -1;
}
-static bool alien_place(object *alien)
-{
- if (rand() % 2 == 0)
- alien->x = rrand(screen->w, screen->w * 2);
- else
- alien->x = rrand(-screen->w, 0);
-
- if (rand() % 2 == 0)
- alien->y = rrand(screen->h, screen->h * 2);
- else
- alien->y = rrand(-screen->h, 0);
-
- if (currentGame.area == 24)
- {
- alien->x = screen->w;
- alien->y = rrand(screen->h / 3, (2 * screen->h) / 3);
- }
-
- for (int i = 0 ; i < MAX_ALIENS ; i++)
- {
- if ((enemy[i].owner != alien) && (enemy[i].shield > 0))
- {
- if (collision(alien->x, alien->y, alien->image[0]->w, alien->image[0]->h, enemy[i].x, enemy[i].y, enemy[i].image[0]->w, enemy[i].image[0]->h))
- return false;
- }
- }
-
- return true;
-}
-
bool alien_add()
{
int index = alien_getFreeIndex();
@@ -236,7 +206,7 @@ bool alien_add()
return true;
}
-static void alien_addDrone(object *hostEnemy)
+void alien_addDrone(object *hostAlien)
{
int index = alien_getFreeIndex();
@@ -253,11 +223,11 @@ static void alien_addDrone(object *hostEnemy)
enemy[index].deathCounter = 0 - (enemy[index].maxShield * 3);
enemy[index].hit = 0;
- enemy[index].x = hostEnemy->x + rand() % 50;
- enemy[index].y = hostEnemy->y + rand() % 50;
+ enemy[index].x = hostAlien->x + rand() % 50;
+ enemy[index].y = hostAlien->y + rand() % 50;
}
-static void alien_addSmallAsteroid(object *hostEnemy)
+void alien_addSmallAsteroid(object *hostAlien)
{
if (engine.missionCompleteTimer != 0)
return;
@@ -266,7 +236,7 @@ static void alien_addSmallAsteroid(object *hostEnemy)
int debris = 1 + rand() % 10;
for (int i = 0 ; i < debris ; i++)
- addBullet(&weapon[W_ROCKETS], hostEnemy, 0, 0);
+ addBullet(&weapon[W_ROCKETS], hostAlien, 0, 0);
for (int i = 10 ; i < 20 ; i++)
if (!enemy[i].active)
@@ -294,12 +264,12 @@ static void alien_addSmallAsteroid(object *hostEnemy)
enemy[index].deathCounter = 0 - (enemy[index].maxShield * 3);
enemy[index].hit = 0;
- enemy[index].x = hostEnemy->x;
- enemy[index].y = hostEnemy->y;
+ enemy[index].x = hostAlien->x;
+ enemy[index].y = hostAlien->y;
enemy[index].active = true;
}
-static void alien_addFriendly(int type)
+void alien_addFriendly(int type)
{
if (type != FR_SID)
enemy[type] = defEnemy[CD_FRIEND];
@@ -331,320 +301,198 @@ static void alien_addFriendly(int type)
enemy[type].flags |= FL_IMMORTAL;
}
-static void aliens_getPreDefined()
+bool alien_place(object *alien)
{
- FILE *fp;
- char string[255];
- strcpy(string, "");
+ if (rand() % 2 == 0)
+ alien->x = rrand(screen->w, screen->w * 2);
+ else
+ alien->x = rrand(-screen->w, 0);
- int index, alienType, placeAttempt;
- int barrierSpeed = 1;
+ if (rand() % 2 == 0)
+ alien->y = rrand(screen->h, screen->h * 2);
+ else
+ alien->y = rrand(-screen->h, 0);
- sprintf(string, "data/aliens%d.dat", currentGame.area);
- fp = fopen(string, "rb");
- if (fp == NULL)
+ if (currentGame.area == 24)
+ {
+ alien->x = screen->w;
+ alien->y = rrand(screen->h / 3, (2 * screen->h) / 3);
+ }
+
+ for (int i = 0 ; i < MAX_ALIENS ; i++)
+ {
+ if ((enemy[i].owner != alien) && (enemy[i].shield > 0))
+ {
+ if (collision(alien->x, alien->y, alien->image[0]->w, alien->image[0]->h, enemy[i].x, enemy[i].y, enemy[i].image[0]->w, enemy[i].image[0]->h))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void alien_setAI(object *alien)
+{
+ // Make friendly craft generally concentrate on smaller fighters
+ if ((alien->flags & FL_FRIEND) && (alien->target == &enemy[WC_BOSS]))
+ {
+ if ((rand() % 5) == 0)
+ {
+ alien->target = alien;
+ alien->thinktime = 0;
+ return;
+ }
+ }
+
+ int i = rand() % 10;
+ float tx = alien->target->x;
+ float ty = alien->target->y;
+
+ int chase = 0; // Chance in 10 of chasing player
+ int area = 0; // Chance in 10 of moving to an area around the player
+ int stop = 0; // Chance in 10 of hanging back
+ int point = 0; // Size of area alien will move into
+
+ switch (alien->AIType)
+ {
+ case AI_NORMAL:
+ chase = 3;
+ point = 6;
+ stop = 9;
+ area = 250;
+ break;
+ case AI_OFFENSIVE:
+ chase = 7;
+ point = 8;
+ stop = 9;
+ area = 50;
+ break;
+ case AI_DEFENSIVE:
+ chase = 2;
+ point = 6;
+ stop = 8;
+ area = 300;
+ break;
+ case AI_EVASIVE:
+ chase = 1;
+ point = 8;
+ stop = 9;
+ area = 600;
+ break;
+ case AI_WANDER:
+ chase = -1;
+ point = 0;
+ stop = 10;
+ area = 1200;
+ break;
+ }
+
+ if (i <= chase)
+ {
+ // Chase the target
+ alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
+ alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
return;
-
- while (fscanf(fp, "%d %d ", &index, &alienType) == 2)
- {
- placeAttempt = 0;
-
- enemy[index] = defEnemy[alienType];
- enemy[index].owner = &enemy[index];
- enemy[index].target = &enemy[index];
- enemy[index].face = rand() % 2;
- enemy[index].active = true;
-
- /*
- we make 1000 attempts to place this enemy since it is required. If after
- 1000 attempts we still haven't managed to place the alien, then it
- simply isn't going to happen and we will just exit the game. The chances
- of this happening are very very low!
- */
- while (true)
- {
- placeAttempt++;
-
- if (alien_place(&enemy[index]))
- break;
-
- if (placeAttempt > 1000)
- showErrorAndExit(2, "");
- }
-
- if (currentGame.area == 2)
- addCargo(&enemy[index], P_CARGO);
- else if (currentGame.area == 7)
- addCargo(&enemy[index], P_PHOEBE);
-
- if (index == WC_KLINE)
- {
- enemy[WC_KLINE].target = &player;
- if (currentGame.area == 25)
- enemy[WC_KLINE].shield = 500;
- }
-
- if (enemy[index].classDef == CD_CLOAKFIGHTER)
- {
- enemy[index].active = false;
- enemy[index].maxShield = enemy[index].shield = 400;
- enemy[index].flags &= ~FL_RUNSAWAY;
- enemy[index].speed = 3;
- }
-
- if ((enemy[index].classDef == CD_MOBILE_RAY) && (index >= 11))
- {
- enemy[index].active = false;
- }
-
- if (enemy[index].classDef == CD_FIREFLY)
- {
- enemy[index].active = false;
- }
-
- if (enemy[index].classDef == CD_BARRIER)
- {
- enemy[index].owner = &enemy[WC_BOSS];
- enemy[index].speed = barrierSpeed;
- barrierSpeed++;
- }
-
- if ((currentGame.area == 17) && (enemy[index].classDef == CD_BOSS))
- {
- enemy[index].imageIndex[1] = 29;
- enemy[index].flags |= FL_IMMORTAL;
- }
-
- if (currentGame.area == 18)
- enemy[index].flags |= FL_HASMINIMUMSPEED;
-
- if (currentGame.area == 23)
- {
- enemy[index].flags = FL_WEAPCO;
- if (index == WC_BOSS)
- enemy[index].chance[1] = 5;
- }
}
-
- fclose(fp);
-
- if (currentGame.area == 5)
+ else if ((i >= point) && (i <= stop))
{
- enemy[WC_BOSS].target = &player;
- enemy[WC_BOSS].x = -screen->w / 2;
- enemy[WC_BOSS].y = screen->h / 2;
-
- enemy[13].owner = &enemy[WC_BOSS];
- enemy[13].target = &player;
- enemy[13].dx = -25;
- enemy[13].dy = -21;
-
- enemy[12].owner = &enemy[WC_BOSS];
- enemy[12].target = &player;
- enemy[12].dx = -20;
- enemy[12].dy = 37;
+ // Fly to a random point around the target
+ tx += (rand() % area - (rand() % area * 2));
+ ty += (rand() % area - (rand() % area * 2));
+ alien->dx = ((alien->x - tx) / ((300 / alien->speed) + rand() % 100));
+ alien->dy = ((alien->y - ty) / ((300 / alien->speed) + rand() % 100));
+ return;
}
- else if ((currentGame.area == 11) || (currentGame.area == 14))
+ else
{
- enemy[WC_BOSS].target = &player;
- enemy[WC_BOSS].x = -screen->w / 2;
- enemy[WC_BOSS].y = screen->h / 2;
-
- enemy[13].owner = &enemy[WC_BOSS];
- enemy[13].target = &player;
- enemy[13].dx = 15;
- enemy[13].dy = -22;
-
- enemy[12].owner = &enemy[WC_BOSS];
- enemy[12].target = &player;
- enemy[12].dx = 15;
- enemy[12].dy = 22;
-
- enemy[11].owner = &enemy[13];
- enemy[11].target = &player;
- enemy[11].dx = -35;
- enemy[11].dy = -12;
-
- enemy[10].owner = &enemy[12];
- enemy[10].target = &player;
- enemy[10].dx = -35;
- enemy[10].dy = 20;
-
- if (currentGame.area == 14)
- {
- enemy[WC_BOSS].AIType = AI_EVASIVE;
-
- for (int i = 10 ; i < 15 ; i++)
- {
- enemy[i].imageIndex[0] += 15;
- enemy[i].imageIndex[1] += 15;
-
- enemy[i].image[0] = shipShape[enemy[i].imageIndex[0]];
- enemy[i].image[1] = shipShape[enemy[i].imageIndex[1]];
- }
- }
- }
- else if (currentGame.area == 21)
- {
- enemy[WC_BOSS].target = &player;
- enemy[WC_BOSS].x = -screen->w / 2;
- enemy[WC_BOSS].y = screen->h / 2;
-
- enemy[13].owner = &enemy[WC_BOSS];
- enemy[13].dy = 20;
-
- enemy[12].owner = &enemy[WC_BOSS];
- enemy[12].dy = -16;
+ // Hang back
+ alien->dx = 0;
+ alien->dy = 0;
+ return;
}
}
-void player_setTarget(int index)
+void alien_setKlineAttackMethod(object *alien)
{
- engine.targetIndex = index;
- engine.targetShield = 85;
- engine.targetShield /= enemy[index].shield;
+ alien->maxShield -= 500;
+ if (alien->maxShield == 0)
+ alien->flags &= ~FL_CANNOTDIE;
+
+ if (alien->maxShield == 1000)
+ {
+ setRadioMessage(FACE_KLINE, "Very good, Bainfield. Now let's get a little more serious...", 1);
+ alien->weaponType[0] = W_SPREADSHOT;
+ alien->chance[1] = 40;
+ }
+ else if (alien->maxShield == 500)
+ {
+ setRadioMessage(FACE_KLINE, "Your ability to stay alive irritates me!! Try dodging some of these!!", 1);
+ alien->weaponType[0] = W_DIRSHOCKMISSILE;
+ alien->weaponType[1] = W_DIRSHOCKMISSILE;
+ alien->chance[0] = 2;
+ alien->chance[1] = 2;
+ alien->flags |= FL_AIMS;
+ }
+ else if (alien->maxShield == 0)
+ {
+ setRadioMessage(FACE_KLINE, "ENOUGH!! THIS ENDS NOW!!!", 1);
+ alien->weaponType[0] = W_AIMED_SHOT;
+ alien->weaponType[1] = W_MICRO_HOMING_MISSILES;
+ alien->flags |= FL_CANCLOAK;
+ alien->chance[0] = 100;
+ alien->chance[1] = 2;
+ }
+
+ alien->shield = 500;
}
-// XXX: This function initializes the *spawning* of enemies, within an
-// area. It is only used in one place (before the mission loop), so it
-// probably should be moved over to there.
-void initAliens()
+/*
+This AI is exclusively for Kline.
+*/
+void alien_setKlineAI(object *alien)
{
- for (int i = 0 ; i < MAX_ALIENS ; i++)
+ // Weapon type change
+ if ((rand() % 3) == 0)
{
- enemy[i].active = false;
- enemy[i].shield = -1;
- enemy[i].flags = 0;
- }
-
- engine.targetIndex = -1;
-
- aliens_getPreDefined();
-
- // specific for Phoebe being captured!
- if (currentGame.area == 7)
- currentGame.hasWingMate1 = 1;
-
- if (currentGame.area == 11)
- enemy[WC_KLINE].active = false;
-
- for (int i = 0 ; i < engine.maxAliens ; i++)
- alien_add();
-
- if (currentGame.hasWingMate1)
- alien_addFriendly(FR_PHOEBE);
-
- if (currentGame.hasWingMate2)
- alien_addFriendly(FR_URSULA);
-
- if ((currentGame.area == 9) || (currentGame.area == 17) ||
- (currentGame.area == 25))
- alien_addFriendly(FR_SID);
-
- // Disable Wingmates for certain missions
- switch (currentGame.area)
- {
- case 7:
- case 9:
- case 10:
- case 15:
- case 16:
- case 18:
- case 24:
- case 26:
- enemy[FR_PHOEBE].active = false;
- enemy[FR_URSULA].active = false;
- break;
- }
-
- if (currentGame.area == 10)
- {
- enemy[0].collectChance = 100;
- enemy[0].collectType = P_ESCAPEPOD;
- }
-
- // Some specifics for interception missions
- if (currentGame.area == MAX_MISSIONS - 1)
- {
- if ((currentGame.system > 1) && ((rand() % 5) == 0))
+ if (currentGame.area != 26)
{
- enemy[WC_KLINE] = defEnemy[CD_KLINE];
- enemy[WC_KLINE].owner = &enemy[WC_KLINE];
- enemy[WC_KLINE].target = &player;
- enemy[WC_KLINE].shield = 100;
- enemy[WC_KLINE].active = true;
- enemy[WC_KLINE].x = player.x + 1000;
- enemy[WC_KLINE].y = player.y;
- player_setTarget(WC_KLINE);
- }
+ alien->flags &= ~FL_AIMS;
- if ((currentGame.system == 2) && (currentGame.experimentalShield > 0))
- {
- if ((rand() % 2) == 0)
+ switch(rand() % 2)
{
- enemy[10] = defEnemy[CD_CLOAKFIGHTER];
- enemy[10].owner = &enemy[10];
- enemy[10].target = &enemy[10];
- enemy[10].shield = 1000;
- enemy[10].active = true;
- enemy[10].x = player.x - 1000;
- enemy[10].y = player.y;
- player_setTarget(10);
- enemy[10].shield = currentGame.experimentalShield;
+ case 0:
+ alien->weaponType[0] = W_TRIPLE_SHOT;
+ break;
+ case 1:
+ alien->weaponType[0] = W_AIMED_SHOT;
+ alien->flags |= FL_AIMS;
+ break;
}
}
}
- if (currentGame.area == 26)
+ alien->flags &= ~(FL_CIRCLES | FL_CONTINUOUS_FIRE | FL_DROPMINES);
+
+ switch(rand() % 10)
{
- enemy[WC_KLINE].flags |= FL_IMMORTAL | FL_NOFIRE | FL_NOMOVE;
-
- enemy[WC_KLINE].x = screen->w * 2 / 3;
- enemy[WC_KLINE].y = screen->h * 2 / 3;
-
- enemy[WC_KLINE].deathCounter = -250;
- enemy[WC_KLINE].maxShield = 1500;
- enemy[WC_KLINE].shield = 500;
- }
-
- for (int i = 0 ; i < MAX_ALIENS ; i++)
- {
- enemy[i].systemPower = enemy[i].maxShield;
- enemy[i].deathCounter = 0 - (enemy[i].maxShield * 3);
- limitInt(&enemy[i].deathCounter, -350, 0);
- }
-
- // Set target energy meter
- switch (currentGame.area)
- {
- case 5:
- case 11:
- case 13:
- case 17:
- case 18:
- case 19:
- case 20:
- case 21:
- case 23:
- player_setTarget(WC_BOSS);
+ case 0:
+ if ((alien->weaponType[0] != W_DIRSHOCKMISSILE) && (alien->weaponType[1] != W_MICRO_HOMING_MISSILES))
+ alien->flags |= FL_CONTINUOUS_FIRE;
+ alien->dx = ((alien->x - alien->target->x) / ((300 / alien->speed) + rand() % 100));
+ alien->dy = ((alien->y - alien->target->y) / ((300 / alien->speed) + rand() % 100));
break;
- case 7:
- player_setTarget(FR_PHOEBE);
+ case 1:
+ case 2:
+ // Kline only attacks then he is ready!
+ if ((!(alien->flags & FL_NOFIRE)) && (currentGame.area == 11))
+ alien->flags |= FL_DROPMINES;
break;
- case 8:
- player_setTarget(19);
- break;
- case 9:
- player_setTarget(FR_SID);
- break;
- case 10:
- player_setTarget(0);
- break;
- case 25:
- case 26:
- player_setTarget(WC_KLINE);
+ case 3:
+ case 4:
+ alien->flags |= FL_CIRCLES;
break;
default:
+ alien_setAI(alien);
break;
}
}
@@ -653,7 +501,7 @@ void initAliens()
"Looks" for an enemy by picking a randomly active enemy and using them
as a target. If the target is too far away, it will be ignored.
*/
-static void alien_searchForTarget(object *alien)
+void alien_searchForTarget(object *alien)
{
int i;
@@ -712,11 +560,11 @@ static void alien_searchForTarget(object *alien)
alien->target = targetEnemy;
}
-static int alien_checkTarget(object *alien)
+/*
+Do various checks to see if the alien can fire at the target.
+*/
+int alien_checkTarget(object *alien)
{
- // Do various checks to see if the alien can fire at
- // the target. Start with the most obvious checks.
-
// No target
if (alien->target == alien)
return 0;
@@ -755,7 +603,7 @@ static int alien_checkTarget(object *alien)
Currently only used for the allies. Whilst flying around, the allies will fire on
any enemy craft that enter their line of sight.
*/
-static int alien_enemiesInFront(object *alien)
+int alien_enemiesInFront(object *alien)
{
object *anEnemy = enemy;
@@ -778,7 +626,7 @@ static int alien_enemiesInFront(object *alien)
return 0;
}
-static void alien_move(object *alien)
+void alien_move(object *alien)
{
bool checkCollisions;
@@ -877,1040 +725,3 @@ static void alien_move(object *alien)
}
}
}
-
-/*
-Call this whenever a mission requires all the remaining aliens to
-automatically die
-*/
-void mission_killAllEnemies()
-{
- for (int i = 0 ; i < MAX_ALIENS ; i++)
- {
- if ((enemy[i].flags & FL_WEAPCO) && (enemy[i].active) && (enemy[i].shield > 0))
- enemy[i].shield = 0;
- }
-}
-
-// XXX: This function is used in only one place, the main game loop.
-// Should probably be moved to there.
-void doAliens()
-{
- static float barrierLoop = 0;
-
- barrierLoop += 0.2;
-
- // A global variable for checking if all the aliens are dead
- engine.allAliensDead = 1;
-
- bool canFire;
- int shapeToUse;
-
- object *alien = enemy;
-
- for (int i = 0 ; i < MAX_ALIENS ; i++)
- {
- if (alien->active)
- {
- if (alien->shield > 0)
- {
- if ((alien->flags & FL_WEAPCO) && (!(alien->flags & FL_DISABLED)))
- engine.allAliensDead = 0;
-
- // Set part attributes
- if (alien->owner != alien)
- {
- alien->face = alien->owner->face;
-
- if (alien->face == 0)
- alien->x = alien->owner->x - alien->dx;
- else
- alien->x = alien->owner->x + alien->owner->image[0]->w + alien->dx - alien->image[0]->w;
-
- alien->y = (alien->owner->y + alien->dy);
-
- if (alien->owner->shield < 1)
- {
- if ((alien->classDef != CD_URANUSBOSSWING1) && (alien->classDef != CD_URANUSBOSSWING2))
- {
- alien->shield = 0;
- }
- else
- {
- alien->flags &= ~FL_IMMORTAL;
- alien->owner = alien;
- alien->chance[0] = 25;
- }
- }
- }
-
- canFire = true; // The alien is allowed to fire
-
- limitInt(&--alien->thinktime, 0, 250);
-
- if (alien->target->shield < 1)
- alien->target = alien;
-
- // Specific to Sid to stop him pissing about(!)
- if ((alien->classDef == CD_SID) &&
- (alien->target->flags & FL_DISABLED))
- alien->target = alien;
-
- if (alien->target == alien)
- {
- if (engine.missionCompleteTimer == 0)
- {
- alien_searchForTarget(alien);
- }
- else
- {
- if (alien->flags & FL_FRIEND)
- {
- alien->target = &player;
- alien->thinktime = 1;
- }
- }
- }
-
- if ((!(alien->flags & FL_DISABLED)) && (alien->thinktime == 0) && (alien->target != alien) && (alien->owner == alien))
- {
- if (alien->classDef == CD_KLINE)
- alien_setKlineAI(alien);
- else
- alien_setAI(alien);
-
- alien->thinktime = (rand() % 25) * 10;
-
- // Face direction of movement unless you always face your target(!)
-
- if (!(alien->flags & FL_ALWAYSFACE))
- {
- alien->face = 0;
- if (alien->dx > 0) alien->face = 1;
- }
-
- limitFloat(&alien->dx, 0 - alien->speed, alien->speed);
- limitFloat(&alien->dy, 0 - alien->speed, alien->speed);
-
- }
-
- if (alien->flags & FL_ALWAYSFACE)
- {
- alien->face = 0;
- if (alien->x > alien->target->x) alien->face = 1;
- }
-
- if ((currentGame.area == 18) && (alien->classDef == CD_BOSS))
- alien->face = 0;
-
- if ((alien->flags & FL_DEPLOYDRONES) && ((rand() % 300) == 0))
- alien_addDrone(alien);
-
- if (alien->flags & FL_LEAVESECTOR)
- {
- limitFloat(&(alien->dx -= 0.5), 0, -15);
- alien->dy = 0;
- alien->thinktime = 999;
- alien->face = 0;
-
- if (alien->x >= 5000)
- {
- alien->flags -= FL_LEAVESECTOR;
- alien->flags += FL_ESCAPED;
- alien->active = false;
-
- if (alien->classDef == CD_CLOAKFIGHTER)
- {
- currentGame.experimentalShield = alien->shield;
- setInfoLine("Experimental Fighter has fled", FONT_CYAN);
- }
-
- alien->shield = 0;
- updateMissionRequirements(M_ESCAPE_TARGET, alien->classDef, 1);
-
- if (alien->classDef != CD_CLOAKFIGHTER)
- updateMissionRequirements(M_DESTROY_TARGET_TYPE, alien->classDef, 1);
- }
- }
-
- /*
- This deals with the Experimental Fighter in Mordor (and Kline on the final mission)
- It can cloak and uncloak at random. When cloaked, it's sprite is
- not displayed. However the engine trail is still visible!
- */
- if ((alien->flags & FL_CANCLOAK) && ((rand() % 500) == 0))
- {
- if (alien->flags & FL_ISCLOAKED)
- alien->flags -= FL_ISCLOAKED;
- else
- alien->flags += FL_ISCLOAKED;
- playSound(SFX_CLOAK, alien->x);
- }
-
- // ------------ Barriers ------------------
-
- if (alien->classDef == CD_BARRIER)
- {
- alien->dx = -10 + (sinf(barrierLoop + alien->speed) * 60);
- alien->dy = 20 + (cosf(barrierLoop + alien->speed) * 40);
- }
-
- // ----------------------------------------
-
- // ------------ Mobile Shields ------------
-
- if (alien->classDef == CD_MOBILESHIELD)
- {
- limitInt(&(++enemy[WC_BOSS].shield), 0, enemy[WC_BOSS].maxShield);
- }
-
- // ----------------------------------------
-
- limitCharAdd(&alien->reload[0], -1, 0, 999);
- limitCharAdd(&alien->reload[1], -1, 0, 999);
-
- if ((!(alien->flags & FL_DISABLED)) &&
- (!(alien->flags & FL_NOFIRE)))
- {
- if ((alien->target->shield > 0))
- canFire = alien_checkTarget(alien);
-
- if (((alien->thinktime % 2) == 0) &&
- (alien->flags & FL_FRIEND))
- canFire = alien_enemiesInFront(alien);
- }
- else
- {
- canFire = false;
- }
-
- if ((canFire) && (dev.fireAliens))
- {
- if ((alien->reload[0] == 0) &&
- ((rand() % 1000 < alien->chance[0]) ||
- (alien->flags & FL_CONTINUOUS_FIRE)))
- {
- fireBullet(alien, 0);
- }
- if ((alien->reload[1] == 0) &&
- ((rand() % 1000 < alien->chance[1]) ||
- (alien->flags & FL_CONTINUOUS_FIRE)))
- {
- if ((alien->weaponType[1] != W_ENERGYRAY) &&
- (alien->weaponType[1] != W_LASER))
- {
- if (alien->weaponType[1] == W_CHARGER)
- alien->ammo[1] = 50 + rand() % 150;
- fireBullet(alien, 1);
- }
- else if (alien->weaponType[1] == W_LASER)
- {
- alien->flags += FL_FIRELASER;
- }
- else if ((alien->weaponType[1] == W_ENERGYRAY) &&
- (alien->ammo[0] == 250))
- {
- alien->flags += FL_FIRERAY;
- playSound(SFX_ENERGYRAY, alien->x);
- }
- }
- }
-
- // --------------- Ray specific stuff ------------------
- if (alien->flags & FL_FIRERAY)
- {
- fireRay(alien);
- }
- else
- {
- limitCharAdd(&alien->ammo[0], 1, 0, 250);
- }
- // -------------------------------------------------------
-
- // --------------- Laser specific stuff ------------------
- if (alien->flags & FL_FIRELASER)
- {
- fireBullet(alien, 1);
- if ((rand() % 25) == 0)
- alien->flags -= FL_FIRELASER;
- }
- // -------------------------------------------------------
-
- // ---------------- Mine specific stuff ------------------
-
- if (alien->flags & FL_DROPMINES)
- if ((rand() % 150) == 0)
- addCollectable(alien->x, alien->y, P_MINE, 25,
- 600 + rand() % 2400);
-
- // Kline drops mines a lot more often
- if ((alien->flags & FL_DROPMINES) && (alien == &enemy[WC_KLINE]))
- if ((rand() % 10) == 0)
- addCollectable(alien->x, alien->y, P_MINE, 25,
- 600 + rand() % 2400);
-
- // -------------------------------------------------------
-
- shapeToUse = alien->imageIndex[alien->face];
-
- if (alien->hit)
- shapeToUse += SHIP_HIT_INDEX;
-
- limitCharAdd(&alien->hit, -1, 0, 100);
-
- if ((alien->x + alien->image[0]->w > 0) && (alien->x < screen->w) && (alien->y + alien->image[0]->h > 0) && (alien->y < screen->h))
- {
- if ((!(alien->flags & FL_DISABLED)) && (alien->classDef != CD_ASTEROID) && (alien->classDef != CD_ASTEROID2))
- addEngine(alien);
- if ((!(alien->flags & FL_ISCLOAKED)) || (alien->hit > 0))
- blit(shipShape[shapeToUse], (int)alien->x, (int)alien->y);
- if (alien->flags & FL_DISABLED)
- {
- if ((rand() % 10) == 0)
- addExplosion(alien->x + (rand() % alien->image[0]->w), alien->y + (rand() % alien->image[0]->h), E_ELECTRICAL);
- }
- }
-
- if ((currentGame.area == 24) && (alien->x < -300))
- alien->active = false;
- }
- else
- {
- alien->shield--;
- if ((alien->x > 0) && (alien->x < screen->w) && (alien->y > 0) && (alien->y < screen->h))
- {
- blit(alien->image[alien->face], (int)alien->x, (int)alien->y);
- addExplosion(alien->x + (rand() % alien->image[0]->w), alien->y + (rand() % alien->image[0]->h), E_BIG_EXPLOSION);
- }
- if (alien->shield < alien->deathCounter)
- {
- alien->active = false;
- if ((alien->classDef == CD_BOSS) ||
- (alien->owner == &enemy[WC_BOSS]) ||
- (alien->flags & FL_FRIEND) ||
- (alien->classDef == CD_ASTEROID) ||
- (alien->classDef == CD_KLINE))
- addDebris((int)alien->x, (int)alien->y,
- alien->maxShield);
-
- if (alien->classDef == CD_ASTEROID)
- {
- int i = 1 + (rand() % 3);
- for (int j = 0 ; j < i ; j++)
- alien_addSmallAsteroid(alien);
- }
- }
- }
-
- // Adjust the movement even whilst exploding
- if ((dev.moveAliens) && (!(alien->flags & FL_NOMOVE)) &&
- (!(alien->flags & FL_DISABLED)))
- alien_move(alien);
-
- if ((currentGame.area != 18) || (alien->shield < 0))
- alien->x += engine.ssx;
-
- alien->x += engine.smx;
- alien->y += engine.ssy + engine.smy;
- }
-
- alien++;
- }
-}
-
-// XXX: This function is called only once, as part of the function that
-// loads game graphics. Should probably be merged into that function.
-void setAlienShapes()
-{
- for (int i = 0 ; i < MAX_DEFALIENS ; i++)
- {
- if (shipShape[defEnemy[i].imageIndex[0]] != NULL)
- {
- defEnemy[i].image[0] = shipShape[defEnemy[i].imageIndex[0]];
- defEnemy[i].image[1] = shipShape[defEnemy[i].imageIndex[1]];
- defEnemy[i].engineX = defEnemy[i].image[0]->w;
- defEnemy[i].engineY = (defEnemy[i].image[0]->h / 2);
- }
- }
-}
-
-// XXX: This function is called only once, before the game starts.
-// Should probably be merged into main.
-void defineAliens()
-{
- // Dual Plasma Fighter.
- defEnemy[CD_DUALFIGHTER].classDef = CD_DUALFIGHTER;
- defEnemy[CD_DUALFIGHTER].AIType = AI_NORMAL;
- defEnemy[CD_DUALFIGHTER].speed = 4;
- defEnemy[CD_DUALFIGHTER].maxShield = 5;
- defEnemy[CD_DUALFIGHTER].shield = 5;
- defEnemy[CD_DUALFIGHTER].imageIndex[0] = 2;
- defEnemy[CD_DUALFIGHTER].imageIndex[1] = 3;
- defEnemy[CD_DUALFIGHTER].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_DUALFIGHTER].weaponType[1] = W_ROCKETS;
- defEnemy[CD_DUALFIGHTER].chance[0] = 100;
- defEnemy[CD_DUALFIGHTER].chance[1] = 1;
- defEnemy[CD_DUALFIGHTER].score = 25;
- defEnemy[CD_DUALFIGHTER].collectChance = 50;
- defEnemy[CD_DUALFIGHTER].collectType = P_ANYTHING;
- defEnemy[CD_DUALFIGHTER].collectValue = 50;
- defEnemy[CD_DUALFIGHTER].flags = FL_WEAPCO;
-
- // Missile Boat
- defEnemy[CD_MISSILEBOAT].classDef = CD_MISSILEBOAT;
- defEnemy[CD_MISSILEBOAT].AIType = AI_DEFENSIVE;
- defEnemy[CD_MISSILEBOAT].speed = 2;
- defEnemy[CD_MISSILEBOAT].maxShield = 50;
- defEnemy[CD_MISSILEBOAT].shield = 50;
- defEnemy[CD_MISSILEBOAT].imageIndex[0] = 4;
- defEnemy[CD_MISSILEBOAT].imageIndex[1] = 5;
- defEnemy[CD_MISSILEBOAT].weaponType[0] = W_ROCKETS;
- defEnemy[CD_MISSILEBOAT].weaponType[1] = W_DOUBLE_ROCKETS;
- defEnemy[CD_MISSILEBOAT].chance[0] = 25;
- defEnemy[CD_MISSILEBOAT].chance[1] = 4;
- defEnemy[CD_MISSILEBOAT].score = 250;
- defEnemy[CD_MISSILEBOAT].collectChance = 25;
- defEnemy[CD_MISSILEBOAT].collectType = P_ANYTHING;
- defEnemy[CD_MISSILEBOAT].collectValue = 75;
- defEnemy[CD_MISSILEBOAT].flags = FL_WEAPCO;
-
- //Prototype fighter
- defEnemy[CD_PROTOFIGHTER].classDef = CD_PROTOFIGHTER;
- defEnemy[CD_PROTOFIGHTER].AIType = AI_DEFENSIVE;
- defEnemy[CD_PROTOFIGHTER].speed = 5;
- defEnemy[CD_PROTOFIGHTER].maxShield = 15;
- defEnemy[CD_PROTOFIGHTER].shield = 15;
- defEnemy[CD_PROTOFIGHTER].imageIndex[0] = 6;
- defEnemy[CD_PROTOFIGHTER].imageIndex[1] = 7;
- defEnemy[CD_PROTOFIGHTER].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_PROTOFIGHTER].weaponType[1] = P_ANYTHING;
- defEnemy[CD_PROTOFIGHTER].chance[0] = 100;
- defEnemy[CD_PROTOFIGHTER].chance[1] = 1;
- defEnemy[CD_PROTOFIGHTER].score = 50;
- defEnemy[CD_PROTOFIGHTER].collectChance = 50;
- defEnemy[CD_PROTOFIGHTER].collectType = P_ANYTHING;
- defEnemy[CD_PROTOFIGHTER].collectValue = 50;
- defEnemy[CD_PROTOFIGHTER].flags = FL_WEAPCO;
-
- // Phoebe and Ursula
- defEnemy[CD_FRIEND].classDef = CD_FRIEND;
- defEnemy[CD_FRIEND].AIType = AI_OFFENSIVE;
- defEnemy[CD_FRIEND].speed = 3;
- defEnemy[CD_FRIEND].maxShield = 50;
- defEnemy[CD_FRIEND].shield = 50;
- defEnemy[CD_FRIEND].imageIndex[0] = 20;
- defEnemy[CD_FRIEND].imageIndex[1] = 21;
- defEnemy[CD_FRIEND].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_FRIEND].weaponType[1] = W_HOMING_MISSILE;
- defEnemy[CD_FRIEND].chance[0] = 100;
- defEnemy[CD_FRIEND].chance[1] = 5;
- defEnemy[CD_FRIEND].score = 0;
- defEnemy[CD_FRIEND].collectChance = 0;
- defEnemy[CD_FRIEND].collectType = P_CASH;
- defEnemy[CD_FRIEND].collectValue = 0;
- defEnemy[CD_FRIEND].flags = FL_FRIEND;
-
- // Boss 1
- defEnemy[CD_FRIGATE].classDef = CD_BOSS;
- defEnemy[CD_FRIGATE].AIType = AI_NORMAL;
- defEnemy[CD_FRIGATE].speed = 2;
- defEnemy[CD_FRIGATE].maxShield = 550;
- defEnemy[CD_FRIGATE].shield = 550;
- defEnemy[CD_FRIGATE].imageIndex[0] = 8;
- defEnemy[CD_FRIGATE].imageIndex[1] = 9;
- defEnemy[CD_FRIGATE].weaponType[0] = W_MICRO_ROCKETS;
- defEnemy[CD_FRIGATE].weaponType[1] = W_ENERGYRAY;
- defEnemy[CD_FRIGATE].chance[0] = 100;
- defEnemy[CD_FRIGATE].chance[1] = 85;
- defEnemy[CD_FRIGATE].score = 500;
- defEnemy[CD_FRIGATE].collectChance = 100;
- defEnemy[CD_FRIGATE].collectType = P_CASH;
- defEnemy[CD_FRIGATE].collectValue = 250;
- defEnemy[CD_FRIGATE].flags = FL_WEAPCO;
-
- defEnemy[CD_FRIGATE_WING1].classDef = CD_FRIGATE_WING1;
- defEnemy[CD_FRIGATE_WING1].AIType = AI_NORMAL;
- defEnemy[CD_FRIGATE_WING1].speed = 2;
- defEnemy[CD_FRIGATE_WING1].maxShield = 100;
- defEnemy[CD_FRIGATE_WING1].shield = 100;
- defEnemy[CD_FRIGATE_WING1].imageIndex[0] = 10;
- defEnemy[CD_FRIGATE_WING1].imageIndex[1] = 11;
- defEnemy[CD_FRIGATE_WING1].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_FRIGATE_WING1].weaponType[1] = W_ROCKETS;
- defEnemy[CD_FRIGATE_WING1].chance[0] = 100;
- defEnemy[CD_FRIGATE_WING1].chance[1] = 10;
- defEnemy[CD_FRIGATE_WING1].score = 500;
- defEnemy[CD_FRIGATE_WING1].collectChance = 100;
- defEnemy[CD_FRIGATE_WING1].collectType = P_ANYTHING;
- defEnemy[CD_FRIGATE_WING1].collectValue = 250;
- defEnemy[CD_FRIGATE_WING1].flags = FL_WEAPCO | FL_DAMAGEOWNER;
-
- defEnemy[CD_FRIGATE_WING2].classDef = CD_FRIGATE_WING2;
- defEnemy[CD_FRIGATE_WING2].AIType = AI_NORMAL;
- defEnemy[CD_FRIGATE_WING2].speed = 2;
- defEnemy[CD_FRIGATE_WING2].maxShield = 100;
- defEnemy[CD_FRIGATE_WING2].shield = 100;
- defEnemy[CD_FRIGATE_WING2].imageIndex[0] = 12;
- defEnemy[CD_FRIGATE_WING2].imageIndex[1] = 13;
- defEnemy[CD_FRIGATE_WING2].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_FRIGATE_WING2].weaponType[1] = W_ROCKETS;
- defEnemy[CD_FRIGATE_WING2].chance[0] = 100;
- defEnemy[CD_FRIGATE_WING2].chance[1] = 10;
- defEnemy[CD_FRIGATE_WING2].score = 500;
- defEnemy[CD_FRIGATE_WING2].collectChance = 100;
- defEnemy[CD_FRIGATE_WING2].collectType = P_ANYTHING;
- defEnemy[CD_FRIGATE_WING2].collectValue = 250;
- defEnemy[CD_FRIGATE_WING2].flags = FL_WEAPCO | FL_DAMAGEOWNER;
-
- // Transport ship
- defEnemy[CD_TRANSPORTSHIP].classDef = CD_TRANSPORTSHIP;
- defEnemy[CD_TRANSPORTSHIP].AIType = AI_EVASIVE;
- defEnemy[CD_TRANSPORTSHIP].speed = 4;
- defEnemy[CD_TRANSPORTSHIP].maxShield = 10;
- defEnemy[CD_TRANSPORTSHIP].shield = 10;
- defEnemy[CD_TRANSPORTSHIP].imageIndex[0] = 14;
- defEnemy[CD_TRANSPORTSHIP].imageIndex[1] = 15;
- defEnemy[CD_TRANSPORTSHIP].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_TRANSPORTSHIP].weaponType[1] = W_DOUBLE_SHOT;
- defEnemy[CD_TRANSPORTSHIP].chance[0] = 0;
- defEnemy[CD_TRANSPORTSHIP].chance[1] = 0;
- defEnemy[CD_TRANSPORTSHIP].score = 25;
- defEnemy[CD_TRANSPORTSHIP].collectChance = 100;
- defEnemy[CD_TRANSPORTSHIP].collectType = P_WEAPONS;
- defEnemy[CD_TRANSPORTSHIP].collectValue = 30;
- defEnemy[CD_TRANSPORTSHIP].flags = FL_WEAPCO | FL_NOFIRE;
-
- // Cargo ship
- defEnemy[CD_CARGOSHIP].classDef = CD_CARGOSHIP;
- defEnemy[CD_CARGOSHIP].AIType = AI_EVASIVE;
- defEnemy[CD_CARGOSHIP].speed = 4;
- defEnemy[CD_CARGOSHIP].maxShield = 10;
- defEnemy[CD_CARGOSHIP].shield = 10;
- defEnemy[CD_CARGOSHIP].imageIndex[0] = 22;
- defEnemy[CD_CARGOSHIP].imageIndex[1] = 23;
- defEnemy[CD_CARGOSHIP].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_CARGOSHIP].weaponType[1] = W_DOUBLE_SHOT;
- defEnemy[CD_CARGOSHIP].chance[0] = 0;
- defEnemy[CD_CARGOSHIP].chance[1] = 0;
- defEnemy[CD_CARGOSHIP].score = 25;
- defEnemy[CD_CARGOSHIP].collectChance = 50;
- defEnemy[CD_CARGOSHIP].collectType = P_ANYTHING;
- defEnemy[CD_CARGOSHIP].collectValue = 100;
- defEnemy[CD_CARGOSHIP].flags = FL_WEAPCO | FL_NOFIRE;
-
- // Weapco Miner
- defEnemy[CD_MINER].classDef = CD_MINER;
- defEnemy[CD_MINER].AIType = AI_EVASIVE;
- defEnemy[CD_MINER].speed = 4;
- defEnemy[CD_MINER].maxShield = 25;
- defEnemy[CD_MINER].shield = 25;
- defEnemy[CD_MINER].imageIndex[0] = 16;
- defEnemy[CD_MINER].imageIndex[1] = 17;
- defEnemy[CD_MINER].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_MINER].weaponType[1] = W_DOUBLE_SHOT;
- defEnemy[CD_MINER].chance[0] = 0;
- defEnemy[CD_MINER].chance[1] = 0;
- defEnemy[CD_MINER].score = 100;
- defEnemy[CD_MINER].collectChance = 100;
- defEnemy[CD_MINER].collectType = P_ANYTHING;
- defEnemy[CD_MINER].collectValue = 30;
- defEnemy[CD_MINER].flags = FL_WEAPCO | FL_NOFIRE | FL_DROPMINES;
-
- // Kline
- defEnemy[CD_KLINE].classDef = CD_KLINE;
- defEnemy[CD_KLINE].AIType = AI_OFFENSIVE;
- defEnemy[CD_KLINE].speed = 5;
- defEnemy[CD_KLINE].maxShield = 750;
- defEnemy[CD_KLINE].shield = 750;
- defEnemy[CD_KLINE].imageIndex[0] = 18;
- defEnemy[CD_KLINE].imageIndex[1] = 19;
- defEnemy[CD_KLINE].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_KLINE].weaponType[1] = W_MICRO_ROCKETS;
- defEnemy[CD_KLINE].chance[0] = 100;
- defEnemy[CD_KLINE].chance[1] = 2;
- defEnemy[CD_KLINE].score = 0;
- defEnemy[CD_KLINE].collectChance = 0;
- defEnemy[CD_KLINE].collectType = P_ANYTHING;
- defEnemy[CD_KLINE].collectValue = 0;
- defEnemy[CD_KLINE].flags = FL_WEAPCO | FL_CANNOTDIE | FL_ALWAYSFACE | FL_CIRCLES;
-
- // Aim Fighter
- defEnemy[CD_AIMFIGHTER].classDef = CD_AIMFIGHTER;
- defEnemy[CD_AIMFIGHTER].AIType = AI_NORMAL;
- defEnemy[CD_AIMFIGHTER].speed = 3;
- defEnemy[CD_AIMFIGHTER].maxShield = 15;
- defEnemy[CD_AIMFIGHTER].shield = 15;
- defEnemy[CD_AIMFIGHTER].imageIndex[0] = 8;
- defEnemy[CD_AIMFIGHTER].imageIndex[1] = 9;
- defEnemy[CD_AIMFIGHTER].weaponType[0] = W_AIMED_SHOT;
- defEnemy[CD_AIMFIGHTER].weaponType[1] = W_AIMED_SHOT;
- defEnemy[CD_AIMFIGHTER].chance[0] = 7;
- defEnemy[CD_AIMFIGHTER].chance[1] = 1;
- defEnemy[CD_AIMFIGHTER].score = 50;
- defEnemy[CD_AIMFIGHTER].collectChance = 75;
- defEnemy[CD_AIMFIGHTER].collectType = P_ANYTHING;
- defEnemy[CD_AIMFIGHTER].collectValue = 100;
- defEnemy[CD_AIMFIGHTER].flags = FL_WEAPCO | FL_AIMS;
-
- // Slave ship
- defEnemy[CD_SLAVETRANSPORT].classDef = CD_SLAVETRANSPORT;
- defEnemy[CD_SLAVETRANSPORT].AIType = AI_EVASIVE;
- defEnemy[CD_SLAVETRANSPORT].speed = 2;
- defEnemy[CD_SLAVETRANSPORT].maxShield = 10;
- defEnemy[CD_SLAVETRANSPORT].shield = 20;
- defEnemy[CD_SLAVETRANSPORT].imageIndex[0] = 10;
- defEnemy[CD_SLAVETRANSPORT].imageIndex[1] = 11;
- defEnemy[CD_SLAVETRANSPORT].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_SLAVETRANSPORT].weaponType[1] = W_DOUBLE_SHOT;
- defEnemy[CD_SLAVETRANSPORT].chance[0] = 0;
- defEnemy[CD_SLAVETRANSPORT].chance[1] = 0;
- defEnemy[CD_SLAVETRANSPORT].score = 25;
- defEnemy[CD_SLAVETRANSPORT].collectChance = 100;
- defEnemy[CD_SLAVETRANSPORT].collectType = P_SLAVES;
- defEnemy[CD_SLAVETRANSPORT].collectValue = 25;
- defEnemy[CD_SLAVETRANSPORT].flags = FL_WEAPCO | FL_NOFIRE;
-
- // Good Transport
- defEnemy[CD_GOODTRANSPORT].classDef = CD_GOODTRANSPORT;
- defEnemy[CD_GOODTRANSPORT].AIType = AI_EVASIVE;
- defEnemy[CD_GOODTRANSPORT].speed = 3;
- defEnemy[CD_GOODTRANSPORT].maxShield = 75;
- defEnemy[CD_GOODTRANSPORT].shield = 75;
- defEnemy[CD_GOODTRANSPORT].imageIndex[0] = 12;
- defEnemy[CD_GOODTRANSPORT].imageIndex[1] = 13;
- defEnemy[CD_GOODTRANSPORT].weaponType[0] = W_AIMED_SHOT;
- defEnemy[CD_GOODTRANSPORT].weaponType[1] = W_AIMED_SHOT;
- defEnemy[CD_GOODTRANSPORT].chance[0] = 100;
- defEnemy[CD_GOODTRANSPORT].chance[1] = 100;
- defEnemy[CD_GOODTRANSPORT].score = 0;
- defEnemy[CD_GOODTRANSPORT].collectChance = 0;
- defEnemy[CD_GOODTRANSPORT].collectType = P_ANYTHING;
- defEnemy[CD_GOODTRANSPORT].collectValue = 0;
- defEnemy[CD_GOODTRANSPORT].flags = FL_FRIEND | FL_NOFIRE | FL_AIMS;
-
- // Sid Wilson
- defEnemy[CD_SID].classDef = CD_SID;
- defEnemy[CD_SID].AIType = AI_NORMAL;
- defEnemy[CD_SID].speed = 3;
- defEnemy[CD_SID].maxShield = 50;
- defEnemy[CD_SID].shield = 50;
- defEnemy[CD_SID].imageIndex[0] = 24;
- defEnemy[CD_SID].imageIndex[1] = 25;
- defEnemy[CD_SID].weaponType[0] = W_IONCANNON;
- defEnemy[CD_SID].weaponType[1] = W_IONCANNON;
- defEnemy[CD_SID].chance[0] = 100;
- defEnemy[CD_SID].chance[1] = 0;
- defEnemy[CD_SID].score = 0;
- defEnemy[CD_SID].collectChance = 0;
- defEnemy[CD_SID].collectType = P_ANYTHING;
- defEnemy[CD_SID].collectValue = 0;
- defEnemy[CD_SID].flags = FL_FRIEND | FL_AIMS;
-
- // Mining Vessel Boss
- defEnemy[CD_MINEBOSS].classDef = CD_BOSS;
- defEnemy[CD_MINEBOSS].AIType = AI_NORMAL;
- defEnemy[CD_MINEBOSS].speed = 3;
- defEnemy[CD_MINEBOSS].maxShield = 1000;
- defEnemy[CD_MINEBOSS].shield = 1000;
- defEnemy[CD_MINEBOSS].imageIndex[0] = 26;
- defEnemy[CD_MINEBOSS].imageIndex[1] = 27;
- defEnemy[CD_MINEBOSS].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_MINEBOSS].weaponType[1] = W_SPREADSHOT;
- defEnemy[CD_MINEBOSS].chance[0] = 0;
- defEnemy[CD_MINEBOSS].chance[1] = 0;
- defEnemy[CD_MINEBOSS].score = 1000;
- defEnemy[CD_MINEBOSS].collectChance = 100;
- defEnemy[CD_MINEBOSS].collectType = P_ANYTHING;
- defEnemy[CD_MINEBOSS].collectValue = 255;
- defEnemy[CD_MINEBOSS].flags = FL_WEAPCO | FL_IMMORTAL;
-
- defEnemy[CD_BOSS2_WING1].classDef = CD_BOSS2_WING1;
- defEnemy[CD_BOSS2_WING1].AIType = AI_NORMAL;
- defEnemy[CD_BOSS2_WING1].speed = 1;
- defEnemy[CD_BOSS2_WING1].maxShield = 250;
- defEnemy[CD_BOSS2_WING1].shield = 250;
- defEnemy[CD_BOSS2_WING1].imageIndex[0] = 28;
- defEnemy[CD_BOSS2_WING1].imageIndex[1] = 29;
- defEnemy[CD_BOSS2_WING1].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_BOSS2_WING1].weaponType[1] = W_SPREADSHOT;
- defEnemy[CD_BOSS2_WING1].chance[0] = 0;
- defEnemy[CD_BOSS2_WING1].chance[1] = 0;
- defEnemy[CD_BOSS2_WING1].score = 1000;
- defEnemy[CD_BOSS2_WING1].collectChance = 100;
- defEnemy[CD_BOSS2_WING1].collectType = P_ANYTHING;
- defEnemy[CD_BOSS2_WING1].collectValue = 255;
- defEnemy[CD_BOSS2_WING1].flags = FL_WEAPCO | FL_DAMAGEOWNER;
-
- defEnemy[CD_BOSS2_WING2].classDef = CD_BOSS2_WING2;
- defEnemy[CD_BOSS2_WING2].AIType = AI_NORMAL;
- defEnemy[CD_BOSS2_WING2].speed = 1;
- defEnemy[CD_BOSS2_WING2].maxShield = 500;
- defEnemy[CD_BOSS2_WING2].shield = 500;
- defEnemy[CD_BOSS2_WING2].imageIndex[0] = 30;
- defEnemy[CD_BOSS2_WING2].imageIndex[1] = 31;
- defEnemy[CD_BOSS2_WING2].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_BOSS2_WING2].weaponType[1] = W_SPREADSHOT;
- defEnemy[CD_BOSS2_WING2].chance[0] = 0;
- defEnemy[CD_BOSS2_WING2].chance[1] = 0;
- defEnemy[CD_BOSS2_WING2].score = 1000;
- defEnemy[CD_BOSS2_WING2].collectChance = 100;
- defEnemy[CD_BOSS2_WING2].collectType = P_ANYTHING;
- defEnemy[CD_BOSS2_WING2].collectValue = 255;
- defEnemy[CD_BOSS2_WING2].flags = FL_WEAPCO | FL_DEPLOYDRONES | FL_DAMAGEOWNER;
-
- defEnemy[CD_BOSS2_WING3].classDef = CD_BOSS2_WING3;
- defEnemy[CD_BOSS2_WING3].AIType = AI_NORMAL;
- defEnemy[CD_BOSS2_WING3].speed = 1;
- defEnemy[CD_BOSS2_WING3].maxShield = 500;
- defEnemy[CD_BOSS2_WING3].shield = 500;
- defEnemy[CD_BOSS2_WING3].imageIndex[0] = 32;
- defEnemy[CD_BOSS2_WING3].imageIndex[1] = 33;
- defEnemy[CD_BOSS2_WING3].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_BOSS2_WING3].weaponType[1] = W_SPREADSHOT;
- defEnemy[CD_BOSS2_WING3].chance[0] = 0;
- defEnemy[CD_BOSS2_WING3].chance[1] = 0;
- defEnemy[CD_BOSS2_WING3].score = 1000;
- defEnemy[CD_BOSS2_WING3].collectChance = 100;
- defEnemy[CD_BOSS2_WING3].collectType = P_ANYTHING;
- defEnemy[CD_BOSS2_WING3].collectValue = 255;
- defEnemy[CD_BOSS2_WING3].flags = FL_WEAPCO | FL_DEPLOYDRONES | FL_DAMAGEOWNER;
-
- defEnemy[CD_BOSS2_WING4].classDef = CD_BOSS2_WING4;
- defEnemy[CD_BOSS2_WING4].AIType = AI_NORMAL;
- defEnemy[CD_BOSS2_WING4].speed = 1;
- defEnemy[CD_BOSS2_WING4].maxShield = 250;
- defEnemy[CD_BOSS2_WING4].shield = 250;
- defEnemy[CD_BOSS2_WING4].imageIndex[0] = 34;
- defEnemy[CD_BOSS2_WING4].imageIndex[1] = 35;
- defEnemy[CD_BOSS2_WING4].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_BOSS2_WING4].weaponType[1] = W_SPREADSHOT;
- defEnemy[CD_BOSS2_WING4].chance[0] = 0;
- defEnemy[CD_BOSS2_WING4].chance[1] = 0;
- defEnemy[CD_BOSS2_WING4].score = 1000;
- defEnemy[CD_BOSS2_WING4].collectChance = 100;
- defEnemy[CD_BOSS2_WING4].collectType = P_ANYTHING;
- defEnemy[CD_BOSS2_WING4].collectValue = 255;
- defEnemy[CD_BOSS2_WING4].flags = FL_WEAPCO | FL_DAMAGEOWNER;
-
- // Drone
- defEnemy[CD_DRONE].classDef = CD_DRONE;
- defEnemy[CD_DRONE].AIType = AI_OFFENSIVE;
- defEnemy[CD_DRONE].speed = 8;
- defEnemy[CD_DRONE].maxShield = 5;
- defEnemy[CD_DRONE].shield = 5;
- defEnemy[CD_DRONE].imageIndex[0] = 36;
- defEnemy[CD_DRONE].imageIndex[1] = 37;
- defEnemy[CD_DRONE].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_DRONE].weaponType[1] = W_LASER;
- defEnemy[CD_DRONE].chance[0] = 100;
- defEnemy[CD_DRONE].chance[1] = 0;
- defEnemy[CD_DRONE].score = 0;
- defEnemy[CD_DRONE].collectChance = 10;
- defEnemy[CD_DRONE].collectType = P_SHIELD;
- defEnemy[CD_DRONE].collectValue = 1;
- defEnemy[CD_DRONE].flags = FL_WEAPCO;
-
- // Experimental Fighter
- defEnemy[CD_CLOAKFIGHTER].classDef = CD_CLOAKFIGHTER;
- defEnemy[CD_CLOAKFIGHTER].AIType = AI_OFFENSIVE;
- defEnemy[CD_CLOAKFIGHTER].speed = 6;
- defEnemy[CD_CLOAKFIGHTER].maxShield = 1000;
- defEnemy[CD_CLOAKFIGHTER].shield = 1000;
- defEnemy[CD_CLOAKFIGHTER].imageIndex[0] = 10;
- defEnemy[CD_CLOAKFIGHTER].imageIndex[1] = 11;
- defEnemy[CD_CLOAKFIGHTER].weaponType[0] = W_SPREADSHOT;
- defEnemy[CD_CLOAKFIGHTER].weaponType[1] = W_DOUBLE_ROCKETS;
- defEnemy[CD_CLOAKFIGHTER].chance[0] = 100;
- defEnemy[CD_CLOAKFIGHTER].chance[1] = 5;
- defEnemy[CD_CLOAKFIGHTER].score = 550;
- defEnemy[CD_CLOAKFIGHTER].collectChance = 100;
- defEnemy[CD_CLOAKFIGHTER].collectType = P_CASH;
- defEnemy[CD_CLOAKFIGHTER].collectValue = 255;
- defEnemy[CD_CLOAKFIGHTER].flags = FL_WEAPCO | FL_CANCLOAK | FL_RUNSAWAY;
-
- // Evil Ursula
- defEnemy[CD_EVILURSULA].classDef = CD_EVILURSULA;
- defEnemy[CD_EVILURSULA].AIType = AI_OFFENSIVE;
- defEnemy[CD_EVILURSULA].speed = 5;
- defEnemy[CD_EVILURSULA].maxShield = 500;
- defEnemy[CD_EVILURSULA].shield = 500;
- defEnemy[CD_EVILURSULA].imageIndex[0] = 12;
- defEnemy[CD_EVILURSULA].imageIndex[1] = 13;
- defEnemy[CD_EVILURSULA].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_EVILURSULA].weaponType[1] = W_HOMING_MISSILE;
- defEnemy[CD_EVILURSULA].chance[0] = 100;
- defEnemy[CD_EVILURSULA].chance[1] = 100;
- defEnemy[CD_EVILURSULA].score = 500;
- defEnemy[CD_EVILURSULA].collectChance = 100;
- defEnemy[CD_EVILURSULA].collectType = P_ESCAPEPOD;
- defEnemy[CD_EVILURSULA].collectValue = 1;
- defEnemy[CD_EVILURSULA].flags = FL_WEAPCO;
-
- // Mercenary
- defEnemy[CD_KRASS].classDef = CD_KRASS;
- defEnemy[CD_KRASS].AIType = AI_OFFENSIVE;
- defEnemy[CD_KRASS].speed = 5;
- defEnemy[CD_KRASS].maxShield = 1000;
- defEnemy[CD_KRASS].shield = 1000;
- defEnemy[CD_KRASS].imageIndex[0] = 26;
- defEnemy[CD_KRASS].imageIndex[1] = 27;
- defEnemy[CD_KRASS].weaponType[0] = W_SPREADSHOT;
- defEnemy[CD_KRASS].weaponType[1] = W_CHARGER;
- defEnemy[CD_KRASS].chance[0] = 100;
- defEnemy[CD_KRASS].chance[1] = 0;
- defEnemy[CD_KRASS].score = 2000;
- defEnemy[CD_KRASS].collectChance = 100;
- defEnemy[CD_KRASS].collectType = P_ANYTHING;
- defEnemy[CD_KRASS].collectValue = 255;
- defEnemy[CD_KRASS].flags = FL_FRIEND | FL_IMMORTAL;
-
- // Executive Transport
- defEnemy[CD_EXEC].classDef = CD_BOSS;
- defEnemy[CD_EXEC].AIType = AI_NORMAL;
- defEnemy[CD_EXEC].speed = 5;
- defEnemy[CD_EXEC].maxShield = 1000;
- defEnemy[CD_EXEC].shield = 1000;
- defEnemy[CD_EXEC].imageIndex[0] = 28;
- defEnemy[CD_EXEC].imageIndex[1] = 28;
- defEnemy[CD_EXEC].weaponType[0] = W_SPREADSHOT;
- defEnemy[CD_EXEC].weaponType[1] = W_HOMING_MISSILE;
- defEnemy[CD_EXEC].chance[0] = 0;
- defEnemy[CD_EXEC].chance[1] = 0;
- defEnemy[CD_EXEC].score = 2000;
- defEnemy[CD_EXEC].collectChance = 0;
- defEnemy[CD_EXEC].collectType = P_ANYTHING;
- defEnemy[CD_EXEC].collectValue = 0;
- defEnemy[CD_EXEC].flags = FL_WEAPCO | FL_NOFIRE;
-
- // Asteroid
- defEnemy[CD_ASTEROID].classDef = CD_ASTEROID;
- defEnemy[CD_ASTEROID].AIType = AI_WANDER;
- defEnemy[CD_ASTEROID].speed = 1;
- defEnemy[CD_ASTEROID].maxShield = 50;
- defEnemy[CD_ASTEROID].shield = 50;
- defEnemy[CD_ASTEROID].imageIndex[0] = 38;
- defEnemy[CD_ASTEROID].imageIndex[1] = 38;
- defEnemy[CD_ASTEROID].weaponType[0] = W_SPREADSHOT;
- defEnemy[CD_ASTEROID].weaponType[1] = W_HOMING_MISSILE;
- defEnemy[CD_ASTEROID].chance[0] = 0;
- defEnemy[CD_ASTEROID].chance[1] = 0;
- defEnemy[CD_ASTEROID].score = 0;
- defEnemy[CD_ASTEROID].collectChance = 25;
- defEnemy[CD_ASTEROID].collectType = P_ORE;
- defEnemy[CD_ASTEROID].collectValue = 1;
- defEnemy[CD_ASTEROID].flags = FL_WEAPCO;
-
- defEnemy[CD_ASTEROID2].classDef = CD_ASTEROID2;
- defEnemy[CD_ASTEROID2].AIType = AI_WANDER;
- defEnemy[CD_ASTEROID2].speed = 1;
- defEnemy[CD_ASTEROID2].maxShield = 10;
- defEnemy[CD_ASTEROID2].shield = 10;
- defEnemy[CD_ASTEROID2].imageIndex[0] = 39;
- defEnemy[CD_ASTEROID2].imageIndex[1] = 40;
- defEnemy[CD_ASTEROID2].weaponType[0] = W_SPREADSHOT;
- defEnemy[CD_ASTEROID2].weaponType[1] = W_HOMING_MISSILE;
- defEnemy[CD_ASTEROID2].chance[0] = 0;
- defEnemy[CD_ASTEROID2].chance[1] = 0;
- defEnemy[CD_ASTEROID2].score = 0;
- defEnemy[CD_ASTEROID2].collectChance = 25;
- defEnemy[CD_ASTEROID2].collectType = P_ORE;
- defEnemy[CD_ASTEROID2].collectValue = 1;
- defEnemy[CD_ASTEROID2].flags = FL_WEAPCO;
-
- // Escort
- defEnemy[CD_ESCORT].classDef = CD_ESCORT;
- defEnemy[CD_ESCORT].AIType = AI_NORMAL;
- defEnemy[CD_ESCORT].speed = 3;
- defEnemy[CD_ESCORT].maxShield = 200;
- defEnemy[CD_ESCORT].shield = 200;
- defEnemy[CD_ESCORT].imageIndex[0] = 30;
- defEnemy[CD_ESCORT].imageIndex[1] = 31;
- defEnemy[CD_ESCORT].weaponType[0] = W_LASER;
- defEnemy[CD_ESCORT].weaponType[1] = W_LASER;
- defEnemy[CD_ESCORT].chance[0] = 25;
- defEnemy[CD_ESCORT].chance[1] = 25;
- defEnemy[CD_ESCORT].score = 450;
- defEnemy[CD_ESCORT].collectChance = 100;
- defEnemy[CD_ESCORT].collectType = P_ANYTHING;
- defEnemy[CD_ESCORT].collectValue = 100;
- defEnemy[CD_ESCORT].flags = FL_WEAPCO;
-
- // Mobile Ray Cannon
- defEnemy[CD_MOBILE_RAY].classDef = CD_MOBILE_RAY;
- defEnemy[CD_MOBILE_RAY].AIType = AI_OFFENSIVE;
- defEnemy[CD_MOBILE_RAY].speed = 5;
- defEnemy[CD_MOBILE_RAY].maxShield = 250;
- defEnemy[CD_MOBILE_RAY].shield = 250;
- defEnemy[CD_MOBILE_RAY].imageIndex[0] = 10;
- defEnemy[CD_MOBILE_RAY].imageIndex[1] = 11;
- defEnemy[CD_MOBILE_RAY].weaponType[0] = W_ENERGYRAY;
- defEnemy[CD_MOBILE_RAY].weaponType[1] = W_ENERGYRAY;
- defEnemy[CD_MOBILE_RAY].chance[0] = 50;
- defEnemy[CD_MOBILE_RAY].chance[1] = 50;
- defEnemy[CD_MOBILE_RAY].score = 1000;
- defEnemy[CD_MOBILE_RAY].collectChance = 75;
- defEnemy[CD_MOBILE_RAY].collectType = P_SHIELD;
- defEnemy[CD_MOBILE_RAY].collectValue = 2;
- defEnemy[CD_MOBILE_RAY].flags = FL_WEAPCO;
-
- // Rebel Carrier
- defEnemy[CD_REBELCARRIER].classDef = CD_REBELCARRIER;
- defEnemy[CD_REBELCARRIER].AIType = AI_OFFENSIVE;
- defEnemy[CD_REBELCARRIER].speed = 2;
- defEnemy[CD_REBELCARRIER].maxShield = 100;
- defEnemy[CD_REBELCARRIER].shield = 100;
- defEnemy[CD_REBELCARRIER].imageIndex[0] = 32;
- defEnemy[CD_REBELCARRIER].imageIndex[1] = 33;
- defEnemy[CD_REBELCARRIER].weaponType[0] = W_DOUBLE_ROCKETS;
- defEnemy[CD_REBELCARRIER].weaponType[1] = W_MICRO_ROCKETS;
- defEnemy[CD_REBELCARRIER].chance[0] = 50;
- defEnemy[CD_REBELCARRIER].chance[1] = 2;
- defEnemy[CD_REBELCARRIER].score = 0;
- defEnemy[CD_REBELCARRIER].collectChance = 0;
- defEnemy[CD_REBELCARRIER].collectType = P_SHIELD;
- defEnemy[CD_REBELCARRIER].collectValue = 0;
- defEnemy[CD_REBELCARRIER].flags = FL_FRIEND;
-
- // Pluto Boss
- defEnemy[CD_PLUTOBOSS].classDef = CD_PLUTOBOSS;
- defEnemy[CD_PLUTOBOSS].AIType = AI_OFFENSIVE;
- defEnemy[CD_PLUTOBOSS].speed = 4;
- defEnemy[CD_PLUTOBOSS].maxShield = 500;
- defEnemy[CD_PLUTOBOSS].shield = 500;
- defEnemy[CD_PLUTOBOSS].imageIndex[0] = 12;
- defEnemy[CD_PLUTOBOSS].imageIndex[1] = 13;
- defEnemy[CD_PLUTOBOSS].weaponType[0] = W_DOUBLE_ROCKETS;
- defEnemy[CD_PLUTOBOSS].weaponType[1] = W_MICRO_ROCKETS;
- defEnemy[CD_PLUTOBOSS].chance[0] = 50;
- defEnemy[CD_PLUTOBOSS].chance[1] = 2;
- defEnemy[CD_PLUTOBOSS].score = 1000;
- defEnemy[CD_PLUTOBOSS].collectChance = 0;
- defEnemy[CD_PLUTOBOSS].collectType = P_SHIELD;
- defEnemy[CD_PLUTOBOSS].collectValue = 0;
- defEnemy[CD_PLUTOBOSS].flags = FL_WEAPCO;
-
- // Pluto Boss Barrier
- defEnemy[CD_BARRIER].classDef = CD_BARRIER;
- defEnemy[CD_BARRIER].AIType = AI_OFFENSIVE;
- defEnemy[CD_BARRIER].speed = 1;
- defEnemy[CD_BARRIER].maxShield = 250;
- defEnemy[CD_BARRIER].shield = 250;
- defEnemy[CD_BARRIER].imageIndex[0] = 32;
- defEnemy[CD_BARRIER].imageIndex[1] = 33;
- defEnemy[CD_BARRIER].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_BARRIER].weaponType[1] = W_MICRO_ROCKETS;
- defEnemy[CD_BARRIER].chance[0] = 0;
- defEnemy[CD_BARRIER].chance[1] = 0;
- defEnemy[CD_BARRIER].score = 1000;
- defEnemy[CD_BARRIER].collectChance = 100;
- defEnemy[CD_BARRIER].collectType = P_ANYTHING;
- defEnemy[CD_BARRIER].collectValue = 25;
- defEnemy[CD_BARRIER].flags = FL_WEAPCO | FL_NOFIRE;
-
- // Neptune Boss
- defEnemy[CD_NEPTUNEBOSS].classDef = CD_NEPTUNEBOSS;
- defEnemy[CD_NEPTUNEBOSS].AIType = AI_OFFENSIVE;
- defEnemy[CD_NEPTUNEBOSS].speed = 4;
- defEnemy[CD_NEPTUNEBOSS].maxShield = 800;
- defEnemy[CD_NEPTUNEBOSS].shield = 800;
- defEnemy[CD_NEPTUNEBOSS].imageIndex[0] = 12;
- defEnemy[CD_NEPTUNEBOSS].imageIndex[1] = 13;
- defEnemy[CD_NEPTUNEBOSS].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_NEPTUNEBOSS].weaponType[1] = W_MICRO_ROCKETS;
- defEnemy[CD_NEPTUNEBOSS].chance[0] = 100;
- defEnemy[CD_NEPTUNEBOSS].chance[1] = 0;
- defEnemy[CD_NEPTUNEBOSS].score = 1000;
- defEnemy[CD_NEPTUNEBOSS].collectChance = 100;
- defEnemy[CD_NEPTUNEBOSS].collectType = P_ANYTHING;
- defEnemy[CD_NEPTUNEBOSS].collectValue = 25;
- defEnemy[CD_NEPTUNEBOSS].flags = FL_WEAPCO;
-
- // Mobile Shield
- defEnemy[CD_MOBILESHIELD].classDef = CD_MOBILESHIELD;
- defEnemy[CD_MOBILESHIELD].AIType = AI_EVASIVE;
- defEnemy[CD_MOBILESHIELD].speed = 6;
- defEnemy[CD_MOBILESHIELD].maxShield = 150;
- defEnemy[CD_MOBILESHIELD].shield = 150;
- defEnemy[CD_MOBILESHIELD].imageIndex[0] = 34;
- defEnemy[CD_MOBILESHIELD].imageIndex[1] = 35;
- defEnemy[CD_MOBILESHIELD].weaponType[0] = W_DOUBLE_SHOT;
- defEnemy[CD_MOBILESHIELD].weaponType[1] = W_MICRO_ROCKETS;
- defEnemy[CD_MOBILESHIELD].chance[0] = 0;
- defEnemy[CD_MOBILESHIELD].chance[1] = 0;
- defEnemy[CD_MOBILESHIELD].score = 250;
- defEnemy[CD_MOBILESHIELD].collectChance = 100;
- defEnemy[CD_MOBILESHIELD].collectType = P_ANYTHING;
- defEnemy[CD_MOBILESHIELD].collectValue = 25;
- defEnemy[CD_MOBILESHIELD].flags = FL_WEAPCO | FL_NOFIRE;
-
- // Firefly
- defEnemy[CD_FIREFLY].classDef = CD_FIREFLY;
- defEnemy[CD_FIREFLY].AIType = AI_OFFENSIVE;
- defEnemy[CD_FIREFLY].speed = 5;
- defEnemy[CD_FIREFLY].maxShield = 250;
- defEnemy[CD_FIREFLY].shield = 250;
- defEnemy[CD_FIREFLY].imageIndex[0] = 0;
- defEnemy[CD_FIREFLY].imageIndex[1] = 1;
- defEnemy[CD_FIREFLY].weaponType[0] = W_TRIPLE_SHOT;
- defEnemy[CD_FIREFLY].weaponType[1] = W_DOUBLE_ROCKETS;
- defEnemy[CD_FIREFLY].chance[0] = 100;
- defEnemy[CD_FIREFLY].chance[1] = 5;
- defEnemy[CD_FIREFLY].score = 500;
- defEnemy[CD_FIREFLY].collectChance = 100;
- defEnemy[CD_FIREFLY].collectType = P_ANYTHING;
- defEnemy[CD_FIREFLY].collectValue = 250;
- defEnemy[CD_FIREFLY].flags = FL_WEAPCO;
-
- // Uranus Boss
- defEnemy[CD_URANUSBOSS].classDef = CD_URANUSBOSS;
- defEnemy[CD_URANUSBOSS].AIType = AI_OFFENSIVE;
- defEnemy[CD_URANUSBOSS].speed = 4;
- defEnemy[CD_URANUSBOSS].maxShield = 750;
- defEnemy[CD_URANUSBOSS].shield = 750;
- defEnemy[CD_URANUSBOSS].imageIndex[0] = 41;
- defEnemy[CD_URANUSBOSS].imageIndex[1] = 42;
- defEnemy[CD_URANUSBOSS].weaponType[0] = W_SPREADSHOT;
- defEnemy[CD_URANUSBOSS].weaponType[1] = W_DOUBLE_ROCKETS;
- defEnemy[CD_URANUSBOSS].chance[0] = 100;
- defEnemy[CD_URANUSBOSS].chance[1] = 5;
- defEnemy[CD_URANUSBOSS].score = 500;
- defEnemy[CD_URANUSBOSS].collectChance = 100;
- defEnemy[CD_URANUSBOSS].collectType = P_ANYTHING;
- defEnemy[CD_URANUSBOSS].collectValue = 250;
- defEnemy[CD_URANUSBOSS].flags = FL_WEAPCO;
-
- // Uranus Boss Wing 1
- defEnemy[CD_URANUSBOSSWING1].classDef = CD_URANUSBOSSWING1;
- defEnemy[CD_URANUSBOSSWING1].AIType = AI_OFFENSIVE;
- defEnemy[CD_URANUSBOSSWING1].speed = 4;
- defEnemy[CD_URANUSBOSSWING1].maxShield = 250;
- defEnemy[CD_URANUSBOSSWING1].shield = 250;
- defEnemy[CD_URANUSBOSSWING1].imageIndex[0] = 43;
- defEnemy[CD_URANUSBOSSWING1].imageIndex[1] = 44;
- defEnemy[CD_URANUSBOSSWING1].weaponType[0] = W_DOUBLE_ROCKETS;
- defEnemy[CD_URANUSBOSSWING1].weaponType[1] = W_DOUBLE_ROCKETS;
- defEnemy[CD_URANUSBOSSWING1].chance[0] = 5;
- defEnemy[CD_URANUSBOSSWING1].chance[1] = 0;
- defEnemy[CD_URANUSBOSSWING1].score = 500;
- defEnemy[CD_URANUSBOSSWING1].collectChance = 100;
- defEnemy[CD_URANUSBOSSWING1].collectType = P_ANYTHING;
- defEnemy[CD_URANUSBOSSWING1].collectValue = 250;
- defEnemy[CD_URANUSBOSSWING1].flags = FL_WEAPCO | FL_IMMORTAL;
-
- // Uranus Boss Wing 2
- defEnemy[CD_URANUSBOSSWING2].classDef = CD_URANUSBOSSWING2;
- defEnemy[CD_URANUSBOSSWING2].AIType = AI_OFFENSIVE;
- defEnemy[CD_URANUSBOSSWING2].speed = 4;
- defEnemy[CD_URANUSBOSSWING2].maxShield = 250;
- defEnemy[CD_URANUSBOSSWING2].shield = 250;
- defEnemy[CD_URANUSBOSSWING2].imageIndex[0] = 45;
- defEnemy[CD_URANUSBOSSWING2].imageIndex[1] = 46;
- defEnemy[CD_URANUSBOSSWING2].weaponType[0] = W_DOUBLE_ROCKETS;
- defEnemy[CD_URANUSBOSSWING2].weaponType[1] = W_DOUBLE_ROCKETS;
- defEnemy[CD_URANUSBOSSWING2].chance[0] = 5;
- defEnemy[CD_URANUSBOSSWING2].chance[1] = 0;
- defEnemy[CD_URANUSBOSSWING2].score = 500;
- defEnemy[CD_URANUSBOSSWING2].collectChance = 100;
- defEnemy[CD_URANUSBOSSWING2].collectType = P_ANYTHING;
- defEnemy[CD_URANUSBOSSWING2].collectValue = 250;
- defEnemy[CD_URANUSBOSSWING2].flags = FL_WEAPCO | FL_IMMORTAL;
-}
diff --git a/src/aliens.h b/src/aliens.h
index 1fd3941..8d20b5e 100644
--- a/src/aliens.h
+++ b/src/aliens.h
@@ -17,18 +17,23 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#ifndef ALIENS_H
-#define ALIENS_H
+#ifndef ALIEN_H
+#define ALIEN_H
extern object defEnemy[MAX_DEFALIENS];
extern object enemy[MAX_ALIENS];
bool alien_add();
-void player_setTarget(int index);
-void initAliens();
-void mission_killAllEnemies();
-void doAliens();
-void setAlienShapes();
-void defineAliens();
+void alien_addDrone(object *hostAlien);
+void alien_addSmallAsteroid(object *hostAlien);
+void alien_addFriendly(int type);
+bool alien_place(object *alien);
+void alien_setAI(object *alien);
+void alien_setKlineAttackMethod(object *alien);
+void alien_setKlineAI(object *alien);
+void alien_searchForTarget(object *alien);
+int alien_checkTarget(object *alien);
+int alien_enemiesInFront(object *alien);
+void alien_move(object *alien);
#endif
diff --git a/src/game.cpp b/src/game.cpp
index a0f6efc..4c1e4bf 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -122,6 +122,16 @@ void newGame()
int mainGameLoop()
{
+ static float barrierLoop = 0;
+
+ bool canFire;
+ int shapeToUse;
+ FILE *fp;
+ char string[255];
+ int index, alienType, placeAttempt;
+ int barrierSpeed;
+ int n;
+
resetLists();
setMission(currentGame.area);
@@ -129,7 +139,305 @@ int mainGameLoop()
initCargo();
initPlayer();
- initAliens();
+
+ // Init aliens
+ for (int i = 0 ; i < MAX_ALIENS ; i++)
+ {
+ enemy[i].active = false;
+ enemy[i].shield = -1;
+ enemy[i].flags = 0;
+ }
+
+ engine.targetIndex = -1;
+
+ strcpy(string, "");
+ barrierSpeed = 1;
+
+ sprintf(string, "data/aliens%d.dat", currentGame.area);
+ fp = fopen(string, "rb");
+
+ if (fp != NULL)
+ {
+ while (fscanf(fp, "%d %d ", &index, &alienType) == 2)
+ {
+ placeAttempt = 0;
+
+ enemy[index] = defEnemy[alienType];
+ enemy[index].owner = &enemy[index];
+ enemy[index].target = &enemy[index];
+ enemy[index].face = rand() % 2;
+ enemy[index].active = true;
+
+ /*
+ we make 1000 attempts to place this enemy since it is required. If after
+ 1000 attempts we still haven't managed to place the alien, then it
+ simply isn't going to happen and we will just exit the game. The chances
+ of this happening are very very low!
+ */
+ while (true)
+ {
+ placeAttempt++;
+
+ if (alien_place(&enemy[index]))
+ break;
+
+ if (placeAttempt > 1000)
+ showErrorAndExit(2, "");
+ }
+
+ if (currentGame.area == 2)
+ addCargo(&enemy[index], P_CARGO);
+ else if (currentGame.area == 7)
+ addCargo(&enemy[index], P_PHOEBE);
+
+ if (index == WC_KLINE)
+ {
+ enemy[WC_KLINE].target = &player;
+ if (currentGame.area == 25)
+ enemy[WC_KLINE].shield = 500;
+ }
+
+ if (enemy[index].classDef == CD_CLOAKFIGHTER)
+ {
+ enemy[index].active = false;
+ enemy[index].maxShield = enemy[index].shield = 400;
+ enemy[index].flags &= ~FL_RUNSAWAY;
+ enemy[index].speed = 3;
+ }
+
+ if ((enemy[index].classDef == CD_MOBILE_RAY) && (index >= 11))
+ {
+ enemy[index].active = false;
+ }
+
+ if (enemy[index].classDef == CD_FIREFLY)
+ {
+ enemy[index].active = false;
+ }
+
+ if (enemy[index].classDef == CD_BARRIER)
+ {
+ enemy[index].owner = &enemy[WC_BOSS];
+ enemy[index].speed = barrierSpeed;
+ barrierSpeed++;
+ }
+
+ if ((currentGame.area == 17) && (enemy[index].classDef == CD_BOSS))
+ {
+ enemy[index].imageIndex[1] = 29;
+ enemy[index].flags |= FL_IMMORTAL;
+ }
+
+ if (currentGame.area == 18)
+ enemy[index].flags |= FL_HASMINIMUMSPEED;
+
+ if (currentGame.area == 23)
+ {
+ enemy[index].flags = FL_WEAPCO;
+ if (index == WC_BOSS)
+ enemy[index].chance[1] = 5;
+ }
+ }
+
+ fclose(fp);
+
+ if (currentGame.area == 5)
+ {
+ enemy[WC_BOSS].target = &player;
+ enemy[WC_BOSS].x = -screen->w / 2;
+ enemy[WC_BOSS].y = screen->h / 2;
+
+ enemy[13].owner = &enemy[WC_BOSS];
+ enemy[13].target = &player;
+ enemy[13].dx = -25;
+ enemy[13].dy = -21;
+
+ enemy[12].owner = &enemy[WC_BOSS];
+ enemy[12].target = &player;
+ enemy[12].dx = -20;
+ enemy[12].dy = 37;
+ }
+ else if ((currentGame.area == 11) || (currentGame.area == 14))
+ {
+ enemy[WC_BOSS].target = &player;
+ enemy[WC_BOSS].x = -screen->w / 2;
+ enemy[WC_BOSS].y = screen->h / 2;
+
+ enemy[13].owner = &enemy[WC_BOSS];
+ enemy[13].target = &player;
+ enemy[13].dx = 15;
+ enemy[13].dy = -22;
+
+ enemy[12].owner = &enemy[WC_BOSS];
+ enemy[12].target = &player;
+ enemy[12].dx = 15;
+ enemy[12].dy = 22;
+
+ enemy[11].owner = &enemy[13];
+ enemy[11].target = &player;
+ enemy[11].dx = -35;
+ enemy[11].dy = -12;
+
+ enemy[10].owner = &enemy[12];
+ enemy[10].target = &player;
+ enemy[10].dx = -35;
+ enemy[10].dy = 20;
+
+ if (currentGame.area == 14)
+ {
+ enemy[WC_BOSS].AIType = AI_EVASIVE;
+
+ for (int i = 10 ; i < 15 ; i++)
+ {
+ enemy[i].imageIndex[0] += 15;
+ enemy[i].imageIndex[1] += 15;
+
+ enemy[i].image[0] = shipShape[enemy[i].imageIndex[0]];
+ enemy[i].image[1] = shipShape[enemy[i].imageIndex[1]];
+ }
+ }
+ }
+ else if (currentGame.area == 21)
+ {
+ enemy[WC_BOSS].target = &player;
+ enemy[WC_BOSS].x = -screen->w / 2;
+ enemy[WC_BOSS].y = screen->h / 2;
+
+ enemy[13].owner = &enemy[WC_BOSS];
+ enemy[13].dy = 20;
+
+ enemy[12].owner = &enemy[WC_BOSS];
+ enemy[12].dy = -16;
+ }
+ }
+
+ // specific for Phoebe being captured!
+ if (currentGame.area == 7)
+ currentGame.hasWingMate1 = 1;
+
+ if (currentGame.area == 11)
+ enemy[WC_KLINE].active = false;
+
+ for (int i = 0 ; i < engine.maxAliens ; i++)
+ alien_add();
+
+ if (currentGame.hasWingMate1)
+ alien_addFriendly(FR_PHOEBE);
+
+ if (currentGame.hasWingMate2)
+ alien_addFriendly(FR_URSULA);
+
+ if ((currentGame.area == 9) || (currentGame.area == 17) ||
+ (currentGame.area == 25))
+ alien_addFriendly(FR_SID);
+
+ // Disable Wingmates for certain missions
+ switch (currentGame.area)
+ {
+ case 7:
+ case 9:
+ case 10:
+ case 15:
+ case 16:
+ case 18:
+ case 24:
+ case 26:
+ enemy[FR_PHOEBE].active = false;
+ enemy[FR_URSULA].active = false;
+ break;
+ }
+
+ if (currentGame.area == 10)
+ {
+ enemy[0].collectChance = 100;
+ enemy[0].collectType = P_ESCAPEPOD;
+ }
+
+ // Some specifics for interception missions
+ if (currentGame.area == MAX_MISSIONS - 1)
+ {
+ if ((currentGame.system > 1) && ((rand() % 5) == 0))
+ {
+ enemy[WC_KLINE] = defEnemy[CD_KLINE];
+ enemy[WC_KLINE].owner = &enemy[WC_KLINE];
+ enemy[WC_KLINE].target = &player;
+ enemy[WC_KLINE].shield = 100;
+ enemy[WC_KLINE].active = true;
+ enemy[WC_KLINE].x = player.x + 1000;
+ enemy[WC_KLINE].y = player.y;
+ player_setTarget(WC_KLINE);
+ }
+
+ if ((currentGame.system == 2) && (currentGame.experimentalShield > 0))
+ {
+ if ((rand() % 2) == 0)
+ {
+ enemy[10] = defEnemy[CD_CLOAKFIGHTER];
+ enemy[10].owner = &enemy[10];
+ enemy[10].target = &enemy[10];
+ enemy[10].shield = 1000;
+ enemy[10].active = true;
+ enemy[10].x = player.x - 1000;
+ enemy[10].y = player.y;
+ player_setTarget(10);
+ enemy[10].shield = currentGame.experimentalShield;
+ }
+ }
+ }
+
+ if (currentGame.area == 26)
+ {
+ enemy[WC_KLINE].flags |= FL_IMMORTAL | FL_NOFIRE | FL_NOMOVE;
+
+ enemy[WC_KLINE].x = screen->w * 2 / 3;
+ enemy[WC_KLINE].y = screen->h * 2 / 3;
+
+ enemy[WC_KLINE].deathCounter = -250;
+ enemy[WC_KLINE].maxShield = 1500;
+ enemy[WC_KLINE].shield = 500;
+ }
+
+ for (int i = 0 ; i < MAX_ALIENS ; i++)
+ {
+ enemy[i].systemPower = enemy[i].maxShield;
+ enemy[i].deathCounter = 0 - (enemy[i].maxShield * 3);
+ limitInt(&enemy[i].deathCounter, -350, 0);
+ }
+
+ // Set target energy meter
+ switch (currentGame.area)
+ {
+ case 5:
+ case 11:
+ case 13:
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 23:
+ player_setTarget(WC_BOSS);
+ break;
+ case 7:
+ player_setTarget(FR_PHOEBE);
+ break;
+ case 8:
+ player_setTarget(19);
+ break;
+ case 9:
+ player_setTarget(FR_SID);
+ break;
+ case 10:
+ player_setTarget(0);
+ break;
+ case 25:
+ case 26:
+ player_setTarget(WC_KLINE);
+ break;
+ default:
+ break;
+ }
+
clearInfoLines();
loadScriptEvents();
@@ -174,7 +482,8 @@ int mainGameLoop()
// Default to no aliens dead...
engine.allAliensDead = 0;
- engine.keyState[KEY_FIRE] = engine.keyState[KEY_ALTFIRE] = 0;
+ engine.keyState[KEY_FIRE] = 0;
+ engine.keyState[KEY_ALTFIRE] = 0;
flushInput();
while (engine.done != 1)
@@ -260,7 +569,323 @@ int mainGameLoop()
doStarfield();
doCollectables();
doBullets();
- doAliens();
+
+ barrierLoop += 0.2;
+
+ // A global variable for checking if all the aliens are dead
+ engine.allAliensDead = 1;
+
+ object *alien = enemy;
+
+ for (int i = 0 ; i < MAX_ALIENS ; i++)
+ {
+ if (alien->active)
+ {
+ if (alien->shield > 0)
+ {
+ if ((alien->flags & FL_WEAPCO) && (!(alien->flags & FL_DISABLED)))
+ engine.allAliensDead = 0;
+
+ // Set part attributes
+ if (alien->owner != alien)
+ {
+ alien->face = alien->owner->face;
+
+ if (alien->face == 0)
+ alien->x = alien->owner->x - alien->dx;
+ else
+ alien->x = alien->owner->x + alien->owner->image[0]->w + alien->dx - alien->image[0]->w;
+
+ alien->y = (alien->owner->y + alien->dy);
+
+ if (alien->owner->shield < 1)
+ {
+ if ((alien->classDef != CD_URANUSBOSSWING1) &&
+ (alien->classDef != CD_URANUSBOSSWING2))
+ {
+ alien->shield = 0;
+ }
+ else
+ {
+ alien->flags &= ~FL_IMMORTAL;
+ alien->owner = alien;
+ alien->chance[0] = 25;
+ }
+ }
+ }
+
+ canFire = true; // The alien is allowed to fire
+
+ limitInt(&--alien->thinktime, 0, 250);
+
+ if (alien->target->shield < 1)
+ alien->target = alien;
+
+ // Specific to Sid to stop him pissing about(!)
+ if ((alien->classDef == CD_SID) &&
+ (alien->target->flags & FL_DISABLED))
+ alien->target = alien;
+
+ if (alien->target == alien)
+ {
+ if (engine.missionCompleteTimer == 0)
+ {
+ alien_searchForTarget(alien);
+ }
+ else
+ {
+ if (alien->flags & FL_FRIEND)
+ {
+ alien->target = &player;
+ alien->thinktime = 1;
+ }
+ }
+ }
+
+ if ((!(alien->flags & FL_DISABLED)) &&
+ (alien->thinktime == 0) && (alien->target != alien) &&
+ (alien->owner == alien))
+ {
+ if (alien->classDef == CD_KLINE)
+ alien_setKlineAI(alien);
+ else
+ alien_setAI(alien);
+
+ alien->thinktime = (rand() % 25) * 10;
+
+ // Face direction of movement unless you always face
+ // your target(!)
+ if (!(alien->flags & FL_ALWAYSFACE))
+ {
+ alien->face = (alien->dx > 0);
+ }
+
+ limitFloat(&alien->dx, 0 - alien->speed, alien->speed);
+ limitFloat(&alien->dy, 0 - alien->speed, alien->speed);
+
+ }
+
+ if (alien->flags & FL_ALWAYSFACE)
+ {
+ alien->face = 0;
+ if (alien->x > alien->target->x) alien->face = 1;
+ }
+
+ if ((currentGame.area == 18) && (alien->classDef == CD_BOSS))
+ alien->face = 0;
+
+ if ((alien->flags & FL_DEPLOYDRONES) && ((rand() % 300) == 0))
+ alien_addDrone(alien);
+
+ if (alien->flags & FL_LEAVESECTOR)
+ {
+ limitFloat(&(alien->dx -= 0.5), 0, -15);
+ alien->dy = 0;
+ alien->thinktime = 999;
+ alien->face = 0;
+
+ if (alien->x >= 5000)
+ {
+ alien->flags -= FL_LEAVESECTOR;
+ alien->flags += FL_ESCAPED;
+ alien->active = false;
+
+ if (alien->classDef == CD_CLOAKFIGHTER)
+ {
+ currentGame.experimentalShield = alien->shield;
+ setInfoLine("Experimental Fighter has fled",
+ FONT_CYAN);
+ }
+
+ alien->shield = 0;
+ updateMissionRequirements(M_ESCAPE_TARGET,
+ alien->classDef, 1);
+
+ if (alien->classDef != CD_CLOAKFIGHTER)
+ updateMissionRequirements(M_DESTROY_TARGET_TYPE,
+ alien->classDef, 1);
+ }
+ }
+
+ // This deals with the Experimental Fighter in Mordor
+ // (and Kline on the final mission)
+ // It can cloak and uncloak at random. When cloaked,
+ // its sprite is not displayed. However the engine
+ // trail is still visible!
+ if ((alien->flags & FL_CANCLOAK) && ((rand() % 500) == 0))
+ {
+ if (alien->flags & FL_ISCLOAKED)
+ alien->flags -= FL_ISCLOAKED;
+ else
+ alien->flags += FL_ISCLOAKED;
+ playSound(SFX_CLOAK, alien->x);
+ }
+
+ if (alien->classDef == CD_BARRIER)
+ {
+ alien->dx = -10 + (sinf(barrierLoop + alien->speed) * 60);
+ alien->dy = 20 + (cosf(barrierLoop + alien->speed) * 40);
+ }
+
+ if (alien->classDef == CD_MOBILESHIELD)
+ {
+ limitInt(&(++enemy[WC_BOSS].shield), 0, enemy[WC_BOSS].maxShield);
+ }
+
+ limitCharAdd(&alien->reload[0], -1, 0, 999);
+ limitCharAdd(&alien->reload[1], -1, 0, 999);
+
+ if ((!(alien->flags & FL_DISABLED)) &&
+ (!(alien->flags & FL_NOFIRE)))
+ {
+ if ((alien->target->shield > 0))
+ canFire = alien_checkTarget(alien);
+
+ if (((alien->thinktime % 2) == 0) &&
+ (alien->flags & FL_FRIEND))
+ canFire = alien_enemiesInFront(alien);
+ }
+ else
+ {
+ canFire = false;
+ }
+
+ if ((canFire) && (dev.fireAliens))
+ {
+ if ((alien->reload[0] == 0) &&
+ ((rand() % 1000 < alien->chance[0]) ||
+ (alien->flags & FL_CONTINUOUS_FIRE)))
+ {
+ fireBullet(alien, 0);
+ }
+ if ((alien->reload[1] == 0) &&
+ ((rand() % 1000 < alien->chance[1]) ||
+ (alien->flags & FL_CONTINUOUS_FIRE)))
+ {
+ if ((alien->weaponType[1] != W_ENERGYRAY) &&
+ (alien->weaponType[1] != W_LASER))
+ {
+ if (alien->weaponType[1] == W_CHARGER)
+ alien->ammo[1] = 50 + rand() % 150;
+ fireBullet(alien, 1);
+ }
+ else if (alien->weaponType[1] == W_LASER)
+ {
+ alien->flags += FL_FIRELASER;
+ }
+ else if ((alien->weaponType[1] == W_ENERGYRAY) &&
+ (alien->ammo[0] == 250))
+ {
+ alien->flags += FL_FIRERAY;
+ playSound(SFX_ENERGYRAY, alien->x);
+ }
+ }
+ }
+
+ if (alien->flags & FL_FIRERAY)
+ {
+ fireRay(alien);
+ }
+ else
+ {
+ limitCharAdd(&alien->ammo[0], 1, 0, 250);
+ }
+
+ if (alien->flags & FL_FIRELASER)
+ {
+ fireBullet(alien, 1);
+ if ((rand() % 25) == 0)
+ alien->flags -= FL_FIRELASER;
+ }
+
+ if (alien->flags & FL_DROPMINES)
+ {
+ if ((rand() % 150) == 0)
+ addCollectable(alien->x, alien->y, P_MINE, 25,
+ 600 + rand() % 2400);
+
+ // Kline drops mines a lot more often
+ if ((alien == &enemy[WC_KLINE]))
+ {
+ if ((rand() % 10) == 0)
+ addCollectable(alien->x, alien->y, P_MINE, 25,
+ 600 + rand() % 2400);
+ }
+ }
+
+ shapeToUse = alien->imageIndex[alien->face];
+
+ if (alien->hit)
+ shapeToUse += SHIP_HIT_INDEX;
+
+ limitCharAdd(&alien->hit, -1, 0, 100);
+
+ if ((alien->x + alien->image[0]->w > 0) &&
+ (alien->x < screen->w) &&
+ (alien->y + alien->image[0]->h > 0) &&
+ (alien->y < screen->h))
+ {
+ if ((!(alien->flags & FL_DISABLED)) &&
+ (alien->classDef != CD_ASTEROID) &&
+ (alien->classDef != CD_ASTEROID2))
+ addEngine(alien);
+ if ((!(alien->flags & FL_ISCLOAKED)) || (alien->hit > 0))
+ blit(shipShape[shapeToUse], (int)alien->x,
+ (int)alien->y);
+ if (alien->flags & FL_DISABLED)
+ {
+ if ((rand() % 10) == 0)
+ addExplosion(alien->x + (rand() % alien->image[0]->w), alien->y + (rand() % alien->image[0]->h), E_ELECTRICAL);
+ }
+ }
+
+ if ((currentGame.area == 24) && (alien->x < -300))
+ alien->active = false;
+ }
+ else
+ {
+ alien->shield--;
+ if ((alien->x > 0) && (alien->x < screen->w) &&
+ (alien->y > 0) && (alien->y < screen->h))
+ {
+ blit(alien->image[alien->face], (int)alien->x, (int)alien->y);
+ addExplosion(alien->x + (rand() % alien->image[0]->w), alien->y + (rand() % alien->image[0]->h), E_BIG_EXPLOSION);
+ }
+ if (alien->shield < alien->deathCounter)
+ {
+ alien->active = false;
+ if ((alien->classDef == CD_BOSS) ||
+ (alien->owner == &enemy[WC_BOSS]) ||
+ (alien->flags & FL_FRIEND) ||
+ (alien->classDef == CD_ASTEROID) ||
+ (alien->classDef == CD_KLINE))
+ addDebris((int)alien->x, (int)alien->y,
+ alien->maxShield);
+
+ if (alien->classDef == CD_ASTEROID)
+ {
+ n = 1 + (rand() % 3);
+ for (int i = 0 ; i < n ; i++)
+ alien_addSmallAsteroid(alien);
+ }
+ }
+ }
+
+ // Adjust the movement even whilst exploding
+ if ((dev.moveAliens) && (!(alien->flags & FL_NOMOVE)) &&
+ (!(alien->flags & FL_DISABLED)))
+ alien_move(alien);
+
+ if ((currentGame.area != 18) || (alien->shield < 0))
+ alien->x += engine.ssx;
+
+ alien->x += engine.smx;
+ alien->y += engine.ssy + engine.smy;
+ }
+
+ alien++;
+ }
+
doPlayer();
doCargo();
doDebris();
@@ -285,7 +910,8 @@ int mainGameLoop()
if ((currentGame.area == 24) && (engine.addAliens > -1))
{
if ((rand() % 10) == 0)
- addCollectable(rrand(800, 100), player.y, P_MINE, 25, 180 + rand() % 60);
+ addCollectable(rrand(800, 100), player.y, P_MINE, 25,
+ 180 + rand() % 60);
}
if (engine.addAliens > -1)
diff --git a/src/init.cpp b/src/init.cpp
index eaed072..e9497ea 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -40,8 +40,6 @@ void initVars()
star[i].speed = 1 + (rand() % 3);
}
- // These are good values for sound and music
-
if (engine.useAudio)
{
Mix_Volume(-1, 100);
diff --git a/src/missions.cpp b/src/missions.cpp
index 7d75367..1d3a017 100644
--- a/src/missions.cpp
+++ b/src/missions.cpp
@@ -262,6 +262,19 @@ void setMission(int mission)
engine.timeTaken = 0;
}
+/*
+Call this whenever a mission requires all the remaining aliens to
+automatically die
+*/
+static void mission_killAllEnemies()
+{
+ for (int i = 0 ; i < MAX_ALIENS ; i++)
+ {
+ if ((enemy[i].flags & FL_WEAPCO) && (enemy[i].active) && (enemy[i].shield > 0))
+ enemy[i].shield = 0;
+ }
+}
+
void checkTimer()
{
for (int i = 0 ; i < 3 ; i++)
diff --git a/src/player.cpp b/src/player.cpp
index 75c4c93..2e8a7ba 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -64,6 +64,13 @@ void initPlayer()
player.ammo[1] = 0;
}
+void player_setTarget(int index)
+{
+ engine.targetIndex = index;
+ engine.targetShield = 85;
+ engine.targetShield /= enemy[index].shield;
+}
+
void exitPlayer()
{
charger_fired = false;
diff --git a/src/player.h b/src/player.h
index 1d3662b..8920867 100644
--- a/src/player.h
+++ b/src/player.h
@@ -23,6 +23,7 @@ along with this program. If not, see .
extern object player;
extern void initPlayer();
+void player_setTarget(int index);
extern void exitPlayer();
extern void doPlayer();
extern void flushInput();
diff --git a/src/resources.cpp b/src/resources.cpp
index 4475b78..e2bda6e 100644
--- a/src/resources.cpp
+++ b/src/resources.cpp
@@ -130,7 +130,16 @@ void loadGameGraphics()
loadBackground(systemBackground[currentGame.system]);
- setAlienShapes();
+ for (int i = 0 ; i < MAX_DEFALIENS ; i++)
+ {
+ if (shipShape[defEnemy[i].imageIndex[0]] != NULL)
+ {
+ defEnemy[i].image[0] = shipShape[defEnemy[i].imageIndex[0]];
+ defEnemy[i].image[1] = shipShape[defEnemy[i].imageIndex[1]];
+ defEnemy[i].engineX = defEnemy[i].image[0]->w;
+ defEnemy[i].engineY = (defEnemy[i].image[0]->h / 2);
+ }
+ }
setWeaponShapes();
}