Пример #1
0
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;
		}
	}
}
Пример #2
0
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);
}
Пример #3
0
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);
	}
}
Пример #4
0
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;
    }
}
Пример #5
0
int CIntegralRotation::GetRotationAngle (const CIntegralRotationDesc &Desc) const

//	GetRotationAngle
//
//	Converts from our rotation frame to an angle

	{
	return Desc.GetRotationAngle(GetFrameIndex(m_iRotationFrame));
	}
Пример #6
0
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);
    }
}
Пример #7
0
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);
	}
}
Пример #8
0
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);
	}
}
Пример #9
0
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);
}
Пример #10
0
// 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;
}
Пример #11
0
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));
	}
}
Пример #12
0
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;
	}
}
Пример #13
0
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);
	}
Пример #14
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);
	}
}
Пример #15
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);
    }
}
Пример #16
0
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));
		}
	}
}
Пример #17
0
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;
	}
}
Пример #18
0
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;
	}
}
Пример #19
0
void RasterLayer::mouseDoubleClickEvent(QMouseEvent *e)
{
    int frameIndex = GetFrameIndex(e->x() + mTimeline->GetOffset(), e->y());
    AddFrame(frameIndex);
}
Пример #20
0
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;
	}
}
Пример #21
0
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);
	}
}
Пример #22
0
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;
	}
Пример #23
0
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;
    }
}
Пример #24
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);
    }
}