Exemple #1
0
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));
		}
	}
}
Exemple #2
0
static COUNT
initialize_bug_missile (ELEMENT *ShipPtr, HELEMENT MissileArray[])
{
#define PKUNK_OFFSET 15
#define MISSILE_HITS 1
#define MISSILE_DAMAGE 1
#define MISSILE_OFFSET 1
	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.index = 0;
	MissileBlock.sender = ShipPtr->playerNr;
	MissileBlock.flags = IGNORE_SIMILAR;
	MissileBlock.pixoffs = PKUNK_OFFSET;
	MissileBlock.speed = MISSILE_SPEED;
	MissileBlock.hit_points = MISSILE_HITS;
	MissileBlock.damage = MISSILE_DAMAGE;
	MissileBlock.life = MISSILE_LIFE;
	MissileBlock.preprocess_func = NULL;
	MissileBlock.blast_offs = MISSILE_OFFSET;

	for (i = 0; i < 3; ++i)
	{
		MissileBlock.face =
				StarShipPtr->ShipFacing
				+ (ANGLE_TO_FACING (QUADRANT) * i);
		if (i == 2)
			MissileBlock.face += ANGLE_TO_FACING (QUADRANT);
		MissileBlock.face = NORMALIZE_FACING (MissileBlock.face);

		if ((MissileArray[i] = initialize_missile (&MissileBlock)))
		{
			SIZE dx, dy;
			ELEMENT *MissilePtr;

			LockElement (MissileArray[i], &MissilePtr);
			GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);
			DeltaVelocityComponents (&MissilePtr->velocity, dx, dy);
			MissilePtr->current.location.x -= VELOCITY_TO_WORLD (dx);
			MissilePtr->current.location.y -= VELOCITY_TO_WORLD (dy);

			MissilePtr->preprocess_func = animate;
			UnlockElement (MissileArray[i]);
		}
	}

	return (3);
}
Exemple #3
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);
}
Exemple #4
0
static COUNT
initialize_flame (PELEMENT ShipPtr, HELEMENT FlameArray[])
{
#define ILWRATH_OFFSET 29
#define MISSILE_SPEED MAX_THRUST
#define MISSILE_HITS 1
#define MISSILE_DAMAGE 1
#define MISSILE_OFFSET 0
	STARSHIPPTR 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 = StarShipPtr->ShipFacing;
	MissileBlock.index = 0;
	MissileBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY))
			| IGNORE_SIMILAR;
	MissileBlock.pixoffs = ILWRATH_OFFSET;
	MissileBlock.speed = MISSILE_SPEED;
	MissileBlock.hit_points = MISSILE_HITS;
	MissileBlock.damage = MISSILE_DAMAGE;
	MissileBlock.life = MISSILE_LIFE;
	MissileBlock.preprocess_func = flame_preprocess;
	MissileBlock.blast_offs = MISSILE_OFFSET;
	FlameArray[0] = initialize_missile (&MissileBlock);

	if (FlameArray[0])
	{
		SIZE dx, dy;
		ELEMENTPTR FlamePtr;

		LockElement (FlameArray[0], &FlamePtr);
		GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);
		DeltaVelocityComponents (&FlamePtr->velocity, dx, dy);
		FlamePtr->current.location.x -= VELOCITY_TO_WORLD (dx);
		FlamePtr->current.location.y -= VELOCITY_TO_WORLD (dy);

		FlamePtr->collision_func = flame_collision;
		FlamePtr->turn_wait = 0;
		UnlockElement (FlameArray[0]);
	}

	return (1);
}
static COUNT
initialize_cannon (ELEMENT *ShipPtr, HELEMENT CannonArray[])
{
	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 = StarShipPtr->ShipFacing;
	MissileBlock.index = MissileBlock.face;
	MissileBlock.sender = ShipPtr->playerNr;
	MissileBlock.flags = IGNORE_SIMILAR;
	MissileBlock.pixoffs = DRUUGE_OFFSET;
	MissileBlock.speed = (MISSILE_SPEED << RESOLUTION_FACTOR); 
	MissileBlock.hit_points = MISSILE_HITS;
	MissileBlock.damage = MISSILE_DAMAGE;
	MissileBlock.life = MISSILE_LIFE;
	MissileBlock.preprocess_func = NULL;
	MissileBlock.blast_offs = MISSILE_OFFSET;
	CannonArray[0] = initialize_missile (&MissileBlock);
	
	if (CannonArray[0])
	{
		SIZE dx, dy;
		ELEMENT *CannonPtr;

		LockElement (CannonArray[0], &CannonPtr);

		CannonPtr->collision_func = cannon_collision;
		
		GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);
		dx = dx * 1/2;
		dy = dy * 1/2;

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

		UnlockElement (CannonArray[0]);
	}

	return (1);
}
static COUNT
initialize_test_pump_up (ELEMENT *ShipPtr, HELEMENT PumpUpArray[])
{
    STARSHIP *StarShipPtr;
    MISSILE_BLOCK MissileBlock;
    //ELEMENT *PumpUpPtr;

    GetElementStarShip (ShipPtr, &StarShipPtr);
    MissileBlock.cx = ShipPtr->next.location.x;
    MissileBlock.cy = ShipPtr->next.location.y;
    MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon;
    MissileBlock.face = StarShipPtr->ShipFacing;
    MissileBlock.index = 0;
    MissileBlock.sender = ShipPtr->playerNr;
    MissileBlock.flags = IGNORE_SIMILAR;
    MissileBlock.pixoffs = MELNORME_OFFSET;
    MissileBlock.speed = PUMPUP_SPEED;
    MissileBlock.hit_points = PUMPUP_DAMAGE;
    MissileBlock.damage = PUMPUP_DAMAGE;
    MissileBlock.life = PUMPUP_LIFE;
    MissileBlock.preprocess_func = 0;
    MissileBlock.blast_offs = 0;
    PumpUpArray[0] = initialize_missile (&MissileBlock);

    if (PumpUpArray[0])
    {
        SIZE dx, dy;
        ELEMENT *MissilePtr;

        LockElement (PumpUpArray[0], &MissilePtr);

        GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);
        dx = dx * 1/2;
        dy = dy * 1/2;

        // Add some of the Trader'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);

        UnlockElement (PumpUpArray[0]);
    }

    return (1);
}
static COUNT
initialize_confusion (ELEMENT *ShipPtr, HELEMENT ConfusionArray[])
{
    STARSHIP *StarShipPtr;
    MISSILE_BLOCK ConfusionBlock;

    GetElementStarShip (ShipPtr, &StarShipPtr);
    ConfusionBlock.cx = ShipPtr->next.location.x;
    ConfusionBlock.cy = ShipPtr->next.location.y;
    ConfusionBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special;
    ConfusionBlock.index = 0;
    ConfusionBlock.face = StarShipPtr->ShipFacing;
    ConfusionBlock.sender = ShipPtr->playerNr;
    ConfusionBlock.flags = IGNORE_SIMILAR;
    ConfusionBlock.pixoffs = MELNORME_OFFSET;
    ConfusionBlock.speed = CMISSILE_SPEED;
    ConfusionBlock.hit_points = CMISSILE_HITS;
    ConfusionBlock.damage = CMISSILE_DAMAGE;
    ConfusionBlock.life = CMISSILE_LIFE;
    ConfusionBlock.preprocess_func = confuse_preprocess;
    ConfusionBlock.blast_offs = CMISSILE_OFFSET;
    ConfusionArray[0] = initialize_missile (&ConfusionBlock);

    if (ConfusionArray[0])
    {
        ELEMENT *CMissilePtr;
        SIZE dx,dy;

        LockElement (ConfusionArray[0], &CMissilePtr);
        CMissilePtr->collision_func = confusion_collision;
        SetElementStarShip (CMissilePtr, StarShipPtr);

        GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);
        dx = dx * 3/4;
        dy = dy * 3/4;

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

        UnlockElement (ConfusionArray[0]);
    }
    return (1);
}
Exemple #8
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));
		}
	}
}
Exemple #9
0
static void
androsynth_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	EVALUATE_DESC *lpEvalDesc;
	STARSHIP *StarShipPtr;

	GetElementStarShip (ShipPtr, &StarShipPtr);

	lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
				/* in blazer form */
	if (ShipPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special)
	{
		ObjectsOfConcern[CREW_OBJECT_INDEX].ObjectPtr = 0;
		if (lpEvalDesc->ObjectPtr && lpEvalDesc->MoveState == ENTICE)
		{
			if ((lpEvalDesc->ObjectPtr->state_flags & FINITE_LIFE)
					&& !(lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT))
				lpEvalDesc->MoveState = AVOID;
			else
				lpEvalDesc->ObjectPtr = 0;
		}

		ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);
	}
	else
	{
		STARSHIP *pEnemyStarShip = NULL;

		lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
		if (lpEvalDesc->ObjectPtr)
		{
			GetElementStarShip (lpEvalDesc->ObjectPtr, &pEnemyStarShip);
			// JMS_GFX
			if (lpEvalDesc->which_turn <= 16
					&& (StarShipPtr->special_counter > 0
					|| StarShipPtr->RaceDescPtr->ship_info.energy_level < MAX_ENERGY / 3
					|| ((WEAPON_RANGE (&pEnemyStarShip->RaceDescPtr->cyborg_control) <= (CLOSE_RANGE_WEAPON << RESOLUTION_FACTOR)
					&& lpEvalDesc->ObjectPtr->crew_level > BLAZER_DAMAGE)
					|| (lpEvalDesc->ObjectPtr->crew_level > (BLAZER_DAMAGE * 3)
					&& MANEUVERABILITY (&pEnemyStarShip->RaceDescPtr->cyborg_control) > SLOW_SHIP))))
				lpEvalDesc->MoveState = ENTICE;
		}

		ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

		if (StarShipPtr->special_counter == 0)
		{
			StarShipPtr->ship_input_state &= ~SPECIAL;
			// JMS_GFX
			if ((ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr
					&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].which_turn <= 4)
					|| (lpEvalDesc->ObjectPtr
					&& StarShipPtr->RaceDescPtr->ship_info.energy_level >= MAX_ENERGY / 3
					&& (WEAPON_RANGE (&pEnemyStarShip->RaceDescPtr->cyborg_control) >=
					WEAPON_RANGE (&StarShipPtr->RaceDescPtr->cyborg_control) << 1
					|| (lpEvalDesc->which_turn < 16
					&& (WEAPON_RANGE (&pEnemyStarShip->RaceDescPtr->cyborg_control) > (CLOSE_RANGE_WEAPON << RESOLUTION_FACTOR)
					|| lpEvalDesc->ObjectPtr->crew_level <= BLAZER_DAMAGE)
					&& (lpEvalDesc->ObjectPtr->crew_level <= (BLAZER_DAMAGE * 3)
					|| MANEUVERABILITY (&pEnemyStarShip->RaceDescPtr->cyborg_control) <=
					SLOW_SHIP)))))
				StarShipPtr->ship_input_state |= SPECIAL;
		}

		if (!(StarShipPtr->ship_input_state & SPECIAL)
				&& StarShipPtr->weapon_counter == 0
				&& lpEvalDesc->ObjectPtr)
		{
			if (lpEvalDesc->which_turn <= 4)
				StarShipPtr->ship_input_state |= WEAPON;
			else if (lpEvalDesc->MoveState != PURSUE
					&& lpEvalDesc->which_turn <= 12)
			{
				COUNT travel_facing, direction_facing;
				SIZE delta_x, delta_y,
							ship_delta_x, ship_delta_y,
							other_delta_x, other_delta_y;

				GetCurrentVelocityComponents (&ShipPtr->velocity,
						&ship_delta_x, &ship_delta_y);
				GetCurrentVelocityComponents (&lpEvalDesc->ObjectPtr->velocity,
						&other_delta_x, &other_delta_y);
				delta_x = ship_delta_x - other_delta_x;
				delta_y = ship_delta_y - other_delta_y;
				travel_facing = ARCTAN (delta_x, delta_y);

				delta_x =
						lpEvalDesc->ObjectPtr->next.location.x -
						ShipPtr->next.location.x;
				delta_y =
						lpEvalDesc->ObjectPtr->next.location.y -
						ShipPtr->next.location.y;
				direction_facing = ARCTAN (delta_x, delta_y);

				if (NORMALIZE_ANGLE (travel_facing
						- direction_facing + OCTANT) <= QUADRANT)
					StarShipPtr->ship_input_state |= WEAPON;
			}
		}
	}
}
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);
}
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;
    }
}
Exemple #12
0
static void
mmrnmhrm_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	BOOLEAN CanTransform;
	EVALUATE_DESC *lpEvalDesc;
	STARSHIP *StarShipPtr;
	STARSHIP *EnemyStarShipPtr;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	CanTransform = (BOOLEAN)(StarShipPtr->special_counter == 0
			&& StarShipPtr->RaceDescPtr->ship_info.energy_level >=
			StarShipPtr->RaceDescPtr->characteristics.special_energy_cost);

	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (lpEvalDesc->ObjectPtr)
	{
		GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr);
	}

	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	StarShipPtr->ship_input_state &= ~SPECIAL;
	if (CanTransform
			&& lpEvalDesc->ObjectPtr
			&& !(StarShipPtr->ship_input_state & WEAPON))
	{
		SIZE delta_x, delta_y;
		COUNT travel_angle, direction_angle;

		GetCurrentVelocityComponents (&lpEvalDesc->ObjectPtr->velocity,
				&delta_x, &delta_y);
		if (delta_x == 0 && delta_y == 0)
			direction_angle = travel_angle = 0;
		else
		{
			delta_x = lpEvalDesc->ObjectPtr->current.location.x
					- ShipPtr->current.location.x;
			delta_y = lpEvalDesc->ObjectPtr->current.location.y
					- ShipPtr->current.location.y;
			direction_angle = ARCTAN (-delta_x, -delta_y);
			travel_angle = GetVelocityTravelAngle (
					&lpEvalDesc->ObjectPtr->velocity
					);
		}

		if (ShipPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.ship)
		{
			if (lpEvalDesc->which_turn > 8)
			{
				if (MANEUVERABILITY (&EnemyStarShipPtr->RaceDescPtr->cyborg_control) <= SLOW_SHIP
						|| NORMALIZE_ANGLE (
								direction_angle - travel_angle + QUADRANT
								) > HALF_CIRCLE)
					StarShipPtr->ship_input_state |= SPECIAL;
			}
		}
		else
		{
			SIZE ship_delta_x, ship_delta_y;

			GetCurrentVelocityComponents (&ShipPtr->velocity,
					&ship_delta_x, &ship_delta_y);
			delta_x -= ship_delta_x;
			delta_y -= ship_delta_y;
			travel_angle = ARCTAN (delta_x, delta_y);
			if (lpEvalDesc->which_turn < 16)
			{
				if (lpEvalDesc->which_turn <= 8
						|| NORMALIZE_ANGLE (
								direction_angle - travel_angle + OCTANT
								) <= QUADRANT)
					StarShipPtr->ship_input_state |= SPECIAL;
			}
			else if (lpEvalDesc->which_turn > 32
					&& NORMALIZE_ANGLE (
							direction_angle - travel_angle + QUADRANT
							) > HALF_CIRCLE)
				StarShipPtr->ship_input_state |= SPECIAL;
		}
	}

	if (ShipPtr->current.image.farray == StarShipPtr->RaceDescPtr->ship_data.special)
	{
		if (!(StarShipPtr->ship_input_state & SPECIAL)
				&& lpEvalDesc->ObjectPtr)
			StarShipPtr->ship_input_state |= WEAPON;
		else
			StarShipPtr->ship_input_state &= ~WEAPON;
	}
}
static void
initialize_diagonal_flame (ELEMENT *ElementPtr)
{
	COUNT i;
	STARSHIP *StarShipPtr;
	MISSILE_BLOCK MissileBlock;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon;
	MissileBlock.index = 0;
	MissileBlock.sender = ElementPtr->playerNr;
	MissileBlock.flags = IGNORE_SIMILAR;
	MissileBlock.pixoffs = ILWRATH_OFFSET;
	MissileBlock.speed = MISSILE_SPEED;
	MissileBlock.hit_points = MISSILE_HITS;
	MissileBlock.damage = MISSILE_DAMAGE;
	MissileBlock.life = MISSILE_LIFE;
	MissileBlock.preprocess_func = flame_preprocess;
	MissileBlock.blast_offs = MISSILE_OFFSET;

	for(i = 0; i < 2; ++i)
	{
		HELEMENT hFlame;
	
		if (i == 0)
		{
			MissileBlock.cx = ElementPtr->next.location.x
				+ COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -32);
			MissileBlock.cy = ElementPtr->next.location.y
				+ SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), -32);

			MissileBlock.face = NORMALIZE_FACING (StarShipPtr->ShipFacing + 2);
		}
		else
		{
			MissileBlock.cx = ElementPtr->next.location.x
				+ COSINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 32);
			MissileBlock.cy = ElementPtr->next.location.y
				+ SINE(FACING_TO_ANGLE(StarShipPtr->ShipFacing + 4), 32);

			MissileBlock.face = NORMALIZE_FACING (StarShipPtr->ShipFacing - 2);
		}

		hFlame = initialize_missile (&MissileBlock);
		if (hFlame)
		{
			SIZE dx, dy;
			ELEMENT *FlamePtr;
	
			LockElement (hFlame, &FlamePtr);
			SetElementStarShip (FlamePtr, StarShipPtr);
			FlamePtr->hTarget = 0;
			GetCurrentVelocityComponents (&ElementPtr->velocity, &dx, &dy);
			DeltaVelocityComponents (&FlamePtr->velocity, dx, dy);
			FlamePtr->current.location.x -= VELOCITY_TO_WORLD (dx);
			FlamePtr->current.location.y -= VELOCITY_TO_WORLD (dy);
	
			FlamePtr->collision_func = flame_collision;
			FlamePtr->turn_wait = 0;
			UnlockElement (hFlame);
			PutElement (hFlame);
		}
	}
}
Exemple #14
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;
    }
}
static COUNT
initialize_weapon (ELEMENT *ShipPtr, HELEMENT WeaponArray[])
{
	COUNT i;
	STARSHIP *StarShipPtr;
	MISSILE_BLOCK MissileBlock;
	
	GetElementStarShip (ShipPtr, &StarShipPtr);
	MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon;
	// MissileBlock.face = StarShipPtr->ShipFacing;
	MissileBlock.face = MissileBlock.index = StarShipPtr->ShipFacing;
	MissileBlock.sender = ShipPtr->playerNr;
	MissileBlock.flags = IGNORE_SIMILAR;
	MissileBlock.speed = (MISSILE_SPEED << RESOLUTION_FACTOR);
	MissileBlock.hit_points = MISSILE_HITS;
	MissileBlock.damage = MISSILE_DAMAGE;
	MissileBlock.life = MISSILE_LIFE;
	MissileBlock.blast_offs = MISSILE_OFFSET;
	MissileBlock.preprocess_func = 0;

	for (i = 0; i < 2; ++i)
	{
		if (i == 0)
		{
			MissileBlock.pixoffs = THRADDASH_OFFSET_2;
			MissileBlock.cx = ShipPtr->next.location.x;
			MissileBlock.cy = ShipPtr->next.location.y;
		}
		else if (StarShipPtr->static_counter == 0)
		{
			MissileBlock.pixoffs = THRADDASH_OFFSET_1;
			MissileBlock.cx = ShipPtr->next.location.x
				+ COSINE(FACING_TO_ANGLE (MissileBlock.face + 4), -25);
			MissileBlock.cy = ShipPtr->next.location.y
				+ SINE(FACING_TO_ANGLE (MissileBlock.face + 4), -25);
		}
		else
		{
			MissileBlock.pixoffs = THRADDASH_OFFSET_1;
			MissileBlock.cx = ShipPtr->next.location.x
				+ COSINE(FACING_TO_ANGLE (MissileBlock.face + 4), 25);
			MissileBlock.cy = ShipPtr->next.location.y
				+ SINE(FACING_TO_ANGLE (MissileBlock.face + 4), 25);
		}

		if ((WeaponArray[i] = initialize_missile (&MissileBlock)))
		{
			SIZE dx, dy;
			ELEMENT *WeaponPtr;

			LockElement (WeaponArray[i], &WeaponPtr);
			GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);
			DeltaVelocityComponents (&WeaponPtr->velocity, dx, dy);
			WeaponPtr->current.location.x -= VELOCITY_TO_WORLD (dx);
			WeaponPtr->current.location.y -= VELOCITY_TO_WORLD (dy);
			// WeaponPtr->collision_func = repulsor_collision;		
			UnlockElement (WeaponArray[i]);
		}
	}

	return (2);
}
static void
thraddash_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern, COUNT ConcernCounter)
{

	STARSHIP *StarShipPtr;
	EVALUATE_DESC *lpEvalDesc;
	
	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (lpEvalDesc->ObjectPtr)
	{
#define STATIONARY_SPEED WORLD_TO_VELOCITY (DISPLAY_TO_WORLD (4))
		SIZE dx, dy;

		GetCurrentVelocityComponents (
				&lpEvalDesc->ObjectPtr->velocity, &dx, &dy
				);
		if (lpEvalDesc->which_turn > 8
				|| (long)dx * dx + (long)dy * dy <=
				(long)STATIONARY_SPEED * STATIONARY_SPEED)
			lpEvalDesc->MoveState = PURSUE;
		else
			lpEvalDesc->MoveState = ENTICE;
	}
	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	GetElementStarShip (ShipPtr, &StarShipPtr);
	if (StarShipPtr->special_counter == 0)
	{
		StarShipPtr->ship_input_state &= ~SPECIAL;
		if (ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr
				&& ObjectsOfConcern[ENEMY_WEAPON_INDEX].MoveState == ENTICE)
		{
			if ((StarShipPtr->ship_input_state & THRUST)
					|| (ShipPtr->turn_wait == 0
					&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT)))
					|| NORMALIZE_FACING (ANGLE_TO_FACING (
					GetVelocityTravelAngle (
					&ObjectsOfConcern[ENEMY_WEAPON_INDEX].ObjectPtr->velocity
					) + HALF_CIRCLE + OCTANT)
					- StarShipPtr->ShipFacing) > ANGLE_TO_FACING (QUADRANT))
				StarShipPtr->ship_input_state |= SPECIAL;
		}
		else if (lpEvalDesc->ObjectPtr)
		{
			if (lpEvalDesc->MoveState == PURSUE)
			{
				if (StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST
						+ SPECIAL_ENERGY_COST
						&& ShipPtr->turn_wait == 0
						&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT))
						&& (!(StarShipPtr->cur_status_flags & SPECIAL)
						|| !(StarShipPtr->cur_status_flags
						& (SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED))))
					StarShipPtr->ship_input_state |= SPECIAL;
			}
			else if (lpEvalDesc->MoveState == ENTICE)
			{
				COUNT direction_angle;
				SIZE delta_x, delta_y;

				delta_x = lpEvalDesc->ObjectPtr->next.location.x
						- ShipPtr->next.location.x;
				delta_y = lpEvalDesc->ObjectPtr->next.location.y
						- ShipPtr->next.location.y;
				direction_angle = ARCTAN (delta_x, delta_y);

				if ((lpEvalDesc->which_turn > 24
						&& !(StarShipPtr->ship_input_state & (LEFT | RIGHT)))
						|| (lpEvalDesc->which_turn <= 16
						&& NORMALIZE_ANGLE (direction_angle
						- (FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE)
						+ QUADRANT) <= HALF_CIRCLE
						&& (lpEvalDesc->which_turn < 12
						|| NORMALIZE_ANGLE (direction_angle
						- (GetVelocityTravelAngle (
								&lpEvalDesc->ObjectPtr->velocity
								) + HALF_CIRCLE)
						+ (OCTANT + 2)) <= ((OCTANT + 2) << 1))))
					StarShipPtr->ship_input_state |= SPECIAL;
			}
		}

		if ((StarShipPtr->ship_input_state & SPECIAL)
				&& StarShipPtr->RaceDescPtr->ship_info.energy_level >=
				SPECIAL_ENERGY_COST)
			StarShipPtr->ship_input_state &= ~THRUST;
	}
}
Exemple #17
0
static void
baul_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
						COUNT ConcernCounter)
{
	BYTE old_count;
	STARSHIP *StarShipPtr;
	EVALUATE_DESC *lpEvalDesc;
	BYTE in_gas_cloud = 0;
	
	GetElementStarShip (ShipPtr, &StarShipPtr);
	old_count = StarShipPtr->weapon_counter;
	
	// Don't spawn gas unless specifically told to.
	StarShipPtr->ship_input_state &= ~SPECIAL;
	
	// See if there is gas sticking to OUR ship.
	lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
	if (lpEvalDesc->ObjectPtr)
	{
		if (lpEvalDesc->ObjectPtr->state_flags & GASSY_SUBSTANCE 
			&& lpEvalDesc->ObjectPtr->mass_points == 0
			&& lpEvalDesc->which_turn <= 1)
			in_gas_cloud = 1;
	}
	
	// Now that we're done with the gas examinations, examine enemy ship.
	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	
	// Actions towards enemy ship: 
	if (lpEvalDesc->ObjectPtr)
	{
#define STATIONARY_SPEED WORLD_TO_VELOCITY (DISPLAY_TO_WORLD (4 << RESOLUTION_FACTOR)) // JMS_GFX
		SIZE dx, dy;
		
		GetCurrentVelocityComponents (&lpEvalDesc->ObjectPtr->velocity, &dx, &dy);
		
		// Chase the ship if it's within a reasonable distance and there's no gas sticking to OUR ship.
		if ((lpEvalDesc->which_turn < 20
			|| (long)dx * dx + (long)dy * dy <= (long)STATIONARY_SPEED * STATIONARY_SPEED)
			&& !in_gas_cloud)
			lpEvalDesc->MoveState = PURSUE;
		// Otherwise, entice.
		else
			lpEvalDesc->MoveState = ENTICE;
	}
	
	// Normal ship intelligence.
	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);
	
	// We don't want the Baul shooting all the time so it doesn't kill itself so easily.
	if (lpEvalDesc->ObjectPtr)
	{	
		STARSHIP *EnemyStarShipPtr;
		GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr);
		
		// If the enemy is very close, don't shoot him with the primary to avoid damage to self.
		// We shoot however, if the enemy ship has lazer or tries to shoot us.
		// The philosophy: Better to kill both than do nothing and die.
		if (StarShipPtr->ship_input_state & WEAPON && lpEvalDesc->which_turn < 8
			&& !(EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags & IMMEDIATE_WEAPON)
			&& !(EnemyStarShipPtr->ship_input_state & WEAPON)
			&& !(EnemyStarShipPtr->ship_input_state & SPECIAL) )
			StarShipPtr->ship_input_state &= ~WEAPON;
	}
	
	// Drop gas whenever the battery tops off and when we are far away from the enemy.
	if ((StarShipPtr->RaceDescPtr->ship_info.energy_level 
		 == StarShipPtr->RaceDescPtr->ship_info.max_energy)
		&& lpEvalDesc->which_turn > 12
		&& !in_gas_cloud)
		StarShipPtr->ship_input_state |= SPECIAL;
	
	// Consider dropping gas also when the enemy is in our sights.
	if (StarShipPtr->special_counter == 0)
	{
		BYTE old_input_state;
		old_input_state = StarShipPtr->ship_input_state;
		
		// The final decision of "to gas or not to gas" is made by evaluating a test weapon function.
		StarShipPtr->RaceDescPtr->init_weapon_func = initialize_test_gas;
		ship_intelligence (ShipPtr, ObjectsOfConcern, ENEMY_SHIP_INDEX + 1);
		
		// Since we faked using primary weapon even though we really are gonna use special,
		// change the WEAPON button press to SPECIAL.
		if (StarShipPtr->ship_input_state & WEAPON)
		{
			StarShipPtr->ship_input_state &= ~WEAPON;
			StarShipPtr->ship_input_state |= SPECIAL;
		}
		
		StarShipPtr->ship_input_state = (unsigned char)(old_input_state | (StarShipPtr->ship_input_state & SPECIAL));
	}
	
	// Return the original stats.
	StarShipPtr->weapon_counter = old_count;
	StarShipPtr->RaceDescPtr->init_weapon_func = initialize_spray;
}
Exemple #18
0
// Secondary weapon: Gas cloud.
// The IGNORE_VELOCITY flag is very important: It doesn't only stop the gas from reacting to gravity,
// (see collide.h) but it also makes it possible for the gas to stick to enemy ship (see this file's other gas functions).
static void spawn_gas (ELEMENT *ShipPtr)
{	
	STARSHIP *StarShipPtr;
	MISSILE_BLOCK MissileBlock;
	HELEMENT Missile;
	SIZE offs_x, offs_y;
	COUNT angle;
	static COUNT gas_side[NUM_SIDES]   = {0, 0};
	static COUNT gas_number[NUM_SIDES] = {0, 0};
	
	GetElementStarShip (ShipPtr, &StarShipPtr);
	
	gas_number[ShipPtr->playerNr] = (gas_number[ShipPtr->playerNr] + 1) % 32;
	gas_side[ShipPtr->playerNr] = (gas_side[ShipPtr->playerNr] + 1) % 2;
	angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing);
	
	// This mechanism can be used to alter the "pipe" from which the gas clouds come.
	if(gas_side[ShipPtr->playerNr])
	{
		offs_x = -SINE (angle, GAS_HORZ_OFFSET);
		offs_y = COSINE (angle, GAS_HORZ_OFFSET);
	}
	else
	{
		offs_x = -SINE (angle, GAS_HORZ_OFFSET);
		offs_y = COSINE (angle, GAS_HORZ_OFFSET);
	}
		
	MissileBlock.cx = ShipPtr->next.location.x + offs_x;
	MissileBlock.cy = ShipPtr->next.location.y + offs_y;
	MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special;
	MissileBlock.face = StarShipPtr->ShipFacing;// Baul's gas now flies forward. (this was: (StarShipPtr->ShipFacing - 8) % 16;)
	MissileBlock.index = LAST_DISSOLVE_INDEX; // Start with the gas emerge animation which is the last .pngs in gasXX.ani
	MissileBlock.sender = ShipPtr->playerNr;
	MissileBlock.flags = GASSY_SUBSTANCE | IGNORE_VELOCITY; // Don't erase the IGNORE_VELOCITY. It's very important.
	MissileBlock.pixoffs = GAS_OFFSET;
	MissileBlock.speed = GAS_INIT_SPEED;
	MissileBlock.hit_points = GAS_HITS;
	MissileBlock.damage = GAS_DAMAGE;
	MissileBlock.life = GAS_LIFE;
	MissileBlock.preprocess_func = gas_preprocess;
	MissileBlock.blast_offs = 0;
	Missile = initialize_missile (&MissileBlock);
	
	if (Missile)
	{
		ELEMENT *GasPtr;
		SIZE	dx, dy; // Baul's gas now flies forward.
		
		LockElement (Missile, &GasPtr);
		
		// Baul's gas now flies forward.
		GetCurrentVelocityComponents (&ShipPtr->velocity, &dx, &dy);
		DeltaVelocityComponents (&GasPtr->velocity, dx, dy);
		GasPtr->current.location.x -= VELOCITY_TO_WORLD (dx);
		GasPtr->current.location.y -= VELOCITY_TO_WORLD (dy);
		
		GasPtr->collision_func = gas_collision;
		GasPtr->death_func = gas_death;
		GasPtr->thrust_wait = 1;
		GasPtr->weapon_element_index = gas_number[ShipPtr->playerNr];
		SetElementStarShip (GasPtr, StarShipPtr);
		ProcessSound (SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), GasPtr);
		UnlockElement (Missile);
		PutElement (Missile);
	}
}