static void syreen_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { EVALUATE_DESC *lpEvalDesc; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX]; if (lpEvalDesc->ObjectPtr != NULL) { STARSHIP *StarShipPtr; STARSHIP *EnemyStarShipPtr; GetElementStarShip (ShipPtr, &StarShipPtr); GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr); if (!(EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags & CREW_IMMUNE) && StarShipPtr->special_counter == 0 && lpEvalDesc->ObjectPtr->crew_level > 1 && lpEvalDesc->which_turn <= 14) StarShipPtr->ship_input_state |= SPECIAL; else StarShipPtr->ship_input_state &= ~SPECIAL; } }
static void arilou_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { STARSHIP *StarShipPtr; GetElementStarShip (ShipPtr, &StarShipPtr); StarShipPtr->ship_input_state |= THRUST; ObjectsOfConcern[ENEMY_SHIP_INDEX].MoveState = ENTICE; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); if (StarShipPtr->special_counter == 0) { EVALUATE_DESC *lpEvalDesc; StarShipPtr->ship_input_state &= ~SPECIAL; lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 6) { BOOLEAN IsTrackingWeapon; STARSHIP *EnemyStarShipPtr; GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr); if (((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags & SEEKING_WEAPON) && lpEvalDesc->ObjectPtr->next.image.farray == EnemyStarShipPtr->RaceDescPtr->ship_data.weapon) || ((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags & SEEKING_SPECIAL) && lpEvalDesc->ObjectPtr->next.image.farray == EnemyStarShipPtr->RaceDescPtr->ship_data.special)) IsTrackingWeapon = TRUE; else IsTrackingWeapon = FALSE; // JMS: Added the GASSY_SUBSTANCE clauses to prevent 'long teleport' if Baul gas is sticking to the Arilou ship. if (((lpEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP) /* means IMMEDIATE WEAPON */ || (IsTrackingWeapon && (lpEvalDesc->which_turn == 1 || (lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT))) /* FIGHTERS!!! */ || (PlotIntercept (lpEvalDesc->ObjectPtr, ShipPtr, 3, 0) && (!(lpEvalDesc->ObjectPtr->state_flags & GASSY_SUBSTANCE) // Ignore stuck gas || (lpEvalDesc->ObjectPtr->state_flags & GASSY_SUBSTANCE && EnemyStarShipPtr->ship_input_state & WEAPON && ObjectsOfConcern[ENEMY_SHIP_INDEX].which_turn <= 20) // If sticking to gas, teleport when Baul is near&firing primary || (lpEvalDesc->ObjectPtr->state_flags & GASSY_SUBSTANCE && lpEvalDesc->ObjectPtr->state_flags & IGNORE_VELOCITY))) // non-stuck gas ) && !(TFB_Random () & 3)) { StarShipPtr->ship_input_state &= ~(LEFT | RIGHT | THRUST | WEAPON); StarShipPtr->ship_input_state |= SPECIAL; } } } if (StarShipPtr->RaceDescPtr->ship_info.energy_level <= SPECIAL_ENERGY_COST << 1) StarShipPtr->ship_input_state &= ~WEAPON; }
static void druuge_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { UWORD ship_flags; STARSHIP *StarShipPtr; STARSHIP *EnemyStarShipPtr; EVALUATE_DESC *lpEvalDesc; GetElementStarShip (ShipPtr, &StarShipPtr); ship_flags = 0; lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX]; if (StarShipPtr->cur_status_flags & SHIP_BEYOND_MAX_SPEED) lpEvalDesc->MoveState = ENTICE; else if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= WORLD_TO_TURN (MISSILE_RANGE * 3 / 4)) { GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr); ship_flags = EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags; EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags &= ~(FIRES_FORE | FIRES_RIGHT | FIRES_AFT | FIRES_LEFT); lpEvalDesc->MoveState = PURSUE; if (ShipPtr->thrust_wait == 0) ++ShipPtr->thrust_wait; } ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); if (ship_flags) { EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags = ship_flags; } if (!(StarShipPtr->cur_status_flags & SHIP_BEYOND_MAX_SPEED) && (lpEvalDesc->which_turn <= 12 || ( ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr && ObjectsOfConcern[ENEMY_WEAPON_INDEX].which_turn <= 6 ))) { StarShipPtr->ship_input_state |= WEAPON; if (ShipPtr->thrust_wait < WEAPON_WAIT + 1) ShipPtr->thrust_wait = WEAPON_WAIT + 1; } if ((StarShipPtr->ship_input_state & WEAPON) && StarShipPtr->RaceDescPtr->ship_info.energy_level < WEAPON_ENERGY_COST && ShipPtr->crew_level > 1) StarShipPtr->ship_input_state |= SPECIAL; else StarShipPtr->ship_input_state &= ~SPECIAL; }
static void arilou_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { STARSHIP *StarShipPtr; GetElementStarShip (ShipPtr, &StarShipPtr); StarShipPtr->ship_input_state |= THRUST; ObjectsOfConcern[ENEMY_SHIP_INDEX].MoveState = ENTICE; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); if (StarShipPtr->special_counter == 0) { EVALUATE_DESC *lpEvalDesc; StarShipPtr->ship_input_state &= ~SPECIAL; lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 6) { BOOLEAN IsTrackingWeapon; STARSHIP *EnemyStarShipPtr; GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr); if (((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags & SEEKING_WEAPON) && lpEvalDesc->ObjectPtr->next.image.farray == EnemyStarShipPtr->RaceDescPtr->ship_data.weapon) || ((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags & SEEKING_SPECIAL) && lpEvalDesc->ObjectPtr->next.image.farray == EnemyStarShipPtr->RaceDescPtr->ship_data.special)) IsTrackingWeapon = TRUE; else IsTrackingWeapon = FALSE; if (((lpEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP) /* means IMMEDIATE WEAPON */ || (IsTrackingWeapon && (lpEvalDesc->which_turn == 1 || (lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT))) /* FIGHTERS!!! */ || PlotIntercept (lpEvalDesc->ObjectPtr, ShipPtr, 3, 0)) && !(TFB_Random () & 3)) { StarShipPtr->ship_input_state &= ~(LEFT | RIGHT | THRUST | WEAPON); StarShipPtr->ship_input_state |= SPECIAL; } } } if (StarShipPtr->RaceDescPtr->ship_info.energy_level <= SPECIAL_ENERGY_COST << 1) StarShipPtr->ship_input_state &= ~WEAPON; }
static void pkunk_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (StarShipPtr->RaceDescPtr->characteristics.special_wait) --StarShipPtr->RaceDescPtr->characteristics.special_wait; else if ((StarShipPtr->cur_status_flags & SPECIAL) && StarShipPtr->RaceDescPtr->ship_info.energy_level < StarShipPtr->RaceDescPtr->ship_info.max_energy) { COUNT CurSound; do { CurSound = 2 + ((COUNT)TFB_Random () % (GetSoundCount (StarShipPtr->RaceDescPtr->ship_data.ship_sounds) - 2)); } while (CurSound == LastSound); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, CurSound ), ElementPtr); LastSound = CurSound; DeltaEnergy (ElementPtr, SPECIAL_ENERGY_COST); StarShipPtr->RaceDescPtr->characteristics.special_wait = SPECIAL_WAIT; } }
static void intercept_pkunk_death (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; ElementPtr->state_flags &= ~DISAPPEARING; ElementPtr->life_span = 1; GetElementStarShip (ElementPtr, &StarShipPtr); if (StarShipPtr->RaceDescPtr->ship_info.crew_level == 0) { ELEMENT *ShipPtr; LockElement (StarShipPtr->hShip, &ShipPtr); if (GRAVITY_MASS (ShipPtr->mass_points + 1)) { ElementPtr->state_flags |= DISAPPEARING; ElementPtr->life_span = 0; } else { ShipPtr->mass_points = MAX_SHIP_MASS + 1; StarShipPtr->RaceDescPtr->preprocess_func = ShipPtr->preprocess_func; StarShipPtr->RaceDescPtr->postprocess_func = ShipPtr->postprocess_func; StarShipPtr->RaceDescPtr->init_weapon_func = (COUNT (*) (ELEMENT *ElementPtr, HELEMENT Weapon[])) ShipPtr->death_func; ElementPtr->death_func = new_pkunk; } UnlockElement (StarShipPtr->hShip); } }
static void pkunk_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { STARSHIP *StarShipPtr; HELEMENT hPhoenix; GetElementStarShip (ShipPtr, &StarShipPtr); hPhoenix = (HELEMENT) StarShipPtr->RaceDescPtr->data; if (hPhoenix && (StarShipPtr->control & STANDARD_RATING)) { RemoveElement (hPhoenix); FreeElement (hPhoenix); StarShipPtr->RaceDescPtr->data = 0; } if (StarShipPtr->RaceDescPtr->ship_info.energy_level < StarShipPtr->RaceDescPtr->ship_info.max_energy && (StarShipPtr->special_counter == 0 || (BYTE)TFB_Random () < 20)) StarShipPtr->ship_input_state |= SPECIAL; else StarShipPtr->ship_input_state &= ~SPECIAL; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); }
static COUNT initialize_test_pump_up (ELEMENT *ShipPtr, HELEMENT PumpUpArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; //ELEMENT *PumpUpPtr; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = MELNORME_OFFSET; MissileBlock.speed = RES_SCALE(PUMPUP_SPEED); MissileBlock.hit_points = PUMPUP_DAMAGE; MissileBlock.damage = PUMPUP_DAMAGE; MissileBlock.life = PUMPUP_LIFE; MissileBlock.preprocess_func = 0; MissileBlock.blast_offs = 0; PumpUpArray[0] = initialize_missile (&MissileBlock); return (1); }
static COUNT initialize_confusion (ELEMENT *ShipPtr, HELEMENT ConfusionArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK ConfusionBlock; GetElementStarShip (ShipPtr, &StarShipPtr); ConfusionBlock.cx = ShipPtr->next.location.x; ConfusionBlock.cy = ShipPtr->next.location.y; ConfusionBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; ConfusionBlock.index = 0; ConfusionBlock.face = StarShipPtr->ShipFacing; ConfusionBlock.sender = ShipPtr->playerNr; ConfusionBlock.flags = IGNORE_SIMILAR; ConfusionBlock.pixoffs = MELNORME_OFFSET; ConfusionBlock.speed = CMISSILE_SPEED; ConfusionBlock.hit_points = CMISSILE_HITS; ConfusionBlock.damage = CMISSILE_DAMAGE; ConfusionBlock.life = CMISSILE_LIFE; ConfusionBlock.preprocess_func = confuse_preprocess; ConfusionBlock.blast_offs = CMISSILE_OFFSET; ConfusionArray[0] = initialize_missile (&ConfusionBlock); if (ConfusionArray[0]) { ELEMENT *CMissilePtr; LockElement (ConfusionArray[0], &CMissilePtr); CMissilePtr->collision_func = confusion_collision; SetElementStarShip (CMissilePtr, StarShipPtr); UnlockElement (ConfusionArray[0]); } return (1); }
static void druuge_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (StarShipPtr->cur_status_flags & SPECIAL) { if (StarShipPtr->special_counter || ElementPtr->crew_level == 1 || StarShipPtr->RaceDescPtr->ship_info.energy_level == StarShipPtr->RaceDescPtr->ship_info.max_energy) StarShipPtr->cur_status_flags &= ~SPECIAL; else { ProcessSound (SetAbsSoundIndex ( /* BURN UP CREW */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); DeltaCrew (ElementPtr, -1); DeltaEnergy (ElementPtr, SPECIAL_ENERGY_COST); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; } } }
static void human_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { STARSHIP *StarShipPtr; GetElementStarShip (ShipPtr, &StarShipPtr); if (StarShipPtr->special_counter == 0 && ((ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr != NULL && ObjectsOfConcern[ENEMY_WEAPON_INDEX].which_turn <= 2) || (ObjectsOfConcern[ENEMY_SHIP_INDEX].ObjectPtr != NULL && ObjectsOfConcern[ENEMY_SHIP_INDEX].which_turn <= 4))) StarShipPtr->ship_input_state |= SPECIAL; else StarShipPtr->ship_input_state &= ~SPECIAL; ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr = NULL; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); if (StarShipPtr->weapon_counter == 0) { if (ObjectsOfConcern[ENEMY_SHIP_INDEX].ObjectPtr && (!(StarShipPtr->ship_input_state & (LEFT | RIGHT /* | THRUST */)) || ObjectsOfConcern[ENEMY_SHIP_INDEX].which_turn <= 12)) StarShipPtr->ship_input_state |= WEAPON; } }
static void melnorme_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if ((StarShipPtr->cur_status_flags & SPECIAL) && StarShipPtr->special_counter == 0 && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { HELEMENT Confusion; initialize_confusion (ElementPtr, &Confusion); if (Confusion) { ELEMENT *CMissilePtr; LockElement (Confusion, &CMissilePtr); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), CMissilePtr); UnlockElement (Confusion); PutElement (Confusion); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; } } }
// playerNr should be 0 or 1 STARSHIP* findPlayerShip (SIZE playerNr) { HELEMENT hElement, hNextElement; for (hElement = GetHeadElement (); hElement; hElement = hNextElement) { ELEMENT *ElementPtr; LockElement (hElement, &ElementPtr); hNextElement = GetSuccElement (ElementPtr); if ((ElementPtr->state_flags & PLAYER_SHIP) && ElementPtr->playerNr == playerNr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); UnlockElement (hElement); return StarShipPtr; } UnlockElement (hElement); } return NULL; }
static void baul_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); }
static void spin_preprocess (ELEMENT *ElementPtr) { ELEMENT *ShipPtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); LockElement (StarShipPtr->hShip, &ShipPtr); if (ShipPtr->crew_level && ++StarShipPtr->RaceDescPtr->characteristics.special_wait > MAX_SAWS) { ElementPtr->life_span = 1; ElementPtr->state_flags |= DISAPPEARING; } else { ++ElementPtr->life_span; if (ElementPtr->turn_wait) --ElementPtr->turn_wait; else { #define LAST_SPIN_INDEX 1 if (GetFrameIndex (ElementPtr->current.image.frame) < LAST_SPIN_INDEX) ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); else ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->current.image.frame, 0); ElementPtr->state_flags |= CHANGING; ElementPtr->turn_wait = SAW_RATE; } } UnlockElement (StarShipPtr->hShip); }
static void shofixti_intelligence (PELEMENT ShipPtr, PEVALUATE_DESC ObjectsOfConcern, COUNT ConcernCounter) { STARSHIPPTR StarShipPtr; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); GetElementStarShip (ShipPtr, &StarShipPtr); if (StarShipPtr->special_counter == 0) { if (StarShipPtr->ship_input_state & SPECIAL) StarShipPtr->ship_input_state &= ~SPECIAL; else { PEVALUATE_DESC lpWeaponEvalDesc, lpShipEvalDesc; lpWeaponEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; lpShipEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX]; if (StarShipPtr->RaceDescPtr->ship_data.special[0] && (GetFrameCount (StarShipPtr->RaceDescPtr->ship_data.captain_control.special) - GetFrameIndex (StarShipPtr->RaceDescPtr->ship_data.captain_control.special) > 5 || (lpShipEvalDesc->ObjectPtr != NULL_PTR && lpShipEvalDesc->which_turn <= 4) || (lpWeaponEvalDesc->ObjectPtr != NULL_PTR /* means IMMEDIATE WEAPON */ && (((lpWeaponEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP) && ShipPtr->crew_level == 1) || (PlotIntercept (lpWeaponEvalDesc->ObjectPtr, ShipPtr, 2, 0) && lpWeaponEvalDesc->ObjectPtr->mass_points >= ShipPtr->crew_level && (TFB_Random () & 1)))))) StarShipPtr->ship_input_state |= SPECIAL; } } }
static COUNT initialize_dagger (ELEMENT *ShipPtr, HELEMENT DaggerArray[]) { #define SYREEN_OFFSET (30 << RESOLUTION_FACTOR) // JMS_GFX #define MISSILE_HITS 1 #define MISSILE_DAMAGE 2 #define MISSILE_OFFSET (3 << RESOLUTION_FACTOR) // JMS_GFX STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = SYREEN_OFFSET; MissileBlock.speed = MISSILE_SPEED << RESOLUTION_FACTOR; // JMS_GFX MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; DaggerArray[0] = initialize_missile (&MissileBlock); return (1); }
static COUNT initialize_autoaim_laser (ELEMENT *ShipPtr, HELEMENT LaserArray[]) { COUNT orig_facing; SIZE delta_facing; STARSHIP *StarShipPtr; LASER_BLOCK LaserBlock; GetElementStarShip (ShipPtr, &StarShipPtr); LaserBlock.face = orig_facing = StarShipPtr->ShipFacing; if ((delta_facing = TrackShip (ShipPtr, &LaserBlock.face)) > 0) LaserBlock.face = NORMALIZE_FACING (orig_facing + delta_facing); ShipPtr->hTarget = 0; LaserBlock.cx = ShipPtr->next.location.x; LaserBlock.cy = ShipPtr->next.location.y; LaserBlock.ex = COSINE (FACING_TO_ANGLE (LaserBlock.face), LASER_RANGE); LaserBlock.ey = SINE (FACING_TO_ANGLE (LaserBlock.face), LASER_RANGE); LaserBlock.sender = ShipPtr->playerNr; LaserBlock.flags = IGNORE_SIMILAR; LaserBlock.pixoffs = ARILOU_OFFSET; LaserBlock.color = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E); LaserArray[0] = initialize_laser (&LaserBlock); return (1); }
static void druuge_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); /* if just fired cannon */ if ((StarShipPtr->cur_status_flags & WEAPON) && StarShipPtr->weapon_counter == StarShipPtr->RaceDescPtr->characteristics.weapon_wait) { COUNT angle; SIZE cur_delta_x, cur_delta_y; StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED; angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE; DeltaVelocityComponents (&ElementPtr->velocity, COSINE (angle, RECOIL_VELOCITY), SINE (angle, RECOIL_VELOCITY)); GetCurrentVelocityComponents (&ElementPtr->velocity, &cur_delta_x, &cur_delta_y); if ((long)cur_delta_x * (long)cur_delta_x + (long)cur_delta_y * (long)cur_delta_y > (long)MAX_RECOIL_VELOCITY * (long)MAX_RECOIL_VELOCITY) { angle = ARCTAN (cur_delta_x, cur_delta_y); SetVelocityComponents (&ElementPtr->velocity, COSINE (angle, MAX_RECOIL_VELOCITY), SINE (angle, MAX_RECOIL_VELOCITY)); } } }
static COUNT initialize_cannon (ELEMENT *ShipPtr, HELEMENT CannonArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = MissileBlock.face; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = DRUUGE_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; CannonArray[0] = initialize_missile (&MissileBlock); if (CannonArray[0]) { ELEMENT *CannonPtr; LockElement (CannonArray[0], &CannonPtr); CannonPtr->collision_func = cannon_collision; UnlockElement (CannonArray[0]); } return (1); }
// This is used by AI for testing would it hit the enemy ship with gas. static COUNT initialize_test_gas (ELEMENT *ElementPtr, HELEMENT GasArray[]) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ElementPtr, &StarShipPtr); MissileBlock.cx = ElementPtr->next.location.x; MissileBlock.cy = ElementPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = StarShipPtr->ShipFacing; MissileBlock.index = LAST_DISSOLVE_INDEX; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = GASSY_SUBSTANCE | IGNORE_VELOCITY; MissileBlock.pixoffs = GAS_OFFSET; MissileBlock.speed = GAS_INIT_SPEED; MissileBlock.hit_points = GAS_HITS; MissileBlock.damage = GAS_DAMAGE; MissileBlock.life = 20; // Not GAS_LIFE because this test gas doesn't slow down at all -> life has to be short. MissileBlock.preprocess_func = gas_preprocess; MissileBlock.blast_offs = 0; GasArray[0] = initialize_missile (&MissileBlock); return (1); }
static COUNT initialize_standard_missile (ELEMENT *ShipPtr, HELEMENT MissileArray[]) { #define SPATHI_FORWARD_OFFSET 16 #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 1 STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = SPATHI_FORWARD_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; MissileArray[0] = initialize_missile (&MissileBlock); return (1); }
static COUNT initialize_horn (ELEMENT *ShipPtr, HELEMENT HornArray[]) { #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 2 #define SUPOX_OFFSET 23 STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing; MissileBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY)) | IGNORE_SIMILAR; MissileBlock.pixoffs = SUPOX_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; HornArray[0] = initialize_missile (&MissileBlock); return (1); }
void crew_preprocess (ELEMENT *ElementPtr) { HELEMENT hTarget; // Switch from dark to light or vice versa: Color oldColor = GetPrimColor (&DisplayArray[ElementPtr->PrimIndex]); Color newColor = sameColor (oldColor, CREW_COLOR_LOW_INTENSITY) ? CREW_COLOR_HIGH_INTENSITY : CREW_COLOR_LOW_INTENSITY; SetPrimColor (&DisplayArray[ElementPtr->PrimIndex], newColor); ElementPtr->state_flags |= CHANGING; hTarget = ElementPtr->hTarget; if (hTarget == 0) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (StarShipPtr && StarShipPtr->RaceDescPtr->ship_info.crew_level) ElementPtr->hTarget = StarShipPtr->hShip; else { COUNT facing; facing = 0; TrackShip (ElementPtr, &facing); } } if (hTarget) { #define CREW_DELTA SCALED_ONE SIZE delta; ELEMENT *ShipPtr; LockElement (hTarget, &ShipPtr); delta = ShipPtr->current.location.x - ElementPtr->current.location.x; delta = WRAP_DELTA_X (delta); if (delta > 0) ElementPtr->next.location.x += CREW_DELTA; else if (delta < 0) ElementPtr->next.location.x -= CREW_DELTA; delta = ShipPtr->current.location.y - ElementPtr->current.location.y; delta = WRAP_DELTA_Y (delta); if (delta > 0) ElementPtr->next.location.y += CREW_DELTA; else if (delta < 0) ElementPtr->next.location.y -= CREW_DELTA; UnlockElement (hTarget); } }
static COUNT initialize_turret_missile (PELEMENT ShipPtr, HELEMENT MissileArray[]) { #define MISSILE_HITS 2 #define MISSILE_DAMAGE 3 #define MISSILE_OFFSET 1 ELEMENTPTR TurretPtr; STARSHIPPTR StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; LockElement (GetSuccElement (ShipPtr), &TurretPtr); if (TurretPtr->turn_wait == 0 && (StarShipPtr->cur_status_flags & SPECIAL) && (StarShipPtr->cur_status_flags & (LEFT | RIGHT))) { if (StarShipPtr->cur_status_flags & RIGHT) ++TurretPtr->thrust_wait; else --TurretPtr->thrust_wait; TurretPtr->turn_wait = TURRET_WAIT + 1; } MissileBlock.face = MissileBlock.index = NORMALIZE_FACING (StarShipPtr->ShipFacing + TurretPtr->thrust_wait); UnlockElement (GetSuccElement (ShipPtr)); MissileBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY)) | IGNORE_SIMILAR; MissileBlock.pixoffs = TURRET_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL_PTR; MissileBlock.blast_offs = MISSILE_OFFSET; MissileArray[0] = initialize_missile (&MissileBlock); if (MissileArray[0]) { ELEMENTPTR HowitzerPtr; LockElement (MissileArray[0], &HowitzerPtr); HowitzerPtr->collision_func = howitzer_collision; UnlockElement (MissileArray[0]); } return (1); }
static void buzzsaw_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (!(StarShipPtr->cur_status_flags & WEAPON)) { ElementPtr->life_span >>= 1; ElementPtr->preprocess_func = decelerate_preprocess; }
static COUNT initialize_bug_missile (ELEMENT *ShipPtr, HELEMENT MissileArray[]) { #define PKUNK_OFFSET 15 #define MISSILE_HITS 1 #define MISSILE_DAMAGE 1 #define MISSILE_OFFSET 1 COUNT i; STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); MissileBlock.cx = ShipPtr->next.location.x; MissileBlock.cy = ShipPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon; MissileBlock.index = 0; MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = PKUNK_OFFSET; MissileBlock.speed = MISSILE_SPEED; MissileBlock.hit_points = MISSILE_HITS; MissileBlock.damage = MISSILE_DAMAGE; MissileBlock.life = MISSILE_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = MISSILE_OFFSET; for (i = 0; i < 3; ++i) { MissileBlock.face = StarShipPtr->ShipFacing + (ANGLE_TO_FACING (QUADRANT) * i); if (i == 2) MissileBlock.face += ANGLE_TO_FACING (QUADRANT); MissileBlock.face = NORMALIZE_FACING (MissileBlock.face); if ((MissileArray[i] = initialize_missile (&MissileBlock))) { SIZE dx, dy; ELEMENT *MissilePtr; LockElement (MissileArray[i], &MissilePtr); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); DeltaVelocityComponents (&MissilePtr->velocity, dx, dy); MissilePtr->current.location.x -= VELOCITY_TO_WORLD (dx); MissilePtr->current.location.y -= VELOCITY_TO_WORLD (dy); MissilePtr->preprocess_func = animate; UnlockElement (MissileArray[i]); } } return (3); }
static void human_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if ((StarShipPtr->cur_status_flags & SPECIAL) && StarShipPtr->special_counter == 0) { spawn_point_defense (ElementPtr); } }
static void doggy_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); ++StarShipPtr->special_counter; if (ElementPtr->thrust_wait > 0) /* could be non-zero after a collision */ --ElementPtr->thrust_wait; else { COUNT facing, orig_facing; SIZE delta_facing; facing = orig_facing = NORMALIZE_FACING (ANGLE_TO_FACING ( GetVelocityTravelAngle (&ElementPtr->velocity) )); if ((delta_facing = TrackShip (ElementPtr, &facing)) < 0) facing = NORMALIZE_FACING (TFB_Random ()); else { ELEMENT *ShipPtr; LockElement (ElementPtr->hTarget, &ShipPtr); facing = NORMALIZE_FACING (ANGLE_TO_FACING ( ARCTAN (ShipPtr->current.location.x - ElementPtr->current.location.x, ShipPtr->current.location.y - ElementPtr->current.location.y) )); delta_facing = NORMALIZE_FACING (facing - GetFrameIndex (ShipPtr->current.image.frame)); UnlockElement (ElementPtr->hTarget); if (delta_facing > ANGLE_TO_FACING (HALF_CIRCLE - OCTANT) && delta_facing < ANGLE_TO_FACING (HALF_CIRCLE + OCTANT)) { if (delta_facing >= ANGLE_TO_FACING (HALF_CIRCLE)) facing -= ANGLE_TO_FACING (QUADRANT); else facing += ANGLE_TO_FACING (QUADRANT); } facing = NORMALIZE_FACING (facing); } if (facing != orig_facing) SetVelocityVector (&ElementPtr->velocity, DOGGY_SPEED, facing); } }
static void spathi_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { STARSHIP *StarShipPtr; EVALUATE_DESC *lpEvalDesc; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); GetElementStarShip (ShipPtr, &StarShipPtr); StarShipPtr->ship_input_state &= ~SPECIAL; lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX]; if (StarShipPtr->special_counter == 0 && lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 24) { COUNT travel_facing, direction_facing; SIZE delta_x, delta_y; travel_facing = NORMALIZE_FACING ( ANGLE_TO_FACING (GetVelocityTravelAngle (&ShipPtr->velocity) + HALF_CIRCLE) ); delta_x = lpEvalDesc->ObjectPtr->current.location.x - ShipPtr->current.location.x; delta_y = lpEvalDesc->ObjectPtr->current.location.y - ShipPtr->current.location.y; direction_facing = NORMALIZE_FACING ( ANGLE_TO_FACING (ARCTAN (delta_x, delta_y)) ); if (NORMALIZE_FACING (direction_facing - (StarShipPtr->ShipFacing + ANGLE_TO_FACING (HALF_CIRCLE)) + ANGLE_TO_FACING (QUADRANT)) <= ANGLE_TO_FACING (HALF_CIRCLE) && (lpEvalDesc->which_turn <= 8 || NORMALIZE_FACING (direction_facing + ANGLE_TO_FACING (HALF_CIRCLE) - ANGLE_TO_FACING (GetVelocityTravelAngle ( &lpEvalDesc->ObjectPtr->velocity )) + ANGLE_TO_FACING (QUADRANT)) <= ANGLE_TO_FACING (HALF_CIRCLE)) && (!(StarShipPtr->cur_status_flags & (SHIP_BEYOND_MAX_SPEED | SHIP_IN_GRAVITY_WELL)) || NORMALIZE_FACING (direction_facing - travel_facing + ANGLE_TO_FACING (QUADRANT)) <= ANGLE_TO_FACING (HALF_CIRCLE))) StarShipPtr->ship_input_state |= SPECIAL; } }