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 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 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 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 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 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); } }
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; } }
void AudioRecording::Cleanup(AudioComponent *audio, AudioNegativeComponent *audioNeg) { if (hWaveIn) { MMRESULT result = waveInReset(hWaveIn); if (result == MMSYSERR_NOERROR) { if (_state == RecordState::Recording) { if (audioNeg && (waveHeader.dwBytesRecorded > 0)) { // Fill in the audio negative. audioNeg->Audio.Frequency = _recordingFreq; audioNeg->Audio.Flags = _recordingFlags; uint8_t *rawData = reinterpret_cast<uint8_t*>(waveHeader.lpData); audioNeg->Audio.DigitalSamplePCM.clear(); audioNeg->Audio.DigitalSamplePCM.reserve(waveHeader.dwBytesRecorded); std::copy(rawData, rawData + waveHeader.dwBytesRecorded, std::back_inserter(audioNeg->Audio.DigitalSamplePCM)); // Use the default settings: audioNeg->Settings = *appState->_audioProcessing; audio->Flags = _finalFormatFlags; audio->Frequency = _recordingFreq; audio->DigitalSamplePCM.clear(); audioNeg->Audio.ScanForClipped(); ProcessSound(*audioNeg, *audio, audio->Flags); } } } waveInUnprepareHeader(hWaveIn, &waveHeader, sizeof(waveHeader)); waveInClose(hWaveIn); hWaveIn = nullptr; memset(&waveHeader, 0, sizeof(waveHeader)); // Just for good measure lastStreamPositionMonitored = 0; } _state = RecordState::Stopped; }
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; }
// Gas spawning happens in postprocess, because the game seems to like to put specials on the playing field // in postprocess (I guess it has something to do with keeping the queue of elements in the right order.) static void baul_postprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if ((StarShipPtr->cur_status_flags & SPECIAL) && StarShipPtr->special_counter == 0 && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST)) { int i; ProcessSound (SetAbsSoundIndex // Spawn gas. (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr); for (i = 0; i < GAS_BATCH_SIZE; i++) spawn_gas (ElementPtr); StarShipPtr->special_counter = SPECIAL_WAIT; } }
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; } }
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 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; } }
static void preprocess_dead_ship (ELEMENT *DeadShipPtr) { ProcessSound ((SOUND)~0, NULL); (void)DeadShipPtr; // unused argument }
//--------------------------------------------------------------------------- void __fastcall TGetTrackThread::CarStatDetect() { //更改為與LIS相容方式 //由資料庫讀取Event TQuery* pQEvent = new TQuery(Form_ManageState); //Free before catch pQEvent->DatabaseName = "DB_DCH"; pQEvent->SQL->Add("SELECT * FROM tEvent"); try { //由資料庫中把問題找出來,然後進行問題觸發 pQEvent->Active = false; pQEvent->Active = true; for(pQEvent->First(); !pQEvent->Eof; pQEvent->Next()) { if(Terminated) { delete pQEvent; return; } Application->ProcessMessages(); //2002.7.15 added AnsiString CarID = pQEvent->FieldByName("CarID")->AsString; int EventType = pQEvent->FieldByName("EventType")->AsInteger; AnsiString Descript = pQEvent->FieldByName("Descript")->AsString; int CarSN = pQEvent->FieldByName("CarSN")->AsInteger; AnsiString Handler = pQEvent->FieldByName("Handler")->AsString; AnsiString SendDate = pQEvent->FieldByName("SendDate")->AsString; AnsiString SendTime = pQEvent->FieldByName("SendTime")->AsString; Form_ManageState->ImportEvent(CarSN,CarID,EventType,Descript,Handler,SendDate,SendTime); } pQEvent->Active = false; //將列表中的問題與資料庫中的問題拿出來比較,把已解決的問題刪除 for(int i=0; i<Form_ManageState->ListView1->Items->Count;i++) { //假如已經解決的問題就將該筆資料刪除 if(Terminated) { delete pQEvent; return; } Application->ProcessMessages(); //2002.7.15 added TListItem* pListItem = Form_ManageState->ListView1->Items->Item[i]; AnsiString CarID = pListItem->Caption; int EventType = pListItem->SubItems->Strings[0].ToInt(); pQEvent->SQL->Clear(); pQEvent->SQL->Add("SELECT * FROM tEvent"); pQEvent->SQL->Add("WHERE CarID = :CarID"); pQEvent->SQL->Add("AND EventType = :EventType"); pQEvent->ParamByName("CarID")->AsString = CarID; pQEvent->ParamByName("EventType")->AsInteger = EventType; pQEvent->Active = false; pQEvent->Active = true; if(pQEvent->RecordCount == 0) //此車輛已沒有進行監控,刪除 { pListItem->Delete(); i--; } pQEvent->Active = false; } } catch(EDBEngineError &E) { DataModule1->EstablishConnect(1); } catch(...) {} //將就資料刪除, delete pQEvent; //處理警告聲音 ProcessSound(); }
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; } }
void cleanup_dead_ship (ELEMENT *DeadShipPtr) { STARSHIP *DeadStarShipPtr; ProcessSound ((SOUND)~0, NULL); GetElementStarShip (DeadShipPtr, &DeadStarShipPtr); { // Ship explosion has finished, or ship has just warped out // if DeadStarShipPtr->crew_level != 0 BOOLEAN MusicStarted; HELEMENT hElement, hSuccElement; /* Record crew left after the battle */ DeadStarShipPtr->crew_level = DeadStarShipPtr->RaceDescPtr->ship_info.crew_level; MusicStarted = FALSE; for (hElement = GetHeadElement (); hElement; hElement = hSuccElement) { ELEMENT *ElementPtr; STARSHIP *StarShipPtr; LockElement (hElement, &ElementPtr); hSuccElement = GetSuccElement (ElementPtr); GetElementStarShip (ElementPtr, &StarShipPtr); // Get the STARSHIP that this ELEMENT belongs to. if (StarShipPtr == DeadStarShipPtr) { // This element belongs to the dead ship; it may be the // ship's own element. SetElementStarShip (ElementPtr, 0); if (!(ElementPtr->state_flags & CREW_OBJECT) || ElementPtr->preprocess_func != crew_preprocess) { // Set the element up for deletion. SetPrimType (&DisplayArray[ElementPtr->PrimIndex], NO_PRIM); ElementPtr->life_span = 0; ElementPtr->state_flags = NONSOLID | DISAPPEARING | FINITE_LIFE; ElementPtr->preprocess_func = 0; ElementPtr->postprocess_func = 0; ElementPtr->death_func = 0; ElementPtr->collision_func = 0; } } if (StarShipPtr && (StarShipPtr->cur_status_flags & PLAY_VICTORY_DITTY)) { // StarShipPtr points to the remaining ship. MusicStarted = TRUE; PlayDitty (StarShipPtr); StarShipPtr->cur_status_flags &= ~PLAY_VICTORY_DITTY; } UnlockElement (hElement); } DeadShipPtr->state_flags |= DeadShipPtr->turn_wait; #define MIN_DITTY_FRAME_COUNT ((ONE_SECOND * 3) / BATTLE_FRAME_RATE) // The ship will be "alive" for at least 2 more frames to make sure // the elements it owns (set up for deletion above) expire first. // Ditty does NOT play in the following circumstances: // * The winning ship dies before the loser finishes exploding // * At the moment the losing ship dies, the winner has started // the warp out sequence DeadShipPtr->life_span = MusicStarted ? MIN_DITTY_FRAME_COUNT : 1; if (DeadStarShipPtr == winnerStarShip) { // This ship died but won the battle. We need to keep it alive // longer than the dead opponent ship so that the winning player // picks last. DeadShipPtr->life_span = MIN_DITTY_FRAME_COUNT + 1; } DeadShipPtr->death_func = new_ship; DeadShipPtr->preprocess_func = preprocess_dead_ship; DeadShipPtr->state_flags &= ~DISAPPEARING; // XXX: this increment was originally done by another piece of code // just below this one. I am almost sure it is not needed, but it // keeps the original framecount. ++DeadShipPtr->life_span; SetElementStarShip (DeadShipPtr, DeadStarShipPtr); } }
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 */ }
// 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); } } }
// 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); } }