static void shofixti_intelligence (PELEMENT ShipPtr, PEVALUATE_DESC ObjectsOfConcern, COUNT ConcernCounter) { STARSHIPPTR StarShipPtr; ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter); GetElementStarShip (ShipPtr, &StarShipPtr); if (StarShipPtr->special_counter == 0) { if (StarShipPtr->ship_input_state & SPECIAL) StarShipPtr->ship_input_state &= ~SPECIAL; else { PEVALUATE_DESC lpWeaponEvalDesc, lpShipEvalDesc; lpWeaponEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX]; lpShipEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX]; if (StarShipPtr->RaceDescPtr->ship_data.special[0] && (GetFrameCount (StarShipPtr->RaceDescPtr->ship_data.captain_control.special) - GetFrameIndex (StarShipPtr->RaceDescPtr->ship_data.captain_control.special) > 5 || (lpShipEvalDesc->ObjectPtr != NULL_PTR && lpShipEvalDesc->which_turn <= 4) || (lpWeaponEvalDesc->ObjectPtr != NULL_PTR /* means IMMEDIATE WEAPON */ && (((lpWeaponEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP) && ShipPtr->crew_level == 1) || (PlotIntercept (lpWeaponEvalDesc->ObjectPtr, ShipPtr, 2, 0) && lpWeaponEvalDesc->ObjectPtr->mass_points >= ShipPtr->crew_level && (TFB_Random () & 1)))))) StarShipPtr->ship_input_state |= SPECIAL; } } }
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 nuke_preprocess (PELEMENT ElementPtr) { COUNT facing; facing = GetFrameIndex (ElementPtr->next.image.frame); if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { if (TrackShip (ElementPtr, &facing) > 0) { ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->next.image.frame, facing); ElementPtr->state_flags |= CHANGING; } ElementPtr->turn_wait = TRACK_WAIT; } { SIZE speed; #define THRUST_SCALE DISPLAY_TO_WORLD (1) if ((speed = MISSILE_SPEED + ((MISSILE_LIFE - ElementPtr->life_span) * THRUST_SCALE)) > MAX_MISSILE_SPEED) speed = MAX_MISSILE_SPEED; SetVelocityVector (&ElementPtr->velocity, speed, facing); } }
static void pump_up_preprocess (ELEMENT *ElementPtr) { if (--ElementPtr->thrust_wait & 1) { COUNT frame_index; frame_index = GetFrameIndex (ElementPtr->current.image.frame); if (((ElementPtr->turn_wait & REVERSE_DIR) && (frame_index % NUM_PUMP_ANIMS) != 0) || (!(ElementPtr->turn_wait & REVERSE_DIR) && ((frame_index + 1) % NUM_PUMP_ANIMS) == 0)) { --frame_index; ElementPtr->turn_wait |= REVERSE_DIR; } else { ++frame_index; ElementPtr->turn_wait &= ~REVERSE_DIR; } ElementPtr->next.image.frame = SetAbsFrameIndex ( ElementPtr->current.image.frame, frame_index); ElementPtr->state_flags |= CHANGING; } }
int CIntegralRotation::GetRotationAngle (const CIntegralRotationDesc &Desc) const // GetRotationAngle // // Converts from our rotation frame to an angle { return Desc.GetRotationAngle(GetFrameIndex(m_iRotationFrame)); }
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 doggy_preprocess (ELEMENT *ElementPtr) { STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr, &StarShipPtr); ++StarShipPtr->special_counter; if (ElementPtr->thrust_wait > 0) /* could be non-zero after a collision */ --ElementPtr->thrust_wait; else { COUNT facing, orig_facing; SIZE delta_facing; facing = orig_facing = NORMALIZE_FACING (ANGLE_TO_FACING ( GetVelocityTravelAngle (&ElementPtr->velocity) )); if ((delta_facing = TrackShip (ElementPtr, &facing)) < 0) facing = NORMALIZE_FACING (TFB_Random ()); else { ELEMENT *ShipPtr; LockElement (ElementPtr->hTarget, &ShipPtr); facing = NORMALIZE_FACING (ANGLE_TO_FACING ( ARCTAN (ShipPtr->current.location.x - ElementPtr->current.location.x, ShipPtr->current.location.y - ElementPtr->current.location.y) )); delta_facing = NORMALIZE_FACING (facing - GetFrameIndex (ShipPtr->current.image.frame)); UnlockElement (ElementPtr->hTarget); if (delta_facing > ANGLE_TO_FACING (HALF_CIRCLE - OCTANT) && delta_facing < ANGLE_TO_FACING (HALF_CIRCLE + OCTANT)) { if (delta_facing >= ANGLE_TO_FACING (HALF_CIRCLE)) facing -= ANGLE_TO_FACING (QUADRANT); else facing += ANGLE_TO_FACING (QUADRANT); } facing = NORMALIZE_FACING (facing); } if (facing != orig_facing) SetVelocityVector (&ElementPtr->velocity, DOGGY_SPEED, facing); } }
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); } }
void RasterLayer::mousePressEvent(QMouseEvent *ev) { QPoint e(ev->x() + mTimeline->GetOffset(), ev->y()); mTimeline->SetLayer(this); int frameIndex = GetFrameIndex(e.x(), e.y()); mState = EditorStateMove; this->grabMouse(); int n = (int)mLayerModel->GetFrames().size(); if (frameIndex >= 0) { int idx = 0; int i = 0; for (i = 0; i < n; ++i) { RasterFrameModel* frame = mLayerModel->GetFrames()[i]; int exposure = frame->GetExposure(); if (idx + exposure - 1 >= frameIndex) { break; } idx += exposure; } if (i < n) { RasterFrameModel* frame = mLayerModel->GetFrames()[i]; int xMax = (idx + frame->GetExposure()) * mTimeline->GetCellSize().width(); int xMin = xMax - mTimeline->GetCellSize().width() / 2; if (e.x() >= xMin && e.x() <= xMax) { mState = EditorStateScale; mEditFrame = GetFrameAt(frameIndex); mEditFrameIndex = frameIndex; mEditFrameExposure = mEditFrame->GetExposure(); } } } mTimeline->SetFrameIndex(frameIndex); }
// Reads a piece of screen into a passed FRAME or a newly created one DRAWABLE LoadDisplayPixmap (const RECT *area, FRAME frame) { // TODO: This should just return a FRAME instead of DRAWABLE DRAWABLE buffer = GetFrameParentDrawable (frame); COUNT index; if (!buffer) { // asked to create a new DRAWABLE instead buffer = CreateDrawable (WANT_PIXMAP | MAPPED_TO_DISPLAY, area->extent.width, area->extent.height, 1); if (!buffer) return NULL; index = 0; } else { index = GetFrameIndex (frame); } frame = SetAbsFrameIndex (CaptureDrawable (buffer), index); if (_CurFramePtr->Type != SCREEN_DRAWABLE || frame->Type == SCREEN_DRAWABLE || !(GetFrameParentDrawable (frame)->Flags & MAPPED_TO_DISPLAY)) { log_add (log_Warning, "Unimplemented function activated: " "LoadDisplayPixmap()"); } else { TFB_Image *img = frame->image; TFB_DrawScreen_CopyToImage (img, area, TFB_SCREEN_MAIN); } ReleaseDrawable (frame); return buffer; }
static void asteroid_preprocess (ELEMENT *ElementPtr) { if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { COUNT frame_index; frame_index = GetFrameIndex (ElementPtr->current.image.frame); if (ElementPtr->thrust_wait & (1 << 7)) --frame_index; else ++frame_index; ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->current.image.frame, NORMALIZE_FACING (frame_index)); ElementPtr->state_flags |= CHANGING; ElementPtr->turn_wait = (unsigned char)(ElementPtr->thrust_wait & ((1 << 7) - 1)); } }
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; } }
void CIntegralRotation::ReadFromStream (SLoadCtx &Ctx, const CIntegralRotationDesc &Desc) // ReadFromStream // // Reads data { DWORD dwLoad; Init(Desc); Ctx.pStream->Read((char *)&dwLoad, sizeof(DWORD)); m_iRotationFrame = (int)dwLoad; Ctx.pStream->Read((char *)&dwLoad, sizeof(DWORD)); m_iRotationSpeed = (int)dwLoad; // Make sure our frame is within bounds; this can change if the ship's // rotation count is altered in the XML. if (GetFrameIndex() >= Desc.GetFrameCount()) SetRotationAngle(Desc, 0); }
// 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); } }
void RasterLayer::mouseMoveEvent(QMouseEvent *ev) { QPoint e(ev->x() + mTimeline->GetOffset(), ev->y()); int frameIndex = GetFrameIndex(e.x(), e.y()); if (mState == EditorStateScale) { if (mEditFrame) { int exposure = mEditFrameExposure + (frameIndex - mEditFrameIndex); if (exposure < 1) { exposure = 1; } mEditFrame->SetExposure(exposure); update(); UpdateMaxFrames(); } } else { mTimeline->SetFrameIndex(frameIndex); } }
static void cannon_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1) { weapon_collision (ElementPtr0, pPt0, ElementPtr1, pPt1); if ((ElementPtr1->state_flags & PLAYER_SHIP) && ElementPtr1->crew_level && !GRAVITY_MASS (ElementPtr1->mass_points + 1)) { COUNT angle; SIZE cur_delta_x, cur_delta_y; STARSHIP *StarShipPtr; GetElementStarShip (ElementPtr1, &StarShipPtr); StarShipPtr->cur_status_flags &= ~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED); angle = FACING_TO_ANGLE ( GetFrameIndex (ElementPtr0->next.image.frame) ); DeltaVelocityComponents (&ElementPtr1->velocity, COSINE (angle, RECOIL_VELOCITY), SINE (angle, RECOIL_VELOCITY)); GetCurrentVelocityComponents (&ElementPtr1->velocity, &cur_delta_x, &cur_delta_y); if ((long)cur_delta_x * (long)cur_delta_x + (long)cur_delta_y * (long)cur_delta_y > (long)MAX_RECOIL_VELOCITY * (long)MAX_RECOIL_VELOCITY) { angle = ARCTAN (cur_delta_x, cur_delta_y); SetVelocityComponents (&ElementPtr1->velocity, COSINE (angle, MAX_RECOIL_VELOCITY), SINE (angle, MAX_RECOIL_VELOCITY)); } } }
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 butt_missile_preprocess (ELEMENT *ElementPtr) { if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { COUNT facing; facing = GetFrameIndex (ElementPtr->next.image.frame); if (TrackShip (ElementPtr, &facing) > 0) { ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->next.image.frame, facing); ElementPtr->state_flags |= CHANGING; SetVelocityVector (&ElementPtr->velocity, DISCRIMINATOR_SPEED, facing); } ElementPtr->turn_wait = TRACK_WAIT; } }
void RasterLayer::mouseDoubleClickEvent(QMouseEvent *e) { int frameIndex = GetFrameIndex(e->x() + mTimeline->GetOffset(), e->y()); AddFrame(frameIndex); }
static void butt_missile_preprocess (ELEMENT *ElementPtr) { if (ElementPtr->turn_wait > 0) --ElementPtr->turn_wait; else { COUNT facing; // COUNT num_frames; SIZE delta_x, delta_y, delta_facing; ELEMENT *EnemyPtr; facing = GetFrameIndex (ElementPtr->next.image.frame); if (ElementPtr->hTarget) { LockElement (ElementPtr->hTarget, &EnemyPtr); delta_x = EnemyPtr->current.location.x - ElementPtr->current.location.x; delta_x = WRAP_DELTA_X (delta_x); delta_y = EnemyPtr->current.location.y - ElementPtr->current.location.y; delta_y = WRAP_DELTA_Y (delta_y); /* num_frames = (square_root ((long)delta_x * delta_x + (long)delta_y * delta_y)) / DISCRIMINATOR_SPEED; if (num_frames == 0) num_frames = 1; GetNextVelocityComponents (&EnemyPtr->velocity, &delta_x, &delta_y, num_frames); // Lead the target by its apparent trajectory. delta_x = (EnemyPtr->current.location.x + (delta_x / 2)) - ElementPtr->current.location.x; delta_y = (EnemyPtr->current.location.y + (delta_y / 2)) - ElementPtr->current.location.y; */ delta_facing = NORMALIZE_FACING ( ANGLE_TO_FACING (ARCTAN (delta_x, delta_y)) - facing); if (delta_facing > 0 && !OBJECT_CLOAKED(EnemyPtr)) { if (delta_facing == ANGLE_TO_FACING (HALF_CIRCLE)) facing += (((BYTE)TFB_Random () & 1) << 1) - 1; else if (delta_facing < ANGLE_TO_FACING (HALF_CIRCLE)) ++facing; else --facing; } ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->next.image.frame, facing); ElementPtr->state_flags |= CHANGING; SetVelocityVector (&ElementPtr->velocity, DISCRIMINATOR_SPEED, facing); UnlockElement (ElementPtr->hTarget); } else if (TrackShip (ElementPtr, &facing) > 0) { ElementPtr->next.image.frame = SetAbsFrameIndex (ElementPtr->next.image.frame, facing); ElementPtr->state_flags |= CHANGING; SetVelocityVector (&ElementPtr->velocity, DISCRIMINATOR_SPEED, facing); } ElementPtr->turn_wait = TRACK_WAIT; } }
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); } }
EManeuverTypes CIntegralRotation::GetManeuverToFace (const CIntegralRotationDesc &Desc, int iAngle) const // GetManeuverToFace // // Returns the maneuver required to face the given angle (or NoRotation if we're // already facing in that (rough) direction). { // Convert to a frame index. NOTE: We figure out what our rotation would be // if we stopped thrusting right now. int iCurrentFrameIndex = GetFrameIndex(CalcFinalRotationFrame(Desc)); int iDesiredFrameIndex = Desc.GetFrameIndex(iAngle); // If we're going to be in the right spot by doing nothing, then just stop // rotating. if (iCurrentFrameIndex == iDesiredFrameIndex) return NoRotation; // Otherwise, figure out how many frames we need to turn (and the // direction). int iFrameDiff = ClockDiff(iDesiredFrameIndex, iCurrentFrameIndex, Desc.GetFrameCount()); // Are we turning right? int iNewRotationSpeed; int iMaxFrameRot = (Desc.GetMaxRotationSpeed() / CIntegralRotationDesc::ROTATION_FRACTION); if (iFrameDiff > 0) { // If we have a ways to go, then just turn if (iFrameDiff > iMaxFrameRot) return RotateRight; // Otherwise we need to calculate better. Figure out what our new // rotation speed will be if we turn right. iNewRotationSpeed = m_iRotationSpeed; if (iNewRotationSpeed < m_iMaxRotationRate) { if (iNewRotationSpeed < 0) iNewRotationSpeed = Min(m_iMaxRotationRate, iNewRotationSpeed + m_iRotationAccelStop); else iNewRotationSpeed = Min(m_iMaxRotationRate, iNewRotationSpeed + m_iRotationAccel); } } // Or left else { // If we have a ways to go, then just turn if (-iFrameDiff > iMaxFrameRot) return RotateLeft; // Otherwise we need a better calculation. Figure out what our new // rotation speed will be if we turn left. iNewRotationSpeed = m_iRotationSpeed; if (iNewRotationSpeed > -m_iMaxRotationRate) { if (iNewRotationSpeed > 0) iNewRotationSpeed = Max(-m_iMaxRotationRate, iNewRotationSpeed - m_iRotationAccelStop); else iNewRotationSpeed = Max(-m_iMaxRotationRate, iNewRotationSpeed - m_iRotationAccel); } } // Figure out where we will end up next tick given our new rotation speed. int iNewRotationFrame = m_iRotationFrame; int iFrameMax = Desc.GetFrameCount() * CIntegralRotationDesc::ROTATION_FRACTION; iNewRotationFrame = (iNewRotationFrame + iNewRotationSpeed) % iFrameMax; if (iNewRotationFrame < 0) iNewRotationFrame += iFrameMax; int iNewFrameIndex = GetFrameIndex(CalcFinalRotationFrame(iNewRotationFrame, iNewRotationSpeed, Desc)); int iNewFrameDiff = ClockDiff(iDesiredFrameIndex, iNewFrameIndex, Desc.GetFrameCount()); // If we're closer to the target, then do it. if (Absolute(iNewFrameDiff) < Absolute(iFrameDiff)) return (iFrameDiff < 0 ? RotateLeft : RotateRight); else return NoRotation; }
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 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); } }