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(); }