📄 aliens.cpp
字号:
theEnemy->thinktime = (rand() % 25) * 10; // Face direction of movement unless you always face your target(!) if (!(theEnemy->flags & FL_ALWAYSFACE)) { theEnemy->face = 0; if (theEnemy->dx > 0) theEnemy->face = 1; } Math::limitFloat(&theEnemy->dx, 0 - theEnemy->speed, theEnemy->speed); Math::limitFloat(&theEnemy->dy, 0 - theEnemy->speed, theEnemy->speed); } if (theEnemy->flags & FL_ALWAYSFACE) { theEnemy->face = 0; if (theEnemy->x > theEnemy->target->x) theEnemy->face = 1; } if ((currentGame.area == 18) && (theEnemy->classDef == CD_BOSS)) theEnemy->face = 0; if ((theEnemy->flags & FL_DEPLOYDRONES) && ((rand() % 300) == 0)) addDrone(theEnemy); if (theEnemy->flags & FL_LEAVESECTOR) { Math::limitFloat(&(theEnemy->dx -= 0.5), 0, -15); theEnemy->dy = 0; theEnemy->thinktime = 999; theEnemy->face = 0; if (theEnemy->x >= 5000) { theEnemy->flags -= FL_LEAVESECTOR; theEnemy->flags += FL_ESCAPED; theEnemy->active = 0; if (theEnemy->classDef == CD_CLOAKFIGHTER) { currentGame.experimentalShield = theEnemy->shield; setInfoLine("Experimental Fighter has fled", FONT_CYAN); } theEnemy->shield = 0; updateMissionRequirements(M_ESCAPE_TARGET, theEnemy->classDef, 1); if (theEnemy->classDef != CD_CLOAKFIGHTER) updateMissionRequirements(M_DESTROY_TARGET_TYPE, theEnemy->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 ((theEnemy->flags & FL_CANCLOAK) && ((rand() % 500) == 0)) { if (theEnemy->flags & FL_ISCLOAKED) theEnemy->flags -= FL_ISCLOAKED; else theEnemy->flags += FL_ISCLOAKED; playSound(SFX_CLOAK); } // ------------ Barriers ------------------ if (theEnemy->classDef == CD_BARRIER) { theEnemy->dx = -10 + (sin(barrierLoop + theEnemy->speed) * 60); theEnemy->dy = 20 + (cos(barrierLoop + theEnemy->speed) * 40); } // ---------------------------------------- // ------------ Mobile Shields ------------ if (theEnemy->classDef == CD_MOBILESHIELD) { Math::limitInt(&(++enemy[WC_BOSS].shield), 0, enemy[WC_BOSS].maxShield); } // ---------------------------------------- Math::limitChar(&--theEnemy->reload[0], 0, 999); Math::limitChar(&--theEnemy->reload[1], 0, 999); if ((!(theEnemy->flags & FL_DISABLED)) && (!(theEnemy->flags & FL_NOFIRE))) { if ((theEnemy->target->shield > 0)) canFire = traceTarget(theEnemy); if (((theEnemy->thinktime % 2) == 0) && (theEnemy->flags & FL_FRIEND)) canFire = traceView(theEnemy); } else { canFire = 0; } if ((canFire == 1) && (dev.fireAliens)) { if ((theEnemy->reload[0] == 0) && ((rand() % 1000 < theEnemy->chance[0]) || (theEnemy->flags & FL_CONTINUOUS_FIRE))) { fireBullet(theEnemy, 0); } if ((theEnemy->reload[1] == 0) && ((rand() % 1000 < theEnemy->chance[1]) || (theEnemy->flags & FL_CONTINUOUS_FIRE))) { if ((theEnemy->weaponType[1] != W_ENERGYRAY) && (theEnemy->weaponType[1] != W_LASER)) { if (theEnemy->weaponType[1] == W_CHARGER) theEnemy->ammo[1] = 50 + rand() % 150; fireBullet(theEnemy, 1); } else if (theEnemy->weaponType[1] == W_LASER) { theEnemy->flags += FL_FIRELASER; } else if ((theEnemy->weaponType[1] == W_ENERGYRAY) && (theEnemy->ammo[0] == 250)) { theEnemy->flags += FL_FIRERAY; playSound(SFX_ENERGYRAY); } } } // --------------- Ray specific stuff ------------------ if (theEnemy->flags & FL_FIRERAY) { fireRay(theEnemy); } else { Math::limitChar(&++theEnemy->ammo[0], 0, 250); } // ------------------------------------------------------- // --------------- Laser specific stuff ------------------ if (theEnemy->flags & FL_FIRELASER) { fireBullet(theEnemy, 1); if ((rand() % 25) == 0) theEnemy->flags -= FL_FIRELASER; } // ------------------------------------------------------- // ---------------- Mine specific stuff ------------------ if (theEnemy->flags & FL_DROPMINES) if ((rand() % 150) == 0) addCollectable(theEnemy->x, theEnemy->y, P_MINE, 25, 600 + rand() % 2400); // Kline drops mines a lot more often if ((theEnemy->flags & FL_DROPMINES) && (theEnemy == &enemy[WC_KLINE])) if ((rand() % 10) == 0) addCollectable(theEnemy->x, theEnemy->y, P_MINE, 25, 600 + rand() % 2400); // ------------------------------------------------------- shapeToUse = theEnemy->imageIndex[theEnemy->face]; if (theEnemy->hit) shapeToUse += SHIP_HIT_INDEX; Math::limitChar(&--theEnemy->hit, 0, 100); if ((theEnemy->x + theEnemy->image[0]->w > 0) && (theEnemy->x < 800) && (theEnemy->y + theEnemy->image[0]->h > 0) && (theEnemy->y < 600)) { if ((!(theEnemy->flags & FL_DISABLED)) && (theEnemy->classDef != CD_ASTEROID) && (theEnemy->classDef != CD_ASTEROID2)) addEngine(theEnemy); if ((!(theEnemy->flags & FL_ISCLOAKED)) || (theEnemy->hit > 0)) graphics.blit(graphics.shipShape[shapeToUse], (int)theEnemy->x, (int)theEnemy->y); if (theEnemy->flags & FL_DISABLED) { if ((rand() % 10) == 0) addExplosion(theEnemy->x + (rand() % theEnemy->image[0]->w), theEnemy->y + (rand() % theEnemy->image[0]->h), E_ELECTRICAL); } } if ((currentGame.area == 24) && (theEnemy->x < -300)) theEnemy->active = 0; } else { theEnemy->shield--; if ((theEnemy->x > 0) && (theEnemy->x < 800) && (theEnemy->y > 0) && (theEnemy->y < 600)) { graphics.blit(theEnemy->image[theEnemy->face], (int)theEnemy->x, (int)theEnemy->y); addExplosion(theEnemy->x + (rand() % theEnemy->image[0]->w), theEnemy->y + (rand() % theEnemy->image[0]->h), E_BIG_EXPLOSION); } if (theEnemy->shield < theEnemy->deathCounter) { theEnemy->active = 0; if ((theEnemy->classDef == CD_BOSS) || (theEnemy->owner == &enemy[WC_BOSS]) || (theEnemy->flags & FL_FRIEND) || (theEnemy->classDef == CD_ASTEROID) || (theEnemy->classDef == CD_KLINE)) addDebris((int)theEnemy->x, (int)theEnemy->y, theEnemy->maxShield); if (theEnemy->classDef == CD_ASTEROID) { int i = 1 + (rand() % 3); for (int j = 0 ; j < i ; j++) addSmallAsteroid(theEnemy); } } } // Adjust the movement even whilst exploding if ((dev.moveAliens) && (!(theEnemy->flags & FL_NOMOVE)) && (!(theEnemy->flags & FL_DISABLED))) { moveAndSeparate(theEnemy); } if ((currentGame.area != 18) || (theEnemy->shield < 0)) theEnemy->x += engine.ssx; theEnemy->y += engine.ssy; } *theEnemy++; }}void setAlienShapes(){ for (int i = 0 ; i < MAX_DEFALIENS ; i++) { if (graphics.shipShape[defEnemy[i].imageIndex[0]] != NULL) { defEnemy[i].image[0] = graphics.shipShape[defEnemy[i].imageIndex[0]]; defEnemy[i].image[1] = graphics.shipShape[defEnemy[i].imageIndex[1]]; defEnemy[i].engineX = defEnemy[i].image[0]->w; defEnemy[i].engineY = (defEnemy[i].image[0]->h / 2); } }}#if USEPACKvoid loadAliens(){ int dataLocation = locateDataInPak("data/aliens.dat", 1); int def, ai, speed, shield, max, image1, image2, weapon1, weapon2, chance1, chance2, score; int collectChance, collectType, collectVal, flags; FILE *fp; fp = fopen(PACKLOCATION, "rb"); fseek(fp, dataLocation, SEEK_SET); for (int i = 0 ; i < MAX_DEFALIENS ; i++) { fscanf(fp, "%d", &def); fscanf(fp, "%d", &ai); fscanf(fp, "%d", &speed); fscanf(fp, "%d", &shield); fscanf(fp, "%d", &max); fscanf(fp, "%d", &image1); fscanf(fp, "%d", &image2); fscanf(fp, "%d", &weapon1); fscanf(fp, "%d", &weapon2); fscanf(fp, "%d", &chance1); fscanf(fp, "%d", &chance2); fscanf(fp, "%d", &score); fscanf(fp, "%d", &collectChance); fscanf(fp, "%d", &collectType); fscanf(fp, "%d", &collectVal); fscanf(fp, "%d", &flags); defEnemy[i].classDef = def; defEnemy[i].AIType = ai; defEnemy[i].speed = speed; defEnemy[i].shield = shield; defEnemy[i].maxShield = max; defEnemy[i].imageIndex[0] = image1; defEnemy[i].imageIndex[1] = image2; defEnemy[i].weaponType[0] = weapon1; defEnemy[i].weaponType[1] = weapon2; defEnemy[i].chance[0] = chance1; defEnemy[i].chance[1] = chance2; defEnemy[i].score = score; defEnemy[i].collectChance = collectChance; defEnemy[i].collectType = collectType; defEnemy[i].collectValue = collectVal; defEnemy[i].flags = flags; } fclose(fp);}void defineAliens(){loadAliens();}#elsevoid saveAliens(){ FILE *fp; fp = fopen("data/aliens.dat", "wb"); if (fp == NULL) { printf("Unable to write Alien Data File\n"); exit(1); } for (int i = 0 ; i < MAX_DEFALIENS ; i++) { fprintf(fp, "%d ", defEnemy[i].classDef); fprintf(fp, "%d ", defEnemy[i].AIType); fprintf(fp, "%d ", defEnemy[i].speed); fprintf(fp, "%d ", defEnemy[i].shield); fprintf(fp, "%d ", defEnemy[i].maxShield); fprintf(fp, "%d ", defEnemy[i].imageIndex[0]); fprintf(fp, "%d ", defEnemy[i].imageIndex[1]); fprintf(fp, "%d ", defEnemy[i].weaponType[0]); fprintf(fp, "%d ", defEnemy[i].weaponType[1]); fprintf(fp, "%d ", defEnemy[i].chance[0]); fprintf(fp, "%d ", defEnemy[i].chance[1]); fprintf(fp, "%d ", defEnemy[i].score); fprintf(fp, "%d ", defEnemy[i].collectChance); fprintf(fp, "%d ", defEnemy[i].collectType); fprintf(fp, "%d ", defEnemy[i].collectValue); fprintf(fp, "%d\n", defEnemy[i].flags); } // Put an extra line for the PAK file "just in case" fprintf(fp, "\n"); fclose(fp);}/*Will be dumped into a data file at the end of the project*/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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -