示例#1
0
文件: druuge.c 项目: intgr/sc2-uqm
static void
druuge_postprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
			/* if just fired cannon */
	if ((StarShipPtr->cur_status_flags & WEAPON)
			&& StarShipPtr->weapon_counter ==
			StarShipPtr->RaceDescPtr->characteristics.weapon_wait)
	{
		COUNT angle;
		SIZE cur_delta_x, cur_delta_y;

		StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED;

		angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE;
		DeltaVelocityComponents (&ElementPtr->velocity,
				COSINE (angle, RECOIL_VELOCITY),
				SINE (angle, RECOIL_VELOCITY));
		GetCurrentVelocityComponents (&ElementPtr->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 (&ElementPtr->velocity,
					COSINE (angle, MAX_RECOIL_VELOCITY),
					SINE (angle, MAX_RECOIL_VELOCITY));
		}
	}
}
示例#2
0
static void
decelerate_preprocess (ELEMENT *ElementPtr)
{
	SIZE dx, dy;

	GetCurrentVelocityComponents (&ElementPtr->velocity, &dx, &dy);
	dx /= 2;
	dy /= 2;
	SetVelocityComponents (&ElementPtr->velocity, dx, dy);
	if (dx == 0 && dy == 0)
	{
		ElementPtr->preprocess_func = buzztrack_preprocess;
	}

	spin_preprocess (ElementPtr);
}
示例#3
0
文件: druuge.c 项目: intgr/sc2-uqm
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));
		}
	}
}
示例#4
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;
    }
}
示例#5
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);
	}
}
示例#6
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;
    }
}
示例#7
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);
}
示例#8
0
static COUNT
initialize_flak (ELEMENT *ShipPtr, HELEMENT MissileArray[])
{
	COUNT i;
	STARSHIP *StarShipPtr;
	MISSILE_BLOCK MissileBlock;
	
	GetElementStarShip (ShipPtr, &StarShipPtr);
	MissileBlock.cx = ShipPtr->next.location.x;
	MissileBlock.cy = ShipPtr->next.location.y;
	MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon;
	MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing;
	MissileBlock.sender = ShipPtr->playerNr;
	MissileBlock.flags = IGNORE_SIMILAR;
	MissileBlock.pixoffs = SPATHI_FORWARD_OFFSET;
	MissileBlock.speed = (MISSILE_SPEED << RESOLUTION_FACTOR);
	MissileBlock.hit_points = MISSILE_HITS;
	MissileBlock.damage = MISSILE_DAMAGE;
	MissileBlock.life = MISSILE_LIFE;
	MissileBlock.preprocess_func = flak_preprocess;
	MissileBlock.blast_offs = MISSILE_OFFSET;

	for(i = 0; i < 3; ++i)
	{
		if (i == 0)
		{
			MissileBlock.cx = ShipPtr->next.location.x;
			MissileBlock.cy = ShipPtr->next.location.y;
		}
		else if (i == 1)
		{
			MissileBlock.cx = ShipPtr->next.location.x
				+ COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 12);
			MissileBlock.cy = ShipPtr->next.location.y
				+ SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 12);
		}
		else if (i == 2)
		{
			MissileBlock.cx = ShipPtr->next.location.x
				+ COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -12);
			MissileBlock.cy = ShipPtr->next.location.y
				+ SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -12);
		}
		
		if ((MissileArray[i] = initialize_missile (&MissileBlock)))
		{
			SIZE dx, dy, angle, speed;
			ELEMENT *MissilePtr;

			LockElement (MissileArray[i], &MissilePtr);

			if (i > 0)
			{
				angle = GetVelocityTravelAngle (&MissilePtr->velocity);
				GetCurrentVelocityComponents(&MissilePtr->velocity, &dx, &dy);
				speed = square_root (dx*dx + dy*dy);

				if (i == 1)
					angle += 1;
				else if (i == 2)
					angle -= 1;

				SetVelocityComponents(&MissilePtr->velocity, COSINE(angle, speed), SINE(angle, speed));
			}

			GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);

			// Add the Eluder's velocity to its projectiles.
			DeltaVelocityComponents (&MissilePtr->velocity, dx, dy);
			MissilePtr->current.location.x -= VELOCITY_TO_WORLD (dx);
			MissilePtr->current.location.y -= VELOCITY_TO_WORLD (dy);

			MissilePtr->turn_wait = 1;

			UnlockElement (MissileArray[i]);
		}
	}

	return (3);
}