static void mmrnmhrm_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); /* take care of transform effect */ if (ElementPtr->next.image.farray != ElementPtr->current.image.farray) { CHARACTERISTIC_STUFF t; ProcessSound (SetAbsSoundIndex ( /* TRANSFORM */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); DeltaEnergy (ElementPtr, -StarShipPtr->RaceDescPtr->characteristics.special_energy_cost); StarShipPtr->weapon_counter = 0; t = otherwing_desc[WHICH_SIDE(ElementPtr->state_flags)]; otherwing_desc[WHICH_SIDE(ElementPtr->state_flags)] = StarShipPtr->RaceDescPtr->characteristics; StarShipPtr->RaceDescPtr->characteristics = t; StarShipPtr->RaceDescPtr->cyborg_control.ManeuverabilityIndex = 0; if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special) { StarShipPtr->RaceDescPtr->cyborg_control.WeaponRange = LONG_RANGE_WEAPON - 1; StarShipPtr->RaceDescPtr->ship_info.ship_flags &= ~IMMEDIATE_WEAPON; StarShipPtr->RaceDescPtr->ship_info.ship_flags |= SEEKING_WEAPON; StarShipPtr->RaceDescPtr->ship_data.ship_sounds = SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED); } else { StarShipPtr->RaceDescPtr->cyborg_control.WeaponRange = CLOSE_RANGE_WEAPON; StarShipPtr->RaceDescPtr->ship_info.ship_flags &= ~SEEKING_WEAPON; StarShipPtr->RaceDescPtr->ship_info.ship_flags |= IMMEDIATE_WEAPON; StarShipPtr->RaceDescPtr->ship_data.ship_sounds = SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 0); if (StarShipPtr->cur_status_flags & (SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED)) StarShipPtr->cur_status_flags |= SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED; } } }
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; } } }
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 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 spawn_doggy (ELEMENT *ElementPtr) { HELEMENT hDoggyElement; if ((hDoggyElement = AllocElement ()) != 0) { COUNT angle; ELEMENT *DoggyElementPtr; STARSHIP *StarShipPtr; ElementPtr->state_flags |= DEFY_PHYSICS; PutElement (hDoggyElement); LockElement (hDoggyElement, &DoggyElementPtr); DoggyElementPtr->hit_points = DOGGY_HITS; DoggyElementPtr->mass_points = DOGGY_MASS; DoggyElementPtr->thrust_wait = 0; DoggyElementPtr->playerNr = ElementPtr->playerNr; DoggyElementPtr->state_flags = APPEARING; DoggyElementPtr->life_span = NORMAL_LIFE; SetPrimType (&(GLOBAL (DisplayArray))[DoggyElementPtr->PrimIndex], STAMP_PRIM); { DoggyElementPtr->preprocess_func = doggy_preprocess; DoggyElementPtr->postprocess_func = NULL; DoggyElementPtr->collision_func = doggy_collision; DoggyElementPtr->death_func = doggy_death; } GetElementStarShip (ElementPtr, &StarShipPtr); angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE; DoggyElementPtr->current.location.x = ElementPtr->next.location.x + COSINE (angle, DISPLAY_TO_WORLD (CHENJESU_OFFSET + DOGGY_OFFSET)); DoggyElementPtr->current.location.y = ElementPtr->next.location.y + SINE (angle, DISPLAY_TO_WORLD (CHENJESU_OFFSET + DOGGY_OFFSET)); DoggyElementPtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.special; DoggyElementPtr->current.image.frame = StarShipPtr->RaceDescPtr->ship_data.special[0]; SetVelocityVector (&DoggyElementPtr->velocity, DOGGY_SPEED, NORMALIZE_FACING (ANGLE_TO_FACING (angle))); SetElementStarShip (DoggyElementPtr, StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* RELEASE_DOGGY */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 4), DoggyElementPtr); UnlockElement (hDoggyElement); } }
static void crystal_postprocess (ELEMENT *ElementPtr) { #define FRAGMENT_HITS 1 #define FRAGMENT_DAMAGE 2 #define FRAGMENT_OFFSET 2 #define NUM_FRAGMENTS 8 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.weapon; MissileBlock.index = 1; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = 0; MissileBlock.speed = FRAGMENT_SPEED; MissileBlock.hit_points = FRAGMENT_HITS; MissileBlock.damage = FRAGMENT_DAMAGE; MissileBlock.life = FRAGMENT_LIFE; MissileBlock.preprocess_func = NULL; MissileBlock.blast_offs = FRAGMENT_OFFSET; for (MissileBlock.face = 0; MissileBlock.face < ANGLE_TO_FACING (FULL_CIRCLE); MissileBlock.face += (ANGLE_TO_FACING (FULL_CIRCLE) / NUM_FRAGMENTS)) { HELEMENT hFragment; hFragment = initialize_missile (&MissileBlock); if (hFragment) { ELEMENT *FragPtr; LockElement (hFragment, &FragPtr); SetElementStarShip (FragPtr, StarShipPtr); UnlockElement (hFragment); PutElement (hFragment); } } ProcessSound (SetAbsSoundIndex ( /* CRYSTAL_FRAGMENTS */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); }
static void androsynth_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); /* take care of blazer effect */ if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special) { #define BLAZER_DEGENERATION (-1) if ((StarShipPtr->cur_status_flags & SPECIAL) || StarShipPtr->RaceDescPtr->ship_info.energy_level == 0) { StarShipPtr->RaceDescPtr->characteristics.energy_regeneration = (BYTE)BLAZER_DEGENERATION; StarShipPtr->energy_counter = ENERGY_WAIT; if (StarShipPtr->cur_status_flags & SPECIAL) { ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); /* COMET_ON */ ElementPtr->turn_wait = 0; ElementPtr->thrust_wait = 0; StarShipPtr->RaceDescPtr->characteristics.special_wait = StarShipPtr->RaceDescPtr->characteristics.turn_wait; ElementPtr->mass_points = BLAZER_MASS; StarShipPtr->RaceDescPtr->characteristics.turn_wait = BLAZER_TURN_WAIT; /* Save the current collision func because we were not the * ones who set it */ StarShipPtr->RaceDescPtr->data = (intptr_t) ElementPtr->collision_func; ElementPtr->collision_func = blazer_collision; } } if (StarShipPtr->RaceDescPtr->ship_info.energy_level == 0) /* if blazer wasn't able to change back into ship * give it a little more juice to try to get out * of its predicament. */ { DeltaEnergy (ElementPtr, -BLAZER_DEGENERATION); StarShipPtr->energy_counter = 1; } } }
static void spawn_butt_missile (ELEMENT *ShipPtr) { #define SPATHI_REAR_OFFSET 20 #define DISCRIMINATOR_LIFE 30 #define DISCRIMINATOR_HITS 1 #define DISCRIMINATOR_DAMAGE 2 #define DISCRIMINATOR_OFFSET 4 HELEMENT ButtMissile; STARSHIP *StarShipPtr; MISSILE_BLOCK ButtMissileBlock; GetElementStarShip (ShipPtr, &StarShipPtr); ButtMissileBlock.cx = ShipPtr->next.location.x; ButtMissileBlock.cy = ShipPtr->next.location.y; ButtMissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; ButtMissileBlock.face = ButtMissileBlock.index = NORMALIZE_FACING (StarShipPtr->ShipFacing + ANGLE_TO_FACING (HALF_CIRCLE)); ButtMissileBlock.sender = ShipPtr->playerNr; ButtMissileBlock.flags = 0; ButtMissileBlock.pixoffs = SPATHI_REAR_OFFSET; ButtMissileBlock.speed = DISCRIMINATOR_SPEED; ButtMissileBlock.hit_points = DISCRIMINATOR_HITS; ButtMissileBlock.damage = DISCRIMINATOR_DAMAGE; ButtMissileBlock.life = DISCRIMINATOR_LIFE; ButtMissileBlock.preprocess_func = butt_missile_preprocess; ButtMissileBlock.blast_offs = DISCRIMINATOR_OFFSET; ButtMissile = initialize_missile (&ButtMissileBlock); if (ButtMissile) { ELEMENT *ButtPtr; LockElement (ButtMissile, &ButtPtr); ButtPtr->turn_wait = TRACK_WAIT; SetElementStarShip (ButtPtr, StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* LAUNCH_BUTT_MISSILE */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ButtPtr); UnlockElement (ButtMissile); PutElement (ButtMissile); } }
void DoInput (void *pInputState, BOOLEAN resetInput) { if (resetInput) FlushInput (); do { MENU_SOUND_FLAGS soundFlags; Async_process (); TaskSwitch (); UpdateInputState (); #if DEMO_MODE || CREATE_JOURNAL if (ArrowInput != DemoInput) #endif { #if CREATE_JOURNAL JournalInput (InputState); #endif /* CREATE_JOURNAL */ } soundFlags = MenuKeysToSoundFlags (&PulsedInputState); if (MenuSounds && (soundFlags & (sound_0 | sound_1))) { SOUND S; S = MenuSounds; if (soundFlags & sound_1) S = SetAbsSoundIndex (S, MENU_SOUND_SUCCESS); PlaySoundEffect (S, 0, NotPositional (), NULL, 0); } if (inputCallback) inputCallback (); } while (((INPUT_STATE_DESC*)pInputState)->InputFunc (pInputState)); if (resetInput) FlushInput (); }
static void syreen_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if ((StarShipPtr->cur_status_flags & SPECIAL) && StarShipPtr->special_counter == 0 && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { ProcessSound (SetAbsSoundIndex ( /* SYREEN_SONG */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); spawn_crew (ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; } }
static void doggy_death (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* DOGGY_DIES */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), ElementPtr); ElementPtr->state_flags &= ~DISAPPEARING; ElementPtr->state_flags |= NONSOLID | FINITE_LIFE; ElementPtr->life_span = 6; { ElementPtr->preprocess_func = animate; } ElementPtr->death_func = NULL; ElementPtr->collision_func = NULL; ZeroVelocityComponents (&ElementPtr->velocity); ElementPtr->turn_wait = ElementPtr->next_turn = 0; }
static void doggy_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1) { collision (ElementPtr0, pPt0, ElementPtr1, pPt1); if ((ElementPtr1->state_flags & PLAYER_SHIP) && !elementsOfSamePlayer (ElementPtr0, ElementPtr1)) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr0, &StarShipPtr); ProcessSound (SetAbsSoundIndex ( /* DOGGY_STEALS_ENERGY */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr0); GetElementStarShip (ElementPtr1, &StarShipPtr); if (StarShipPtr->RaceDescPtr->ship_info.energy_level < ENERGY_DRAIN) DeltaEnergy (ElementPtr1, -StarShipPtr->RaceDescPtr->ship_info.energy_level); else DeltaEnergy (ElementPtr1, -ENERGY_DRAIN); } if (ElementPtr0->thrust_wait <= COLLISION_THRUST_WAIT) ElementPtr0->thrust_wait += COLLISION_THRUST_WAIT << 1; }
void crew_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1) { if ((ElementPtr1->state_flags & PLAYER_SHIP) && ElementPtr1->life_span >= NORMAL_LIFE && ElementPtr0->hit_points > 0) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr1, &StarShipPtr); if (!(StarShipPtr->RaceDescPtr->ship_info.ship_flags & CREW_IMMUNE)) { ProcessSound (SetAbsSoundIndex (GameSounds, GRAB_CREW), ElementPtr1); DeltaCrew (ElementPtr1, 1); } } ElementPtr0->hit_points = 0; ElementPtr0->life_span = 0; ElementPtr0->state_flags |= COLLISION | DISAPPEARING | NONSOLID; (void) pPt0; /* Satisfying compiler (unused parameter) */ (void) pPt1; /* Satisfying compiler (unused parameter) */ }
static void ilwrath_preprocess (PELEMENT ElementPtr) { ELEMENT_FLAGS status_flags; STARSHIPPTR StarShipPtr; PPRIMITIVE lpPrim; GetElementStarShip (ElementPtr, &StarShipPtr); status_flags = StarShipPtr->cur_status_flags; lpPrim = &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex]; if (GetPrimType (lpPrim) == STAMPFILL_PRIM) { COLOR Color; BOOLEAN weapon_discharge; Color = GetPrimColor (lpPrim); weapon_discharge = ((status_flags & WEAPON) && StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST); if (weapon_discharge || (StarShipPtr->special_counter == 0 && ((status_flags & SPECIAL) || Color != BLACK_COLOR))) { if (Color == BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)) SetPrimType (lpPrim, STAMP_PRIM); else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); else if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)); else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)); else if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)); else { ProcessSound (SetAbsSoundIndex ( /* CLOAKING_OFF */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr); SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); if (weapon_discharge) { COUNT facing; facing = StarShipPtr->ShipFacing; if (TrackShip (ElementPtr, &facing) >= 0) { #define LOOK_AHEAD 4 ELEMENTPTR eptr; SIZE dx0, dy0, dx1, dy1; VELOCITY_DESC v; LockElement (ElementPtr->hTarget, &eptr); v = eptr->velocity; GetNextVelocityComponents (&v, &dx0, &dy0, LOOK_AHEAD); v = ElementPtr->velocity; GetNextVelocityComponents (&v, &dx1, &dy1, LOOK_AHEAD); dx0 = (eptr->current.location.x + dx0) - (ElementPtr->current.location.x + dx1); dy0 = (eptr->current.location.y + dy0) - (ElementPtr->current.location.y + dy1); UnlockElement (ElementPtr->hTarget); StarShipPtr->ShipFacing = NORMALIZE_FACING ( ANGLE_TO_FACING (ARCTAN (dx0, dy0)) ); #ifdef NOTYET if (ElementPtr->thrust_wait == 0 && (StarShipPtr->cur_status_flags & THRUST)) { COUNT last_facing; do { VELOCITY_DESC temp_v; last_facing = StarShipPtr->ShipFacing; inertial_thrust (ElementPtr); temp_v = ElementPtr->velocity; ElementPtr->velocity = v; dx0 += dx1; dy0 += dy1; GetNextVelocityComponents (&temp_v, &dx1, &dy1, LOOK_AHEAD); dx0 -= dx1; dy0 -= dy1; StarShipPtr->ShipFacing = NORMALIZE_FACING ( ANGLE_TO_FACING (ARCTAN (dx0, dy0)) ); } while (StarShipPtr->ShipFacing != last_facing); } #endif /* NOTYET */ if (ElementPtr->turn_wait == 0) ++ElementPtr->turn_wait; ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->next.image.frame, StarShipPtr->ShipFacing); } ElementPtr->hTarget = 0; } } ElementPtr->state_flags |= CHANGING; status_flags &= ~SPECIAL; StarShipPtr->special_counter = 0; } else if (Color != BLACK_COLOR) { if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)) { SetPrimColor (lpPrim, BLACK_COLOR); Untarget (ElementPtr); } else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); else if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)); else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)); else SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)); ElementPtr->state_flags |= CHANGING; } } if ((status_flags & SPECIAL) && StarShipPtr->special_counter == 0 && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); SetPrimType (lpPrim, STAMPFILL_PRIM); ProcessSound (SetAbsSoundIndex ( /* CLOAKING_ON */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; ElementPtr->state_flags |= CHANGING; } }
// When hit by Baul spray, gas clouds explodes transforming into a lethal shockwave. static void generate_shockwave (ELEMENT *ElementPtr, BYTE which_player) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); // Gas is still 'solid' when it's hit by the spray. Let's make a shockwave and kill the gas cloud. if (!(ElementPtr->state_flags & NONSOLID)) { HELEMENT hShockwave; hShockwave = AllocElement (); if (hShockwave) { ELEMENT *ShockwavePtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); PutElement (hShockwave); LockElement (hShockwave, &ShockwavePtr); SetElementStarShip (ShockwavePtr, StarShipPtr); ShockwavePtr->hit_points = ShockwavePtr->mass_points = 0; ShockwavePtr->playerNr = which_player; ShockwavePtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID | IGNORE_SIMILAR; ShockwavePtr->life_span = SHOCKWAVE_FRAMES; SetPrimType (&(GLOBAL (DisplayArray))[ShockwavePtr->PrimIndex], STAMP_PRIM); ShockwavePtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.special; ShockwavePtr->current.image.frame = SetAbsFrameIndex(StarShipPtr->RaceDescPtr->ship_data.special[0], LAST_GAS_INDEX); ShockwavePtr->next.image.frame = SetAbsFrameIndex(ElementPtr->current.image.frame, LAST_GAS_INDEX); ShockwavePtr->current.location = ElementPtr->current.location; ShockwavePtr->preprocess_func = shockwave_preprocess; ShockwavePtr->postprocess_func = NULL; ShockwavePtr->death_func = NULL; ZeroVelocityComponents (&ShockwavePtr->velocity); UnlockElement (hShockwave); } // Gas dies on the next turn. ElementPtr->state_flags |= NONSOLID; // Explosion sounds. ProcessSound (SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr); ProcessSound (SetAbsSoundIndex (GameSounds, TARGET_DAMAGED_FOR_6_PLUS_PT), ElementPtr); } { // This is called during PostProcessQueue(), close to or at the end, // for the temporary shockwave element to apply the damage. // The effects are not seen until the next frame. HELEMENT hElement, hNextElement; for (hElement = GetHeadElement (); hElement != 0; hElement = hNextElement) { ELEMENT *ObjPtr; LockElement (hElement, &ObjPtr); hNextElement = GetSuccElement (ObjPtr); if (IS_GAS (ObjPtr)) { SIZE delta_x, delta_y; DWORD dist; if ((delta_x = ObjPtr->next.location.x - ElementPtr->next.location.x) < 0) delta_x = -delta_x; if ((delta_y = ObjPtr->next.location.y - ElementPtr->next.location.y) < 0) delta_y = -delta_y; delta_x = WORLD_TO_DISPLAY (delta_x); delta_y = WORLD_TO_DISPLAY (delta_y); if (delta_x <= SHOCKWAVE_RANGE && delta_y <= SHOCKWAVE_RANGE && (dist = (DWORD)(delta_x * delta_x) + (DWORD)(delta_y * delta_y)) <= (DWORD)(SHOCKWAVE_RANGE * SHOCKWAVE_RANGE)) { SIZE destruction; destruction = ((MAX_DESTRUCTION * (SHOCKWAVE_RANGE - square_root (dist))) / SHOCKWAVE_RANGE) + 1; // The shockwave is delayed according to how far it is from the shockwave that set it off. ObjPtr->life_span = (10 / destruction); ObjPtr->death_func = generate_shockwave_2; ObjPtr->playerNr = which_player; } } else if (CollidingElement (ObjPtr) || ORZ_MARINE (ObjPtr)) { SIZE delta_x, delta_y; DWORD dist; if ((delta_x = ObjPtr->next.location.x - ElementPtr->next.location.x) < 0) delta_x = -delta_x; if ((delta_y = ObjPtr->next.location.y - ElementPtr->next.location.y) < 0) delta_y = -delta_y; delta_x = WORLD_TO_DISPLAY (delta_x); delta_y = WORLD_TO_DISPLAY (delta_y); if (delta_x <= SHOCKWAVE_RANGE && delta_y <= SHOCKWAVE_RANGE && (dist = (DWORD)(delta_x * delta_x) + (DWORD)(delta_y * delta_y)) <= (DWORD)(SHOCKWAVE_RANGE * SHOCKWAVE_RANGE)) { SIZE destruction; destruction = ((MAX_DESTRUCTION * (SHOCKWAVE_RANGE - square_root (dist))) / SHOCKWAVE_RANGE) + 1; if (ObjPtr->state_flags & PLAYER_SHIP && ObjPtr->playerNr != which_player) { STARSHIP *EnemyShipPtr; GetElementStarShip (ObjPtr, &EnemyShipPtr); // Deal damage to ships except shield-using Yehat & Utwig. if (!((EnemyShipPtr->SpeciesID == YEHAT_ID || EnemyShipPtr->SpeciesID == UTWIG_ID) && ObjPtr->life_span > NORMAL_LIFE)) { if (!DeltaCrew (ObjPtr, -destruction)) ObjPtr->life_span = 0; } // Charge Utwig shield. else if (EnemyShipPtr->SpeciesID == UTWIG_ID && ObjPtr->life_span > NORMAL_LIFE) ObjPtr->life_span += destruction; } else if (!GRAVITY_MASS (ObjPtr->mass_points) && ObjPtr->playerNr != which_player) { if ((BYTE)destruction < ObjPtr->hit_points) ObjPtr->hit_points -= (BYTE)destruction; else { ObjPtr->hit_points = 0; ObjPtr->life_span = 0; } } } } UnlockElement (hElement); } } }
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 thraddash_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (!(StarShipPtr->cur_status_flags & SPECIAL)) { if ((StarShipPtr->old_status_flags & SPECIAL) && (StarShipPtr->cur_status_flags & SHIP_AT_MAX_SPEED)) StarShipPtr->cur_status_flags |= SHIP_BEYOND_MAX_SPEED; } else if (DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { COUNT max_thrust, thrust_increment; STATUS_FLAGS thrust_status; HELEMENT hTrailElement; if (!(StarShipPtr->old_status_flags & SPECIAL)) StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED); if (ElementPtr->thrust_wait == 0) ++ElementPtr->thrust_wait; thrust_increment = StarShipPtr->RaceDescPtr->characteristics.thrust_increment; max_thrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = SPECIAL_THRUST_INCREMENT; StarShipPtr->RaceDescPtr->characteristics.max_thrust = SPECIAL_MAX_THRUST; thrust_status = inertial_thrust (ElementPtr); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED | SHIP_IN_GRAVITY_WELL); StarShipPtr->cur_status_flags |= thrust_status; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = thrust_increment; StarShipPtr->RaceDescPtr->characteristics.max_thrust = max_thrust; { MISSILE_BLOCK MissileBlock; MissileBlock.cx = ElementPtr->next.location.x; MissileBlock.cy = ElementPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = 0; MissileBlock.index = GetFrameCount ( StarShipPtr->RaceDescPtr->ship_data.special[0] ) - 1; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = 0; MissileBlock.speed = 0; MissileBlock.hit_points = NAPALM_HITS; MissileBlock.damage = NAPALM_DAMAGE; MissileBlock.life = NAPALM_LIFE; MissileBlock.preprocess_func = flame_napalm_preprocess; MissileBlock.blast_offs = NAPALM_OFFSET; hTrailElement = initialize_missile (&MissileBlock); if (hTrailElement) { ELEMENT *TrailElementPtr; LockElement (hTrailElement, &TrailElementPtr); SetElementStarShip (TrailElementPtr, StarShipPtr); TrailElementPtr->hTarget = 0; /* turn_wait is abused here to store the speed of the decay * animation */ TrailElementPtr->turn_wait = NAPALM_DECAY_RATE; TrailElementPtr->state_flags |= NONSOLID; SetPrimType ( &(GLOBAL (DisplayArray))[TrailElementPtr->PrimIndex], NO_PRIM ); /* normally done during preprocess, but because * object is being inserted at head rather than * appended after tail it may never get preprocessed. */ TrailElementPtr->next = TrailElementPtr->current; TrailElementPtr->state_flags |= PRE_PROCESS; UnlockElement (hTrailElement); InsertElement (hTrailElement, GetHeadElement ()); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); } } } }
static void pump_up_postprocess (ELEMENT *ElementPtr) { if (ElementPtr->state_flags & APPEARING) { ZeroVelocityComponents (&ElementPtr->velocity); } else { HELEMENT hPumpUp; ELEMENT *EPtr; ELEMENT *ShipPtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); LockElement (StarShipPtr->hShip, &ShipPtr); initialize_pump_up (ShipPtr, &hPumpUp); DeltaEnergy (ShipPtr, 0); UnlockElement (StarShipPtr->hShip); LockElement (hPumpUp, &EPtr); EPtr->current.image.frame = ElementPtr->current.image.frame; EPtr->turn_wait = ElementPtr->turn_wait; EPtr->thrust_wait = ElementPtr->thrust_wait; if (--EPtr->thrust_wait == 0) { if ((EPtr->turn_wait & ~REVERSE_DIR) < MAX_PUMP - 1) { ++EPtr->turn_wait; EPtr->current.image.frame = SetRelFrameIndex ( EPtr->current.image.frame, NUM_PUMP_ANIMS); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), EPtr); } EPtr->thrust_wait = LEVEL_COUNTER; } EPtr->mass_points = EPtr->hit_points = (PUMPUP_DAMAGE << (ElementPtr->turn_wait & ~REVERSE_DIR)); SetElementStarShip (EPtr, StarShipPtr); if (EPtr->thrust_wait & 1) { COUNT frame_index; frame_index = GetFrameIndex (EPtr->current.image.frame); if (((EPtr->turn_wait & REVERSE_DIR) && (frame_index % NUM_PUMP_ANIMS) != 0) || (!(EPtr->turn_wait & REVERSE_DIR) && ((frame_index + 1) % NUM_PUMP_ANIMS) == 0)) { --frame_index; EPtr->turn_wait |= REVERSE_DIR; } else { ++frame_index; EPtr->turn_wait &= ~REVERSE_DIR; } EPtr->current.image.frame = SetAbsFrameIndex ( EPtr->current.image.frame, frame_index); } if (StarShipPtr->cur_status_flags & StarShipPtr->old_status_flags & WEAPON) { StarShipPtr->weapon_counter = WEAPON_WAIT; } else { SIZE dx, dy; COUNT angle; EPtr->life_span = PUMPUP_LIFE; EPtr->preprocess_func = pump_up_preprocess; EPtr->postprocess_func = 0; angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing); SetVelocityComponents (&EPtr->velocity, COSINE (angle, WORLD_TO_VELOCITY (PUMPUP_SPEED)), SINE (angle, WORLD_TO_VELOCITY (PUMPUP_SPEED))); GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); dx = dx * 1/2; dy = dy * 1/2; // Add some of the Trader's velocity to its projectiles. DeltaVelocityComponents (&EPtr->velocity, dx, dy); EPtr->current.location.x -= VELOCITY_TO_WORLD (dx); EPtr->current.location.y -= VELOCITY_TO_WORLD (dy); ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), EPtr); } UnlockElement (hPumpUp); PutElement (hPumpUp); SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], NO_PRIM); ElementPtr->state_flags |= NONSOLID; } }
void ship_death (ELEMENT *ShipPtr) { STARSHIP *StarShipPtr; STARSHIP *VictoriousStarShipPtr; HELEMENT hElement, hNextElement; ELEMENT *ElementPtr; StopDitty (); StopMusic (); GetElementStarShip (ShipPtr, &StarShipPtr); // JMS: Make sure the Foon-foon's spinning blade sound ends when the ship dies. if (StarShipPtr->SpeciesID == FOONFOON_ID) { COUNT i; for (i = FIRST_SFX_CHANNEL; i <= LAST_SFX_CHANNEL; ++i) { ELEMENT *posobj; if (!ChannelPlaying(i)) continue; posobj = GetPositionalObject (i); if (posobj) StopSource (i); } } if (ShipPtr->mass_points <= MAX_SHIP_MASS) { // Not running away and not reincarnating (Pkunk) // When a ship tries to run away, it is (dis)counted in DoRunAway(), // so when it dies while running away, we will not count it again assert (StarShipPtr->playerNr >= 0); battle_counter[StarShipPtr->playerNr]--; } VictoriousStarShipPtr = NULL; for (hElement = GetHeadElement (); hElement; hElement = hNextElement) { LockElement (hElement, &ElementPtr); if ((ElementPtr->state_flags & PLAYER_SHIP) && ElementPtr != ShipPtr /* and not running away */ && ElementPtr->mass_points <= MAX_SHIP_MASS) { GetElementStarShip (ElementPtr, &VictoriousStarShipPtr); if (VictoriousStarShipPtr->RaceDescPtr->ship_info.crew_level == 0) VictoriousStarShipPtr = NULL; UnlockElement (hElement); break; } hNextElement = GetSuccElement (ElementPtr); UnlockElement (hElement); } StarShipPtr->cur_status_flags &= ~PLAY_VICTORY_DITTY; DeltaEnergy (ShipPtr, -(SIZE)StarShipPtr->RaceDescPtr->ship_info.energy_level); ShipPtr->life_span = NUM_EXPLOSION_FRAMES * 3; ShipPtr->state_flags &= ~DISAPPEARING; ShipPtr->state_flags |= FINITE_LIFE | NONSOLID; ShipPtr->postprocess_func = PostProcessStatus; ShipPtr->death_func = cleanup_dead_ship; ShipPtr->hTarget = 0; ZeroVelocityComponents (&ShipPtr->velocity); if (ShipPtr->crew_level) /* only happens for shofixti self-destruct */ { PlaySound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); DeltaCrew (ShipPtr, -(SIZE)ShipPtr->crew_level); if (VictoriousStarShipPtr == NULL) { // No ships left alive after a Shofixti Glory device, // thus Shofixti wins VictoriousStarShipPtr = StarShipPtr; } } else { ShipPtr->preprocess_func = explosion_preprocess; PlaySound (SetAbsSoundIndex (GameSounds, SHIP_EXPLODES), CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); } if (VictoriousStarShipPtr != NULL) VictoriousStarShipPtr->cur_status_flags |= PLAY_VICTORY_DITTY; // The winner is set once per battle. If both ships die, this function is // called twice, once for each ship. We need to preserve the winner // determined on the first call. if (winnerStarShip == NULL) winnerStarShip = VictoriousStarShipPtr; if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) MeleeShipDeath (StarShipPtr); }
// Secondary weapon: Gas cloud. // The IGNORE_VELOCITY flag is very important: It doesn't only stop the gas from reacting to gravity, // (see collide.h) but it also makes it possible for the gas to stick to enemy ship (see this file's other gas functions). static void spawn_gas (ELEMENT *ShipPtr) { STARSHIP *StarShipPtr; MISSILE_BLOCK MissileBlock; HELEMENT Missile; SIZE offs_x, offs_y; COUNT angle; static COUNT gas_side[NUM_SIDES] = {0, 0}; static COUNT gas_number[NUM_SIDES] = {0, 0}; GetElementStarShip (ShipPtr, &StarShipPtr); gas_number[ShipPtr->playerNr] = (gas_number[ShipPtr->playerNr] + 1) % 32; gas_side[ShipPtr->playerNr] = (gas_side[ShipPtr->playerNr] + 1) % 2; angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing); // This mechanism can be used to alter the "pipe" from which the gas clouds come. if(gas_side[ShipPtr->playerNr]) { offs_x = -SINE (angle, GAS_HORZ_OFFSET); offs_y = COSINE (angle, GAS_HORZ_OFFSET); } else { offs_x = -SINE (angle, GAS_HORZ_OFFSET); offs_y = COSINE (angle, GAS_HORZ_OFFSET); } MissileBlock.cx = ShipPtr->next.location.x + offs_x; MissileBlock.cy = ShipPtr->next.location.y + offs_y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = StarShipPtr->ShipFacing;// Baul's gas now flies forward. (this was: (StarShipPtr->ShipFacing - 8) % 16;) MissileBlock.index = LAST_DISSOLVE_INDEX; // Start with the gas emerge animation which is the last .pngs in gasXX.ani MissileBlock.sender = ShipPtr->playerNr; MissileBlock.flags = GASSY_SUBSTANCE | IGNORE_VELOCITY; // Don't erase the IGNORE_VELOCITY. It's very important. MissileBlock.pixoffs = GAS_OFFSET; MissileBlock.speed = GAS_INIT_SPEED; MissileBlock.hit_points = GAS_HITS; MissileBlock.damage = GAS_DAMAGE; MissileBlock.life = GAS_LIFE; MissileBlock.preprocess_func = gas_preprocess; MissileBlock.blast_offs = 0; Missile = initialize_missile (&MissileBlock); if (Missile) { ELEMENT *GasPtr; SIZE dx, dy; // Baul's gas now flies forward. LockElement (Missile, &GasPtr); // Baul's gas now flies forward. GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy); DeltaVelocityComponents (&GasPtr->velocity, dx, dy); GasPtr->current.location.x -= VELOCITY_TO_WORLD (dx); GasPtr->current.location.y -= VELOCITY_TO_WORLD (dy); GasPtr->collision_func = gas_collision; GasPtr->death_func = gas_death; GasPtr->thrust_wait = 1; GasPtr->weapon_element_index = gas_number[ShipPtr->playerNr]; SetElementStarShip (GasPtr, StarShipPtr); ProcessSound (SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), GasPtr); UnlockElement (Missile); PutElement (Missile); } }
static void ilwrath_preprocess (ELEMENT *ElementPtr) { STATUS_FLAGS status_flags; STARSHIP *StarShipPtr; PRIMITIVE *lpPrim; GetElementStarShip (ElementPtr, &StarShipPtr); status_flags = StarShipPtr->cur_status_flags; lpPrim = &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex]; if (GetPrimType (lpPrim) == STAMPFILL_PRIM) { Color color; BOOLEAN weapon_discharge; color = GetPrimColor (lpPrim); weapon_discharge = ((status_flags & WEAPON) && StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST); if ( weapon_discharge || ( StarShipPtr->special_counter == 0 && ( ((!sameColor(color, BLACK_COLOR)) && (!sameColor(color, INVIS_COLOR))) || status_flags & SPECIAL ) ) ) { if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F))) SetPrimType (lpPrim, STAMP_PRIM); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)); else { ProcessSound (SetAbsSoundIndex ( /* CLOAKING_OFF */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr); SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); } ElementPtr->state_flags |= CHANGING; status_flags &= ~SPECIAL; StarShipPtr->special_counter = 0; } else if ( (!sameColor (color, BLACK_COLOR)) && (!sameColor (color, INVIS_COLOR))) { if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01))) { if(PlayerControl[ElementPtr->playerNr] & HUMAN_CONTROL) SetPrimColor (lpPrim, INVIS_COLOR); else SetPrimColor (lpPrim, BLACK_COLOR); Untarget (ElementPtr); } else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)); else SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)); ElementPtr->state_flags |= CHANGING; } } if ((status_flags & SPECIAL) && StarShipPtr->special_counter == 0 && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); SetPrimType (lpPrim, STAMPFILL_PRIM); ProcessSound (SetAbsSoundIndex ( /* CLOAKING_ON */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; ElementPtr->state_flags |= CHANGING; } }
static void arilou_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (!(ElementPtr->state_flags & NONSOLID)) { if (ElementPtr->thrust_wait == 0) { ZeroVelocityComponents (&ElementPtr->velocity); StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED; } if ((StarShipPtr->cur_status_flags & SPECIAL) && StarShipPtr->special_counter == 0 && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { /* Special key is pressed; start teleport */ #define HYPER_LIFE 5 ZeroVelocityComponents (&ElementPtr->velocity); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | LEFT | RIGHT | THRUST | WEAPON); ElementPtr->state_flags |= NONSOLID | FINITE_LIFE | CHANGING; ElementPtr->life_span = HYPER_LIFE; ElementPtr->next.image.farray = StarShipPtr->RaceDescPtr->ship_data.special; ElementPtr->next.image.frame = StarShipPtr->RaceDescPtr->ship_data.special[0]; ProcessSound (SetAbsSoundIndex ( /* HYPERJUMP */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); StarShipPtr->special_counter = StarShipPtr->RaceDescPtr->characteristics.special_wait; } } else if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special) { COUNT life_span; StarShipPtr->cur_status_flags = (StarShipPtr->cur_status_flags & ~(LEFT | RIGHT | THRUST | WEAPON | SPECIAL)) | (StarShipPtr->old_status_flags & (LEFT | RIGHT | THRUST | WEAPON | SPECIAL)); ++StarShipPtr->weapon_counter; ++StarShipPtr->special_counter; ++StarShipPtr->energy_counter; ++ElementPtr->turn_wait; ++ElementPtr->thrust_wait; if ((life_span = ElementPtr->life_span) == NORMAL_LIFE) { /* Ending teleport */ ElementPtr->state_flags &= ~(NONSOLID | FINITE_LIFE); ElementPtr->state_flags |= APPEARING; ElementPtr->current.image.farray = ElementPtr->next.image.farray = StarShipPtr->RaceDescPtr->ship_data.ship; ElementPtr->current.image.frame = ElementPtr->next.image.frame = SetAbsFrameIndex (StarShipPtr->RaceDescPtr->ship_data.ship[0], StarShipPtr->ShipFacing); InitIntersectStartPoint (ElementPtr); } else { /* Teleporting in progress */ --life_span; if (life_span != 2) { if (life_span < 2) ElementPtr->next.image.frame = DecFrameIndex (ElementPtr->next.image.frame); else ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->next.image.frame); } else { ElementPtr->next.location.x = WRAP_X (DISPLAY_ALIGN_X (TFB_Random ())); ElementPtr->next.location.y = WRAP_Y (DISPLAY_ALIGN_Y (TFB_Random ())); } } ElementPtr->state_flags |= CHANGING; } }
static void pkunk_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if (ElementPtr->state_flags & APPEARING) { HELEMENT hPhoenix = 0; if ((BYTE)TFB_Random () & 1) hPhoenix = AllocElement (); if (hPhoenix) { ELEMENT *PhoenixPtr; LockElement (hPhoenix, &PhoenixPtr); PhoenixPtr->playerNr = ElementPtr->playerNr; PhoenixPtr->state_flags = FINITE_LIFE | NONSOLID | IGNORE_SIMILAR; PhoenixPtr->life_span = 1; PhoenixPtr->death_func = intercept_pkunk_death; SetElementStarShip (PhoenixPtr, StarShipPtr); UnlockElement (hPhoenix); InsertElement (hPhoenix, GetHeadElement ()); } StarShipPtr->RaceDescPtr->data = (intptr_t) hPhoenix; if (ElementPtr->hTarget == 0) StarShipPtr->RaceDescPtr->preprocess_func = 0; else { COUNT angle, facing; ProcessSound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1 ), ElementPtr); ElementPtr->life_span = PHOENIX_LIFE; SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], NO_PRIM); ElementPtr->state_flags |= NONSOLID | FINITE_LIFE | CHANGING; facing = StarShipPtr->ShipFacing; for (angle = OCTANT; angle < FULL_CIRCLE; angle += QUADRANT) { StarShipPtr->ShipFacing = NORMALIZE_FACING ( facing + ANGLE_TO_FACING (angle) ); phoenix_transition (ElementPtr); } StarShipPtr->ShipFacing = facing; } } if (StarShipPtr->RaceDescPtr->preprocess_func) { StarShipPtr->cur_status_flags &= ~(LEFT | RIGHT | THRUST | WEAPON | SPECIAL); if (ElementPtr->life_span == NORMAL_LIFE) { ElementPtr->current.image.frame = ElementPtr->next.image.frame = SetEquFrameIndex ( ElementPtr->current.image.farray[0], ElementPtr->current.image.frame); SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], STAMP_PRIM); InitIntersectStartPoint (ElementPtr); InitIntersectEndPoint (ElementPtr); InitIntersectFrame (ElementPtr); ZeroVelocityComponents (&ElementPtr->velocity); ElementPtr->state_flags &= ~(NONSOLID | FINITE_LIFE); ElementPtr->state_flags |= CHANGING; StarShipPtr->RaceDescPtr->preprocess_func = 0; } } }
static void thraddash_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); // Switch side guns after every shot. if (StarShipPtr->weapon_counter == 1) { if (StarShipPtr->static_counter == 0) ++StarShipPtr->static_counter; else StarShipPtr->static_counter = 0; } if (!(StarShipPtr->cur_status_flags & SPECIAL)) { if (StarShipPtr->old_status_flags & SPECIAL && StarShipPtr->cur_status_flags & SHIP_AT_MAX_SPEED) StarShipPtr->cur_status_flags |= SHIP_BEYOND_MAX_SPEED; } else if (StarShipPtr->RaceDescPtr->ship_info.energy_level >= SPECIAL_ENERGY_COST) { COUNT max_thrust, thrust_increment; STATUS_FLAGS thrust_status; HELEMENT hTrailElement; if (!(StarShipPtr->old_status_flags & SPECIAL)) StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED); if (ElementPtr->thrust_wait == 0) ++ElementPtr->thrust_wait; thrust_increment = StarShipPtr->RaceDescPtr->characteristics.thrust_increment; max_thrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = SPECIAL_THRUST_INCREMENT; StarShipPtr->RaceDescPtr->characteristics.max_thrust = SPECIAL_MAX_THRUST; thrust_status = inertial_thrust (ElementPtr); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED | SHIP_IN_GRAVITY_WELL); StarShipPtr->cur_status_flags |= thrust_status; StarShipPtr->RaceDescPtr->characteristics.thrust_increment = thrust_increment; StarShipPtr->RaceDescPtr->characteristics.max_thrust = max_thrust; // Reduce afterburner energy consumption to 2/3. if (StarShipPtr->special_counter == 0) { DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); StarShipPtr->special_counter = 3; } else if (StarShipPtr->special_counter == 2) DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); { MISSILE_BLOCK MissileBlock; MissileBlock.cx = ElementPtr->next.location.x; MissileBlock.cy = ElementPtr->next.location.y; MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special; MissileBlock.face = 0; MissileBlock.index = GetFrameCount (StarShipPtr->RaceDescPtr->ship_data.special[0]) - 1; MissileBlock.sender = ElementPtr->playerNr; MissileBlock.flags = IGNORE_SIMILAR; MissileBlock.pixoffs = 0; MissileBlock.speed = 0; MissileBlock.hit_points = NAPALM_HITS; MissileBlock.damage = NAPALM_DAMAGE; MissileBlock.life = NAPALM_LIFE; MissileBlock.preprocess_func = flame_napalm_preprocess; MissileBlock.blast_offs = NAPALM_OFFSET; hTrailElement = initialize_missile (&MissileBlock); if (hTrailElement) { ELEMENT *TrailElementPtr; LockElement (hTrailElement, &TrailElementPtr); SetElementStarShip (TrailElementPtr, StarShipPtr); TrailElementPtr->hTarget = 0; TrailElementPtr->turn_wait = NAPALM_FADE_WAIT; TrailElementPtr->state_flags |= NONSOLID; SetPrimType ( &(GLOBAL (DisplayArray))[TrailElementPtr->PrimIndex], NO_PRIM ); /* normally done during preprocess, but because * object is being inserted at head rather than * appended after tail it may never get preprocessed. */ TrailElementPtr->next = TrailElementPtr->current; TrailElementPtr->state_flags |= PRE_PROCESS; UnlockElement (hTrailElement); InsertElement (hTrailElement, GetHeadElement ()); ProcessSound (SetAbsSoundIndex ( /* BURNT_TOAST */ StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); } } } else if (StarShipPtr->RaceDescPtr->ship_info.energy_level < SPECIAL_ENERGY_COST) DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); /* so text will flash */ }