// Create a frame for each player to display their current fleet in, // to be used when selecting the next ship to fight with. void BuildPickMeleeFrame (void) { STAMP s; CONTEXT OldContext = SetContext (OffScreenContext); if (PickMeleeFrame) DestroyDrawable (ReleaseDrawable (PickMeleeFrame)); PickMeleeFrame = CaptureDrawable (CreateDrawable ( WANT_PIXMAP, MELEE_WIDTH, MELEE_HEIGHT, 2)); s.origin.x = 0; s.origin.y = 0; s.frame = CaptureDrawable (LoadGraphic (MELEE_PICK_MASK_PMAP_ANIM)); SetContextFGFrame (PickMeleeFrame); DrawStamp (&s); s.frame = IncFrameIndex (s.frame); SetContextFGFrame (IncFrameIndex (PickMeleeFrame)); DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); SetContext (OldContext); }
static void splinter_preprocess (ELEMENT *ElementPtr) { ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); ElementPtr->state_flags |= CHANGING; }
static void spin_preprocess (ELEMENT *ElementPtr) { ELEMENT *ShipPtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); LockElement (StarShipPtr->hShip, &ShipPtr); if (ShipPtr->crew_level && ++StarShipPtr->RaceDescPtr->characteristics.special_wait > MAX_SAWS) { ElementPtr->life_span = 1; ElementPtr->state_flags |= DISAPPEARING; } else { ++ElementPtr->life_span; if (ElementPtr->turn_wait) --ElementPtr->turn_wait; else { #define LAST_SPIN_INDEX 1 if (GetFrameIndex (ElementPtr->current.image.frame) < LAST_SPIN_INDEX) ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); else ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->current.image.frame, 0); ElementPtr->state_flags |= CHANGING; ElementPtr->turn_wait = SAW_RATE; } } UnlockElement (StarShipPtr->hShip); }
static void blaster_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1) { HELEMENT hBlastElement; hBlastElement = weapon_collision (ElementPtr0, pPt0, ElementPtr1, pPt1); if (hBlastElement) { ELEMENT *BlastElementPtr; LockElement (hBlastElement, &BlastElementPtr); switch (ElementPtr0->mass_points) { case BLASTER_DAMAGE * 1: BlastElementPtr->life_span = 2; BlastElementPtr->current.image.frame = SetAbsFrameIndex (ElementPtr0->current.image.frame, 0); BlastElementPtr->preprocess_func = NULL; break; case BLASTER_DAMAGE * 2: BlastElementPtr->life_span = 6; BlastElementPtr->current.image.frame = IncFrameIndex (ElementPtr0->current.image.frame); break; case BLASTER_DAMAGE * 3: BlastElementPtr->life_span = 7; BlastElementPtr->current.image.frame = SetAbsFrameIndex (ElementPtr0->current.image.frame, 20); break; } UnlockElement (hBlastElement); } }
static void shockwave_preprocess (ELEMENT *ElementPtr) { ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); // This makes the shockwave animate even if the ships are not moving and the screen is stationary. ElementPtr->state_flags |= CHANGING; }
static void blaster_preprocess (ELEMENT *ElementPtr) { BYTE wait; switch (ElementPtr->mass_points) { case BLASTER_DAMAGE * 1: if (GetFrameIndex (ElementPtr->current.image.frame) < 8) { ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); ElementPtr->state_flags |= CHANGING; } break; case BLASTER_DAMAGE * 3: if (GetFrameIndex (ElementPtr->current.image.frame) < 19) ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); else ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->current.image.frame, 16); ElementPtr->state_flags |= CHANGING; break; } if (LONIBBLE (ElementPtr->turn_wait)) --ElementPtr->turn_wait; else if ((wait = HINIBBLE (ElementPtr->turn_wait))) { COUNT facing; facing = NORMALIZE_FACING (ANGLE_TO_FACING ( GetVelocityTravelAngle (&ElementPtr->velocity))); if (TrackShip (ElementPtr, &facing) > 0) SetVelocityVector (&ElementPtr->velocity, BLASTER_SPEED, facing); ElementPtr->turn_wait = MAKE_BYTE (wait, wait); } }
static void flame_preprocess (PELEMENT ElementPtr) { if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); ElementPtr->state_flags |= CHANGING; ElementPtr->turn_wait = ElementPtr->next_turn; } }
static void shofixti_postprocess (PELEMENT ElementPtr) { STARSHIPPTR StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); if ((StarShipPtr->cur_status_flags ^ StarShipPtr->old_status_flags) & SPECIAL) { StarShipPtr->RaceDescPtr->ship_data.captain_control.special = IncFrameIndex (StarShipPtr->RaceDescPtr->ship_data.captain_control.special); if (GetFrameCount (StarShipPtr->RaceDescPtr->ship_data.captain_control.special) - GetFrameIndex (StarShipPtr->RaceDescPtr->ship_data.captain_control.special) == 3) self_destruct (ElementPtr); } }
static void bubble_preprocess (ELEMENT *ElementPtr) { BYTE thrust_wait, turn_wait; thrust_wait = HINIBBLE (ElementPtr->turn_wait); turn_wait = LONIBBLE (ElementPtr->turn_wait); if (thrust_wait > 0) --thrust_wait; else { ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); ElementPtr->state_flags |= CHANGING; thrust_wait = (BYTE)((COUNT)TFB_Random () & 3); } if (turn_wait > 0) --turn_wait; else { COUNT facing; SIZE delta_facing; facing = NORMALIZE_FACING (ANGLE_TO_FACING ( GetVelocityTravelAngle (&ElementPtr->velocity))); if ((delta_facing = TrackShip (ElementPtr, &facing)) == -1) facing = (COUNT)TFB_Random (); else if (delta_facing <= ANGLE_TO_FACING (HALF_CIRCLE)) facing += (COUNT)TFB_Random () & (ANGLE_TO_FACING (HALF_CIRCLE) - 1); else facing -= (COUNT)TFB_Random () & (ANGLE_TO_FACING (HALF_CIRCLE) - 1); SetVelocityVector (&ElementPtr->velocity, MISSILE_SPEED, facing); #define TRACK_WAIT 2 turn_wait = TRACK_WAIT; } ElementPtr->turn_wait = MAKE_BYTE (turn_wait, thrust_wait); }
// The spray preprocess function animates spray. static void spray_preprocess (ELEMENT *ElementPtr) { // Abusing thrust_wait to slow down the anim. if (ElementPtr->thrust_wait > 0) --ElementPtr->thrust_wait; // Move to next frame. else { // Abusing thrust_wait to slow down the anim. (Should help performance a bit.) ElementPtr->thrust_wait = 1; // This makes the gas animate even if the ships are not moving and the screen is stationary. ElementPtr->state_flags |= CHANGING; if (GetFrameIndex (ElementPtr->current.image.frame) < LAST_SPRAY_INDEX) ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); // This is a safeguard to prevent going over frame boundaries if someone messes up the // MISSILE_LIFE <-> LAST_SPRAY_INDEX <-> thrust_wait correspondence. else ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->current.image.frame, 0); } }
static void confuse_preprocess (ELEMENT *ElementPtr) { if (!(ElementPtr->state_flags & NONSOLID)) { ElementPtr->next.image.frame = SetAbsFrameIndex ( ElementPtr->current.image.frame, (GetFrameIndex (ElementPtr->current.image.frame) + 1) & 7); ElementPtr->state_flags |= CHANGING; } else if (ElementPtr->hTarget == 0) { ElementPtr->life_span = 0; ElementPtr->state_flags |= DISAPPEARING; } else { ELEMENT *eptr; LockElement (ElementPtr->hTarget, &eptr); ElementPtr->next.location = eptr->next.location; if (ElementPtr->turn_wait) { HELEMENT hEffect; STARSHIP *StarShipPtr; if (GetFrameIndex (ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame)) == 0) ElementPtr->next.image.frame = SetRelFrameIndex (ElementPtr->next.image.frame, -8); GetElementStarShip (eptr, &StarShipPtr); StarShipPtr->ship_input_state = (StarShipPtr->ship_input_state & ~(LEFT | RIGHT | SPECIAL)) | ElementPtr->turn_wait; // Disable Ur-Quan autoturret. if (StarShipPtr && StarShipPtr->SpeciesID == UR_QUAN_ID) ++StarShipPtr->auxiliary_counter; hEffect = AllocElement (); if (hEffect) { LockElement (hEffect, &eptr); eptr->playerNr = ElementPtr->playerNr; eptr->state_flags = FINITE_LIFE | NONSOLID | CHANGING; eptr->life_span = 1; eptr->current = eptr->next = ElementPtr->next; eptr->preprocess_func = confuse_preprocess; SetPrimType (&(GLOBAL (DisplayArray))[eptr->PrimIndex], STAMP_PRIM); GetElementStarShip (ElementPtr, &StarShipPtr); SetElementStarShip (eptr, StarShipPtr); eptr->hTarget = ElementPtr->hTarget; UnlockElement (hEffect); PutElement (hEffect); } } UnlockElement (ElementPtr->hTarget); } }
static void destruct_preprocess (PELEMENT ElementPtr) { #define DESTRUCT_SWITCH ((NUM_EXPLOSION_FRAMES * 3) - 3) PPRIMITIVE lpPrim; lpPrim = &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex]; ElementPtr->state_flags |= CHANGING; if (ElementPtr->life_span > DESTRUCT_SWITCH) { SetPrimType (lpPrim, STAMPFILL_PRIM); if (ElementPtr->life_span == DESTRUCT_SWITCH + 2) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E)); else SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); } else if (ElementPtr->life_span < DESTRUCT_SWITCH) { ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); if (GetPrimColor (lpPrim) == BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E)); else if (GetPrimColor (lpPrim) == BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x0A, 0x0A), 0x0C)); else if (GetPrimColor (lpPrim) == BUILD_COLOR (MAKE_RGB15 (0x1F, 0x0A, 0x0A), 0x0C)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x14, 0x0A, 0x00), 0x06)); else if (GetPrimColor (lpPrim) == BUILD_COLOR (MAKE_RGB15 (0x14, 0x0A, 0x00), 0x06)) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x14, 0x00, 0x00), 0x04)); } else { HELEMENT hDestruct; SetPrimType (lpPrim, NO_PRIM); ElementPtr->preprocess_func = NULL_PTR; hDestruct = AllocElement (); if (hDestruct) { ELEMENTPTR DestructPtr; STARSHIPPTR StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); PutElement (hDestruct); LockElement (hDestruct, &DestructPtr); SetElementStarShip (DestructPtr, StarShipPtr); DestructPtr->hit_points = DestructPtr->mass_points = 0; DestructPtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID; DestructPtr->life_span = (NUM_EXPLOSION_FRAMES - 3) - 1; SetPrimType ( &(GLOBAL (DisplayArray))[DestructPtr->PrimIndex], STAMPFILL_PRIM ); SetPrimColor ( &(GLOBAL (DisplayArray))[DestructPtr->PrimIndex], BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F) ); DestructPtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.special; DestructPtr->current.image.frame = StarShipPtr->RaceDescPtr->ship_data.special[0]; DestructPtr->current.location = ElementPtr->current.location; { DestructPtr->preprocess_func = destruct_preprocess; } DestructPtr->postprocess_func = DestructPtr->death_func = NULL_PTR; ZeroVelocityComponents (&DestructPtr->velocity); UnlockElement (hDestruct); } } }
static void destruct_preprocess (ELEMENT *ElementPtr) { #define DESTRUCT_SWITCH ((NUM_EXPLOSION_FRAMES * 3) - 3) PRIMITIVE *lpPrim; // ship_death() set the ship element's life_span to // (NUM_EXPLOSION_FRAMES * 3) lpPrim = &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex]; ElementPtr->state_flags |= CHANGING; if (ElementPtr->life_span > DESTRUCT_SWITCH) { // First, stamp-fill the ship's own element with changing colors // for 3 frames. No explosion element yet. SetPrimType (lpPrim, STAMPFILL_PRIM); if (ElementPtr->life_span == DESTRUCT_SWITCH + 2) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E)); else SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); } else if (ElementPtr->life_span < DESTRUCT_SWITCH) { // Stamp-fill the explosion element with cycling colors for the // remainder of the glory explosion frames. Color color = GetPrimColor (lpPrim); ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x0A), 0x0E))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x0A, 0x0A), 0x0C)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x0A, 0x0A), 0x0C))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x14, 0x0A, 0x00), 0x06)); else if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x14, 0x0A, 0x00), 0x06))) SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x14, 0x00, 0x00), 0x04)); } else { HELEMENT hDestruct; SetPrimType (lpPrim, NO_PRIM); // The ship's own element will not be drawn anymore but will remain // alive all through the glory explosion. ElementPtr->preprocess_func = NULL; // Spawn a separate glory explosion element. // XXX: Why? Why not keep using the ship's element? // Is it because of conflicting state_flags, hit_points or // mass_points? hDestruct = AllocElement (); if (hDestruct) { ELEMENT *DestructPtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); PutElement (hDestruct); LockElement (hDestruct, &DestructPtr); SetElementStarShip (DestructPtr, StarShipPtr); DestructPtr->hit_points = DestructPtr->mass_points = 0; DestructPtr->playerNr = NEUTRAL_PLAYER_NUM; DestructPtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID; DestructPtr->life_span = (NUM_EXPLOSION_FRAMES - 3) - 1; SetPrimType (&(GLOBAL (DisplayArray))[DestructPtr->PrimIndex], STAMPFILL_PRIM); SetPrimColor (&(GLOBAL (DisplayArray))[DestructPtr->PrimIndex], BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)); DestructPtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.special; DestructPtr->current.image.frame = StarShipPtr->RaceDescPtr->ship_data.special[0]; DestructPtr->current.location = ElementPtr->current.location; DestructPtr->preprocess_func = destruct_preprocess; DestructPtr->postprocess_func = NULL; DestructPtr->death_func = NULL; ZeroVelocityComponents (&DestructPtr->velocity); UnlockElement (hDestruct); } } }
static void gas_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; SDWORD dx, dy; // Baul's gas now flies forward. Slow down the gas smoothly. GetCurrentVelocityComponentsSdword (&ElementPtr->velocity, &dx, &dy); if (dx != 0 || dy != 0) { dx = (SDWORD)(dx * 9 / 10); dy = (SDWORD)(dy * 9 / 10); SetVelocityComponents (&ElementPtr->velocity, dx, dy); } GetElementStarShip (ElementPtr, &StarShipPtr); // Move to next image frame. (Abusing thrust_wait to slow down the anim.) if (ElementPtr->thrust_wait > 0) --ElementPtr->thrust_wait; else { // Abusing thrust_wait to slow down the anim. (Should help performance a bit.) ElementPtr->thrust_wait = 1; // This makes the gas animate even if the ships are not moving and the screen is stationary. ElementPtr->state_flags |= CHANGING; if (GetFrameIndex (ElementPtr->current.image.frame) >= LAST_DISSOLVE_INDEX && GetFrameIndex (ElementPtr->current.image.frame) < LAST_DISSOLVE_INDEX + NUM_EMERGE_FRAMES) ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); else if (GetFrameIndex (ElementPtr->current.image.frame) < LAST_GAS_INDEX - 1) ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); else ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->current.image.frame, 0); } // If enemy ship dies, remove the gas (this prevents game crashing upon enemy ship dying with gas on it). if ((!(ElementPtr->state_flags & IGNORE_VELOCITY) && ElementPtr->hTarget == 0) || StarShipPtr->RaceDescPtr->ship_info.crew_level == 0) { ElementPtr->life_span = 0; ElementPtr->state_flags |= DISAPPEARING; } // When the gas has collided with enemy ship, it sticks to the ship until expires. // (When the gas is sticking to enemy ship, the gas's IGNORE_VELOCITY flag is disabled.) else if (!(ElementPtr->state_flags & IGNORE_VELOCITY) && !(ElementPtr->state_flags & DISAPPEARING)) { ELEMENT *eptr; SIZE offs_x, offs_y; SBYTE leftOrRight, upOrDown; COUNT angle, angleCorrect; static BYTE alignment[NUM_SIDES]={0,0}; // eptr points to enemy ship now. LockElement (ElementPtr->hTarget, &eptr); // Make gas's location the same as the enemy ship's. ElementPtr->next.location = eptr->next.location; // Randomize the gas's location so every gas cloud doesn't stick to the same place on the enemy ship. GetElementStarShip (eptr, &StarShipPtr); angle = (ElementPtr->weapon_element_index) % 16; alignment[ElementPtr->playerNr] = ElementPtr->weapon_element_index % 4; if (alignment[ElementPtr->playerNr] == 0) { leftOrRight = -1; upOrDown = 1; angleCorrect = 0; } else if (alignment[ElementPtr->playerNr] == 1) { leftOrRight = 1; upOrDown = -1; angleCorrect = 0; } else if (alignment[ElementPtr->playerNr] == 2) { leftOrRight = -1; upOrDown = 1; angleCorrect = HALF_CIRCLE / 2; } else { leftOrRight = 1; upOrDown = -1; angleCorrect = HALF_CIRCLE / 2; } offs_x = SINE (angle - angleCorrect, (ElementPtr->weapon_element_index % 16) * (5 << RESOLUTION_FACTOR)); offs_y = COSINE (angle - angleCorrect, (ElementPtr->weapon_element_index % 16) * (5 << RESOLUTION_FACTOR)); ElementPtr->next.location.x = ElementPtr->next.location.x + leftOrRight * offs_x; ElementPtr->next.location.y = ElementPtr->next.location.y + upOrDown * offs_y; if (ElementPtr->turn_wait) { HELEMENT hEffect; hEffect = AllocElement (); if (hEffect) { // eptr points to the new gas element now. LockElement (hEffect, &eptr); eptr->playerNr = ElementPtr->playerNr; eptr->state_flags = FINITE_LIFE | GASSY_SUBSTANCE | CHANGING; eptr->life_span = 1; eptr->thrust_wait = 1; eptr->weapon_element_index = ElementPtr->weapon_element_index; eptr->current = eptr->next = ElementPtr->next; eptr->preprocess_func = gas_preprocess; eptr->collision_func = gas_collision; // No need to have death_func here: It carries on from the declaration in gas_collision. // In fact, if gas_death is put here as death_func, it just messes up the graphics. SetPrimType (&(GLOBAL (DisplayArray))[eptr->PrimIndex], STAMP_PRIM); GetElementStarShip (ElementPtr, &StarShipPtr); SetElementStarShip (eptr, StarShipPtr); eptr->hTarget = ElementPtr->hTarget; UnlockElement (hEffect); PutElement (hEffect); } } UnlockElement (ElementPtr->hTarget); } }
// This forwards the gas dissolving animation. static void gas_death_animation (ELEMENT *ElementPtr) { ElementPtr->next.image.frame = IncFrameIndex (ElementPtr->current.image.frame); ElementPtr->state_flags |= CHANGING; }
static void CaptainsWindow (CAPTAIN_STUFF *CSPtr, COORD y, STATUS_FLAGS delta_status_flags, STATUS_FLAGS cur_status_flags, COUNT Pass) { STAMP Stamp; Stamp.origin.x = CAPTAIN_XOFFS; Stamp.origin.y = y + CAPTAIN_YOFFS; if (delta_status_flags & LEFT) { Stamp.frame = CSPtr->turn; if (!(delta_status_flags & RIGHT)) { Stamp.frame = SetRelFrameIndex (Stamp.frame, 3); if (Pass == 2) { if (cur_status_flags & LEFT) Stamp.frame = IncFrameIndex (Stamp.frame); else Stamp.frame = DecFrameIndex (Stamp.frame); } } else if (cur_status_flags & RIGHT) { if (Pass == 1) Stamp.frame = SetRelFrameIndex (Stamp.frame, 3); else Stamp.frame = IncFrameIndex (Stamp.frame); DrawStamp (&Stamp); Stamp.frame = DecFrameIndex (Stamp.frame); } else { if (Pass == 1) Stamp.frame = IncFrameIndex (Stamp.frame); else Stamp.frame = SetRelFrameIndex (Stamp.frame, 3); DrawStamp (&Stamp); Stamp.frame = IncFrameIndex (Stamp.frame); } DrawStamp (&Stamp); } else if (delta_status_flags & RIGHT) { Stamp.frame = CSPtr->turn; Stamp.frame = IncFrameIndex (Stamp.frame); if (Pass == 2) { if (cur_status_flags & RIGHT) Stamp.frame = DecFrameIndex (Stamp.frame); else Stamp.frame = IncFrameIndex (Stamp.frame); } DrawStamp (&Stamp); } if (delta_status_flags & THRUST) { Stamp.frame = CSPtr->thrust; if (Pass == 1) Stamp.frame = IncFrameIndex (Stamp.frame); else if (cur_status_flags & THRUST) Stamp.frame = SetRelFrameIndex (Stamp.frame, 2); DrawStamp (&Stamp); } if (delta_status_flags & WEAPON) { Stamp.frame = CSPtr->weapon; if (Pass == 1) Stamp.frame = IncFrameIndex (Stamp.frame); else if (cur_status_flags & WEAPON) Stamp.frame = SetRelFrameIndex (Stamp.frame, 2); DrawStamp (&Stamp); } if (delta_status_flags & SPECIAL) { Stamp.frame = CSPtr->special; if (Pass == 1) Stamp.frame = IncFrameIndex (Stamp.frame); else if (cur_status_flags & SPECIAL) Stamp.frame = SetRelFrameIndex (Stamp.frame, 2); DrawStamp (&Stamp); } }
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; } }