static void
flak_preprocess (ELEMENT *ElementPtr)
{
	if (ElementPtr->turn_wait > 0)
		--ElementPtr->turn_wait;
	else
	{
		SIZE angle, delta_speed;

		angle = GetVelocityTravelAngle (&ElementPtr->velocity);
		delta_speed = WORLD_TO_VELOCITY (MISSILE_DECELERATION);

		DeltaVelocityComponents (&ElementPtr->velocity,
			(SIZE)COSINE (angle, -delta_speed),
			(SIZE)SINE (angle, -delta_speed));
	
		ElementPtr->turn_wait = MISSILE_DECEL_WAIT;
		ElementPtr->state_flags |= CHANGING;
	}
}
Example #2
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;
    }
}
Example #3
0
static void
sis_hyper_preprocess (ELEMENT *ElementPtr)
{
    SIZE udx, udy, dx, dy;
    SIZE AccelerateDirection;
    STARSHIP *StarShipPtr;

    if (ElementPtr->state_flags & APPEARING)
        ElementPtr->velocity = GLOBAL (velocity);

    AccelerateDirection = 0;

    GetElementStarShip (ElementPtr, &StarShipPtr);
    ++StarShipPtr->weapon_counter; /* no shooting in hyperspace! */
    if ((GLOBAL (autopilot)).x == ~0
            || (GLOBAL (autopilot)).y == ~0
            || (StarShipPtr->cur_status_flags & (LEFT | RIGHT | THRUST)))
    {
LeaveAutoPilot:
        (GLOBAL (autopilot)).x =
            (GLOBAL (autopilot)).y = ~0;
        if (!(StarShipPtr->cur_status_flags & THRUST)
                || (GLOBAL_SIS (FuelOnBoard) == 0
                    && GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1))
        {
            AccelerateDirection = -1;
            GetCurrentVelocityComponents (&ElementPtr->velocity,
                                          &dx, &dy);
            udx = dx << 4;
            udy = dy << 4;

            StarShipPtr->cur_status_flags &= ~THRUST;
        }
    }
    else
    {
        SIZE facing;
        POINT universe;

        universe.x = LOGX_TO_UNIVERSE (GLOBAL_SIS (log_x));
        universe.y = LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y));
        udx = (GLOBAL (autopilot)).x - universe.x;
        udy = -((GLOBAL (autopilot)).y - universe.y);
        if ((dx = udx) < 0)
            dx = -dx;
        if ((dy = udy) < 0)
            dy = -dy;
        if (dx <= 1 && dy <= 1)
            goto LeaveAutoPilot;

        facing = NORMALIZE_FACING (ANGLE_TO_FACING (ARCTAN (udx, udy)));

        /* This prevents ship from flying backwards on auto-pilot.
         * It could also theoretically abort autopilot in a bad savegame */
        if ((StarShipPtr->cur_status_flags & SHIP_AT_MAX_SPEED)
                /*|| (ElementPtr->state_flags & APPEARING)*/ )
        {
            if (NORMALIZE_FACING (StarShipPtr->ShipFacing
                                  + ANGLE_TO_FACING (QUADRANT)
                                  - facing) > ANGLE_TO_FACING (HALF_CIRCLE))
                goto LeaveAutoPilot;

            facing = StarShipPtr->ShipFacing;
        }
        else if ((int)facing != (int)StarShipPtr->ShipFacing
                 && ElementPtr->turn_wait == 0)
        {
            if (NORMALIZE_FACING (
                        StarShipPtr->ShipFacing - facing
                    ) >= ANGLE_TO_FACING (HALF_CIRCLE))
            {
                facing = NORMALIZE_FACING (facing - 1);
                StarShipPtr->cur_status_flags |= RIGHT;
            }
            else if ((int)StarShipPtr->ShipFacing != (int)facing)
            {
                facing = NORMALIZE_FACING (facing + 1);
                StarShipPtr->cur_status_flags |= LEFT;
            }

            if ((int)facing == (int)StarShipPtr->ShipFacing)
            {
                ZeroVelocityComponents (&ElementPtr->velocity);
            }
        }

        GetCurrentVelocityComponents (&ElementPtr->velocity, &dx, &dy);
        if ((GLOBAL_SIS (FuelOnBoard)
                || GET_GAME_STATE (ARILOU_SPACE_SIDE) > 1)
                && (int)facing == (int)StarShipPtr->ShipFacing)
        {
            StarShipPtr->cur_status_flags |= SHIP_AT_MAX_SPEED;
            AccelerateDirection = 1;
        }
        else
        {
            AccelerateDirection = -1;
            udx = dx << 4;
            udy = dy << 4;
        }
    }

    if (ElementPtr->thrust_wait == 0 && AccelerateDirection)
    {
        COUNT dist;
        SIZE speed, velocity_increment;

        velocity_increment = WORLD_TO_VELOCITY (
                                 StarShipPtr->RaceDescPtr->characteristics.thrust_increment);

        if ((dist = square_root ((long)udx * udx + (long)udy * udy)) == 0)
            dist = 1; /* prevent divide by zero */

        speed = square_root ((long)dx * dx + (long)dy * dy);
        if (AccelerateDirection < 0)
        {
            dy = (speed / velocity_increment - 1) * velocity_increment;
            if (dy < speed - velocity_increment)
                dy = speed - velocity_increment;
            if ((speed = dy) < 0)
                speed = 0;

            StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED;
        }
        else
        {
            SIZE max_velocity;

            AccelerateDirection = 0;

            max_velocity = WORLD_TO_VELOCITY (
                               StarShipPtr->RaceDescPtr->characteristics.max_thrust);

            dy = (speed / velocity_increment + 1)
                 * velocity_increment;
            if (dy < speed + velocity_increment)
                dy = speed + velocity_increment;
            if ((speed = dy) > max_velocity)
            {
                speed = max_velocity;
                StarShipPtr->cur_status_flags |= SHIP_AT_MAX_SPEED;
            }
        }

        dx = (SIZE)((long)udx * speed / (long)dist);
        dy = (SIZE)((long)udy * speed / (long)dist);
        SetVelocityComponents (&ElementPtr->velocity, dx, dy);

        ElementPtr->thrust_wait =
            StarShipPtr->RaceDescPtr->characteristics.thrust_wait;
    }
}
Example #4
0
static void
explosion_preprocess (ELEMENT *ShipPtr)
{
	BYTE i;

	i = (NUM_EXPLOSION_FRAMES * 3) - ShipPtr->life_span;
	switch (i)
	{
		case 25:
			ShipPtr->preprocess_func = NULL;
		case 0:
		case 1:
		case 2:
		case 20:
		case 21:
		case 22:
		case 23:
		case 24:
			i = 1;
			break;
		case 3:
		case 4:
		case 5:
		case 18:
		case 19:
			i = 2;
			break;
		case 15:
			SetPrimType (&DisplayArray[ShipPtr->PrimIndex], NO_PRIM);
			ShipPtr->state_flags |= CHANGING;
		default:
			i = 3;
			break;
	}

	do
	{
		HELEMENT hElement;

		hElement = AllocElement ();
		if (hElement)
		{
			COUNT angle, dist;
			DWORD rand_val;
			ELEMENT *ElementPtr;
			extern FRAME explosion[];

			PutElement (hElement);
			LockElement (hElement, &ElementPtr);
			ElementPtr->playerNr = NEUTRAL_PLAYER_NUM;
			ElementPtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID;
			ElementPtr->life_span = 9;
			SetPrimType (&DisplayArray[ElementPtr->PrimIndex], STAMP_PRIM);
			ElementPtr->current.image.farray = explosion;
			ElementPtr->current.image.frame = explosion[0];
			rand_val = TFB_Random ();
			angle = LOBYTE (HIWORD (rand_val));
			dist = DISPLAY_TO_WORLD (LOBYTE (LOWORD (rand_val)) % 8);
			if (HIBYTE (LOWORD (rand_val)) < 256 * 1 / 3)
				dist += DISPLAY_TO_WORLD (8);
			ElementPtr->current.location.x =
					ShipPtr->current.location.x + COSINE (angle, dist);
			ElementPtr->current.location.y =
					ShipPtr->current.location.y + SINE (angle, dist);
			ElementPtr->preprocess_func = animation_preprocess;
			rand_val = TFB_Random ();
			angle = LOBYTE (LOWORD (rand_val));
			dist = WORLD_TO_VELOCITY (
					DISPLAY_TO_WORLD (HIBYTE (LOWORD (rand_val)) % 5));
			SetVelocityComponents (&ElementPtr->velocity,
					COSINE (angle, dist), SINE (angle, dist));
			UnlockElement (hElement);
		}
	} while (--i);
}
Example #5
0
BOOLEAN
CalculateGravity (ELEMENT *ElementPtr)
{
	BOOLEAN retval, HasGravity;
	HELEMENT hTestElement, hSuccElement;

	retval = FALSE;
	HasGravity = (BOOLEAN)(CollidingElement (ElementPtr)
			&& GRAVITY_MASS (ElementPtr->mass_points + 1));
	for (hTestElement = GetHeadElement ();
			hTestElement != 0; hTestElement = hSuccElement)
	{
		BOOLEAN TestHasGravity;
		ELEMENT *TestElementPtr;

		LockElement (hTestElement, &TestElementPtr);
		if (TestElementPtr != ElementPtr
				&& CollidingElement (TestElementPtr)
				&& (TestHasGravity =
				GRAVITY_MASS (TestElementPtr->mass_points + 1)) != HasGravity)
		{
			COUNT abs_dx, abs_dy;
			SIZE dx, dy;

			if (!(ElementPtr->state_flags & PRE_PROCESS))
			{
				dx = ElementPtr->current.location.x
						- TestElementPtr->current.location.x;
				dy = ElementPtr->current.location.y
						- TestElementPtr->current.location.y;
			}
			else
			{
				dx = ElementPtr->next.location.x
						- TestElementPtr->next.location.x;
				dy = ElementPtr->next.location.y
						- TestElementPtr->next.location.y;
			}
#ifdef DEBUG_GRAVITY
			if (TestElementPtr->state_flags & PLAYER_SHIP)
			{
				log_add (log_Debug, "CalculateGravity:");
				log_add (log_Debug, "\tdx = %d, dy = %d", dx, dy);
			}
#endif /* DEBUG_GRAVITY */
			dx = WRAP_DELTA_X (dx);
			dy = WRAP_DELTA_Y (dy);
#ifdef DEBUG_GRAVITY
			if (TestElementPtr->state_flags & PLAYER_SHIP)
				log_add (log_Debug, "\twrap_dx = %d, wrap_dy = %d", dx, dy);
#endif /* DEBUG_GRAVITY */
			abs_dx = dx >= 0 ? dx : -dx;
			abs_dy = dy >= 0 ? dy : -dy;
			abs_dx = WORLD_TO_DISPLAY (abs_dx);
			abs_dy = WORLD_TO_DISPLAY (abs_dy);
#ifdef DEBUG_GRAVITY
			if (TestElementPtr->state_flags & PLAYER_SHIP)
				log_add (log_Debug, "\tdisplay_dx = %d, display_dy = %d",
						abs_dx, abs_dy);
#endif /* DEBUG_GRAVITY */
			if (abs_dx <= GRAVITY_THRESHOLD
					&& abs_dy <= GRAVITY_THRESHOLD)
			{
				DWORD dist_squared;

				dist_squared = (DWORD)(abs_dx * abs_dx)
						+ (DWORD)(abs_dy * abs_dy);
				if (dist_squared <= (DWORD)(GRAVITY_THRESHOLD
						* GRAVITY_THRESHOLD))
				{
#ifdef NEVER
					COUNT magnitude;

#define DIFUSE_GRAVITY RES_SCALE(175) // JMS_GFX: Because of the ifdef NEVER this is actually never run. Well, changed it for consistency
					dist_squared += (DWORD)abs_dx * (DIFUSE_GRAVITY << 1)
							+ (DWORD)abs_dy * (DIFUSE_GRAVITY << 1)
							+ ((DWORD)(DIFUSE_GRAVITY * DIFUSE_GRAVITY) << 1);
					if ((magnitude = (COUNT)((DWORD)(GRAVITY_THRESHOLD
							* GRAVITY_THRESHOLD) / dist_squared)) == 0)
						magnitude = 1;

#define MAX_MAGNITUDE RES_SCALE(6) // JMS_GFX: Because of the ifdef NEVER this is actually never run. Well, changed it for consistency
					else if (magnitude > MAX_MAGNITUDE)
						magnitude = MAX_MAGNITUDE;
					log_add (log_Debug, "magnitude = %u", magnitude);
#endif /* NEVER */

#ifdef DEBUG_GRAVITY
					if (TestElementPtr->state_flags & PLAYER_SHIP)
						log_add (log_Debug, "dist_squared = %lu", dist_squared);
#endif /* DEBUG_GRAVITY */
					if (TestHasGravity)
					{
						retval = TRUE;
						UnlockElement (hTestElement);
						break;
					}
					else
					{
						COUNT angle;

						angle = ARCTAN (dx, dy);
						DeltaVelocityComponents (&TestElementPtr->velocity,
								COSINE (angle, WORLD_TO_VELOCITY (RES_SCALE(1))),
								SINE (angle, WORLD_TO_VELOCITY (RES_SCALE(1)))); // JMS_GFX
						if (TestElementPtr->state_flags & PLAYER_SHIP)
						{
							STARSHIP *StarShipPtr;

							GetElementStarShip (TestElementPtr, &StarShipPtr);
							StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED;
							StarShipPtr->cur_status_flags |= SHIP_IN_GRAVITY_WELL;
						}
					}
				}
			}
		}

		hSuccElement = GetSuccElement (TestElementPtr);
		UnlockElement (hTestElement);
	}

	return (retval);
}