static void flame_napalm_preprocess (ELEMENT *ElementPtr) { ZeroVelocityComponents (&ElementPtr->velocity); if (ElementPtr->state_flags & NONSOLID) { ElementPtr->state_flags &= ~NONSOLID; ElementPtr->state_flags |= APPEARING; SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], STAMP_PRIM); InitIntersectStartPoint (ElementPtr); InitIntersectEndPoint (ElementPtr); InitIntersectFrame (ElementPtr); } /* turn_wait is abused here to store the speed of the decay animation */ else if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { if (ElementPtr->life_span <= NUM_NAPALM_FADES * (NAPALM_DECAY_RATE + 1) || GetFrameIndex ( ElementPtr->current.image.frame ) != NUM_NAPALM_FADES) ElementPtr->next.image.frame = DecFrameIndex (ElementPtr->current.image.frame); else if (ElementPtr->life_span > NUM_NAPALM_FADES * (NAPALM_DECAY_RATE + 1)) ElementPtr->next.image.frame = SetAbsFrameIndex ( ElementPtr->current.image.frame, GetFrameCount (ElementPtr->current.image.frame) - 1 ); /* turn_wait is abused here to store the speed of the decay * animation. */ ElementPtr->turn_wait = NAPALM_DECAY_RATE; ElementPtr->state_flags |= CHANGING; } }
static void flame_napalm_preprocess (ELEMENT *ElementPtr) { ZeroVelocityComponents (&ElementPtr->velocity); if (ElementPtr->state_flags & NONSOLID) { ElementPtr->state_flags &= ~NONSOLID; ElementPtr->state_flags |= APPEARING; SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex], STAMP_PRIM); InitIntersectStartPoint (ElementPtr); InitIntersectEndPoint (ElementPtr); InitIntersectFrame (ElementPtr); } else if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { #define NUM_NAPALM_FADES 6 if (ElementPtr->life_span <= NUM_NAPALM_FADES * (NAPALM_WAIT + 1) || GetFrameIndex ( ElementPtr->current.image.frame ) != NUM_NAPALM_FADES) ElementPtr->next.image.frame = DecFrameIndex (ElementPtr->current.image.frame); else if (ElementPtr->life_span > NUM_NAPALM_FADES * (NAPALM_WAIT + 1)) ElementPtr->next.image.frame = SetAbsFrameIndex ( ElementPtr->current.image.frame, GetFrameCount (ElementPtr->current.image.frame) - 1 ); ElementPtr->turn_wait = NAPALM_WAIT; 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; } }
void spawn_ion_trail (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; SHIP_INFO *ShipInfoPtr; HELEMENT hIonElement; assert (ElementPtr->state_flags & PLAYER_SHIP); // JMS: Get the pointers to element's owner ship. // They are needed to see if the ship's thrust is damaged GetElementStarShip (ElementPtr, &StarShipPtr); ShipInfoPtr = &StarShipPtr->RaceDescPtr->ship_info; hIonElement = AllocElement (); if (hIonElement) { #define ION_LIFE 1 COUNT angle; RECT r; ELEMENT *IonElementPtr; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE; GetFrameRect (StarShipPtr->RaceDescPtr->ship_data.ship[0], &r); r.extent.height = DISPLAY_TO_WORLD (r.extent.height + r.corner.y); InsertElement (hIonElement, GetHeadElement ()); LockElement (hIonElement, &IonElementPtr); IonElementPtr->playerNr = NEUTRAL_PLAYER_NUM; IonElementPtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID; IonElementPtr->thrust_wait = ION_LIFE; IonElementPtr->life_span = IonElementPtr->thrust_wait; // When the element "dies", in the death_func // 'cycle_ion_trail', it is given new life a number of // times, by setting life_span to thrust_wait. SetPrimType (&DisplayArray[IonElementPtr->PrimIndex], POINT_PRIM); // JMS: Damaged thruster emits differently colored particles if (ShipInfoPtr->damage_flags & DAMAGE_THRUST) { SetPrimColor (&DisplayArray[IonElementPtr->PrimIndex], START_ION_COLOR_DAMAGED); } else { SetPrimColor (&DisplayArray[IonElementPtr->PrimIndex], START_ION_COLOR); } IonElementPtr->colorCycleIndex = 0; IonElementPtr->current.image.frame = DecFrameIndex (stars_in_space); IonElementPtr->current.image.farray = &stars_in_space; IonElementPtr->current.location = ElementPtr->current.location; IonElementPtr->current.location.x += (COORD)COSINE (angle, r.extent.height); IonElementPtr->current.location.y += (COORD)SINE (angle, r.extent.height); IonElementPtr->death_func = cycle_ion_trail; SetElementStarShip (IonElementPtr, StarShipPtr); { /* normally done during preprocess, but because * object is being inserted at head rather than * appended after tail it may never get preprocessed. */ IonElementPtr->next = IonElementPtr->current; --IonElementPtr->life_span; IonElementPtr->state_flags |= PRE_PROCESS; } UnlockElement (hIonElement); } }
void AbandonShip (ELEMENT *ShipPtr, ELEMENT *TargetPtr, COUNT crew_loss) { SIZE dx, dy; COUNT direction; RECT r; STARSHIP *StarShipPtr; HELEMENT hCrew; INTERSECT_CONTROL ShipIntersect; GetElementStarShip (ShipPtr, &StarShipPtr); if (StarShipPtr->RaceDescPtr->ship_info.ship_flags & CREW_IMMUNE) return; ShipIntersect = ShipPtr->IntersectControl; GetFrameRect (ShipIntersect.IntersectStamp.frame, &r); if ((direction = GetVelocityTravelAngle ( &ShipPtr->velocity)) == FULL_CIRCLE) dx = dy = 0; else { #define MORE_THAN_ENOUGH 100 direction += HALF_CIRCLE; dx = COSINE (direction, MORE_THAN_ENOUGH); dy = SINE (direction, MORE_THAN_ENOUGH); } while (crew_loss-- && (hCrew = AllocElement ())) { #define CREW_LIFE 300 ELEMENT *CrewPtr; DeltaCrew (ShipPtr, -1); PutElement (hCrew); LockElement (hCrew, &CrewPtr); CrewPtr->playerNr = NEUTRAL_PLAYER_NUM; CrewPtr->hit_points = 1; CrewPtr->state_flags = APPEARING | FINITE_LIFE | CREW_OBJECT; CrewPtr->life_span = CREW_LIFE; SetPrimType (&DisplayArray[CrewPtr->PrimIndex], POINT_PRIM); SetPrimColor (&DisplayArray[CrewPtr->PrimIndex], BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x00), 0x02)); CrewPtr->current.image.frame = DecFrameIndex (stars_in_space); CrewPtr->current.image.farray = &stars_in_space; CrewPtr->preprocess_func = crew_preprocess; CrewPtr->collision_func = crew_collision; SetElementStarShip (CrewPtr, StarShipPtr); GetElementStarShip (TargetPtr, &StarShipPtr); CrewPtr->hTarget = StarShipPtr->hShip; { SIZE w, h; INTERSECT_CONTROL CrewIntersect; ShipIntersect.IntersectStamp.origin = ShipPtr->IntersectControl.EndPoint; w = (SIZE)((COUNT)TFB_Random () % r.extent.width); h = (SIZE)((COUNT)TFB_Random () % r.extent.height); CrewIntersect.EndPoint = ShipIntersect.EndPoint; CrewIntersect.IntersectStamp.frame = DecFrameIndex (stars_in_space); if (dx == 0 && dy == 0) { CrewIntersect.EndPoint.x += w - (r.extent.width >> 1); CrewIntersect.EndPoint.y += h - (r.extent.height >> 1); CrewIntersect.IntersectStamp.origin = TargetPtr->IntersectControl.EndPoint; } else { if (dx == 0) CrewIntersect.EndPoint.x += w - (r.extent.width >> 1); else if (dx > 0) CrewIntersect.EndPoint.x += w; else CrewIntersect.EndPoint.x -= w; if (dy == 0) CrewIntersect.EndPoint.y += h - (r.extent.height >> 1); else if (dy > 0)