static void ilwrath_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter) { EVALUATE_DESC *lpEvalDesc; STARSHIP *StarShipPtr; lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX]; lpEvalDesc->MoveState = PURSUE; if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 10) /* don't want to dodge when you could be flaming */ ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr = 0; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); GetElementStarShip (ShipPtr, &StarShipPtr); if (lpEvalDesc->ObjectPtr && (lpEvalDesc->which_turn <= 6 || (lpEvalDesc->which_turn <= 10 && ObjectsOfConcern[ENEMY_WEAPON_INDEX].which_turn <= 10))) { StarShipPtr->ship_input_state &= ~SPECIAL; if (OBJECT_CLOAKED (ShipPtr)) { StarShipPtr->ship_input_state &= ~LEFT | RIGHT; StarShipPtr->ship_input_state |= THRUST; } StarShipPtr->ship_input_state |= WEAPON; } else if (StarShipPtr->special_counter == 0 && (LOBYTE (GLOBAL (CurrentActivity)) != IN_ENCOUNTER || !GET_GAME_STATE (PROBE_ILWRATH_ENCOUNTER))) { StarShipPtr->ship_input_state &= ~SPECIAL; if (!OBJECT_CLOAKED (ShipPtr) && !(StarShipPtr->ship_input_state & WEAPON)) StarShipPtr->ship_input_state |= SPECIAL; } }
static void spawn_point_defense (PELEMENT ElementPtr) { STARSHIPPTR StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (ElementPtr->state_flags & PLAYER_SHIP) { HELEMENT hDefense; hDefense = AllocElement (); if (hDefense) { ELEMENTPTR DefensePtr; LockElement (hDefense, &DefensePtr); DefensePtr->state_flags = APPEARING | NONSOLID | FINITE_LIFE | (ElementPtr->state_flags & (GOOD_GUY | BAD_GUY)); { DefensePtr->death_func = spawn_point_defense; } GetElementStarShip (ElementPtr, &StarShipPtr); SetElementStarShip (DefensePtr, StarShipPtr); UnlockElement (hDefense); PutElement (hDefense); } } else { BOOLEAN PaidFor; HELEMENT hObject, hNextObject; ELEMENTPTR ShipPtr; PaidFor = FALSE; LockElement (StarShipPtr->hShip, &ShipPtr); for (hObject = GetTailElement (); hObject; hObject = hNextObject) { ELEMENTPTR ObjectPtr; LockElement (hObject, &ObjectPtr); hNextObject = GetPredElement (ObjectPtr); if (ObjectPtr != ShipPtr && CollidingElement (ObjectPtr) && !OBJECT_CLOAKED (ObjectPtr)) { #define LASER_RANGE (UWORD)100 SIZE delta_x, delta_y; delta_x = ObjectPtr->next.location.x - ShipPtr->next.location.x; delta_y = ObjectPtr->next.location.y - ShipPtr->next.location.y; if (delta_x < 0) delta_x = -delta_x; if (delta_y < 0) delta_y = -delta_y; delta_x = WORLD_TO_DISPLAY (delta_x); delta_y = WORLD_TO_DISPLAY (delta_y); if ((UWORD)delta_x <= LASER_RANGE && (UWORD)delta_y <= LASER_RANGE && (UWORD)delta_x * (UWORD)delta_x + (UWORD)delta_y * (UWORD)delta_y <= LASER_RANGE * LASER_RANGE) { HELEMENT hPointDefense; LASER_BLOCK LaserBlock; if (!PaidFor) { if (!DeltaEnergy (ShipPtr, -SPECIAL_ENERGY_COST)) break; ProcessSound (SetAbsSoundIndex ( /* POINT_DEFENSE_LASER */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1)); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; PaidFor = TRUE; } LaserBlock.cx = ShipPtr->next.location.x; LaserBlock.cy = ShipPtr->next.location.y; LaserBlock.face = 0; LaserBlock.ex = ObjectPtr->next.location.x - ShipPtr->next.location.x; LaserBlock.ey = ObjectPtr->next.location.y - ShipPtr->next.location.y; LaserBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY)) | IGNORE_SIMILAR; LaserBlock.pixoffs = 0; LaserBlock.color = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F); hPointDefense = initialize_laser (&LaserBlock); if (hPointDefense) { ELEMENTPTR PDPtr; LockElement (hPointDefense, &PDPtr); SetElementStarShip (PDPtr, StarShipPtr); PDPtr->hTarget = 0; UnlockElement (hPointDefense); PutElement (hPointDefense); } } } UnlockElement (hObject); } UnlockElement (StarShipPtr->hShip); } }
static void butt_missile_preprocess (ELEMENT *ElementPtr) { if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { COUNT facing; // COUNT num_frames; SIZE delta_x, delta_y, delta_facing; ELEMENT *EnemyPtr; facing = GetFrameIndex (ElementPtr->next.image.frame); if (ElementPtr->hTarget) { LockElement (ElementPtr->hTarget, &EnemyPtr); delta_x = EnemyPtr->current.location.x - ElementPtr->current.location.x; delta_x = WRAP_DELTA_X (delta_x); delta_y = EnemyPtr->current.location.y - ElementPtr->current.location.y; delta_y = WRAP_DELTA_Y (delta_y); /* num_frames = (square_root ((long)delta_x * delta_x + (long)delta_y * delta_y)) / DISCRIMINATOR_SPEED; if (num_frames == 0) num_frames = 1; GetNextVelocityComponents (&EnemyPtr->velocity, &delta_x, &delta_y, num_frames); // Lead the target by its apparent trajectory. delta_x = (EnemyPtr->current.location.x + (delta_x / 2)) - ElementPtr->current.location.x; delta_y = (EnemyPtr->current.location.y + (delta_y / 2)) - ElementPtr->current.location.y; */ delta_facing = NORMALIZE_FACING ( ANGLE_TO_FACING (ARCTAN (delta_x, delta_y)) - facing); if (delta_facing > 0 && !OBJECT_CLOAKED(EnemyPtr)) { if (delta_facing == ANGLE_TO_FACING (HALF_CIRCLE)) facing += (((BYTE)TFB_Random () & 1) << 1) - 1; else if (delta_facing < ANGLE_TO_FACING (HALF_CIRCLE)) ++facing; else --facing; } ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->next.image.frame, facing); ElementPtr->state_flags |= CHANGING; SetVelocityVector (&ElementPtr->velocity, DISCRIMINATOR_SPEED, facing); UnlockElement (ElementPtr->hTarget); } else if (TrackShip (ElementPtr, &facing) > 0) { ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->next.image.frame, facing); ElementPtr->state_flags |= CHANGING; SetVelocityVector (&ElementPtr->velocity, DISCRIMINATOR_SPEED, facing); } ElementPtr->turn_wait = TRACK_WAIT; } }