Beispiel #1
0
static void
mmrnmhrm_postprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
			/* take care of transform effect */
	if (ElementPtr->next.image.farray != ElementPtr->current.image.farray)
	{
		CHARACTERISTIC_STUFF t;

		ProcessSound (SetAbsSoundIndex (
						/* TRANSFORM */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);
		DeltaEnergy (ElementPtr,
				-StarShipPtr->RaceDescPtr->characteristics.special_energy_cost);

		StarShipPtr->weapon_counter = 0;

		t = otherwing_desc[WHICH_SIDE(ElementPtr->state_flags)];
		otherwing_desc[WHICH_SIDE(ElementPtr->state_flags)] = StarShipPtr->RaceDescPtr->characteristics;
		StarShipPtr->RaceDescPtr->characteristics = t;
		StarShipPtr->RaceDescPtr->cyborg_control.ManeuverabilityIndex = 0;

		if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special)
		{
			StarShipPtr->RaceDescPtr->cyborg_control.WeaponRange = LONG_RANGE_WEAPON - 1;
			StarShipPtr->RaceDescPtr->ship_info.ship_flags &= ~IMMEDIATE_WEAPON;
			StarShipPtr->RaceDescPtr->ship_info.ship_flags |= SEEKING_WEAPON;
			StarShipPtr->RaceDescPtr->ship_data.ship_sounds =
					SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2);

			StarShipPtr->cur_status_flags &=
					~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED);
		}
		else
		{
			StarShipPtr->RaceDescPtr->cyborg_control.WeaponRange = CLOSE_RANGE_WEAPON;
			StarShipPtr->RaceDescPtr->ship_info.ship_flags &= ~SEEKING_WEAPON;
			StarShipPtr->RaceDescPtr->ship_info.ship_flags |= IMMEDIATE_WEAPON;
			StarShipPtr->RaceDescPtr->ship_data.ship_sounds =
					SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 0);

			if (StarShipPtr->cur_status_flags
					& (SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED))
				StarShipPtr->cur_status_flags |=
						SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED;
		}
	}
}
Beispiel #2
0
static void
melnorme_postprocess (ELEMENT *ElementPtr)
{
    STARSHIP *StarShipPtr;

    GetElementStarShip (ElementPtr, &StarShipPtr);
    if ((StarShipPtr->cur_status_flags & SPECIAL)
            && StarShipPtr->special_counter == 0
            && DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST))
    {
        HELEMENT Confusion;

        initialize_confusion (ElementPtr, &Confusion);
        if (Confusion)
        {
            ELEMENT *CMissilePtr;
            LockElement (Confusion, &CMissilePtr);

            ProcessSound (SetAbsSoundIndex (
                              StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), CMissilePtr);

            UnlockElement (Confusion);
            PutElement (Confusion);
            StarShipPtr->special_counter =
                StarShipPtr->RaceDescPtr->characteristics.special_wait;
        }
    }
}
Beispiel #3
0
static void
pkunk_postprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	if (StarShipPtr->RaceDescPtr->characteristics.special_wait)
		--StarShipPtr->RaceDescPtr->characteristics.special_wait;
	else if ((StarShipPtr->cur_status_flags & SPECIAL)
			&& StarShipPtr->RaceDescPtr->ship_info.energy_level <
			StarShipPtr->RaceDescPtr->ship_info.max_energy)
	{
		COUNT CurSound;

		do
		{
			CurSound =
					2 + ((COUNT)TFB_Random ()
					% (GetSoundCount (StarShipPtr->RaceDescPtr->ship_data.ship_sounds) - 2));
		} while (CurSound == LastSound);
		ProcessSound (SetAbsSoundIndex (
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, CurSound
				), ElementPtr);
		LastSound = CurSound;

		DeltaEnergy (ElementPtr, SPECIAL_ENERGY_COST);

		StarShipPtr->RaceDescPtr->characteristics.special_wait = SPECIAL_WAIT;
	}
}
Beispiel #4
0
static void
druuge_preprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	if (StarShipPtr->cur_status_flags & SPECIAL)
	{
		if (StarShipPtr->special_counter
				|| ElementPtr->crew_level == 1
				|| StarShipPtr->RaceDescPtr->ship_info.energy_level
				== StarShipPtr->RaceDescPtr->ship_info.max_energy)
			StarShipPtr->cur_status_flags &= ~SPECIAL;
		else
		{
			ProcessSound (SetAbsSoundIndex (
							/* BURN UP CREW */
					StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);

			DeltaCrew (ElementPtr, -1);
			DeltaEnergy (ElementPtr, SPECIAL_ENERGY_COST);

			StarShipPtr->special_counter =
					StarShipPtr->RaceDescPtr->characteristics.special_wait;
		}
	}
}
Beispiel #5
0
static void
spawn_doggy (ELEMENT *ElementPtr)
{
	HELEMENT hDoggyElement;

	if ((hDoggyElement = AllocElement ()) != 0)
	{
		COUNT angle;
		ELEMENT *DoggyElementPtr;
		STARSHIP *StarShipPtr;

		ElementPtr->state_flags |= DEFY_PHYSICS;

		PutElement (hDoggyElement);
		LockElement (hDoggyElement, &DoggyElementPtr);
		DoggyElementPtr->hit_points = DOGGY_HITS;
		DoggyElementPtr->mass_points = DOGGY_MASS;
		DoggyElementPtr->thrust_wait = 0;
		DoggyElementPtr->playerNr = ElementPtr->playerNr;
		DoggyElementPtr->state_flags = APPEARING;
		DoggyElementPtr->life_span = NORMAL_LIFE;
		SetPrimType (&(GLOBAL (DisplayArray))[DoggyElementPtr->PrimIndex],
				STAMP_PRIM);
		{
			DoggyElementPtr->preprocess_func = doggy_preprocess;
			DoggyElementPtr->postprocess_func = NULL;
			DoggyElementPtr->collision_func = doggy_collision;
			DoggyElementPtr->death_func = doggy_death;
		}

		GetElementStarShip (ElementPtr, &StarShipPtr);
		angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE;
		DoggyElementPtr->current.location.x = ElementPtr->next.location.x
				+ COSINE (angle, DISPLAY_TO_WORLD (CHENJESU_OFFSET + DOGGY_OFFSET));
		DoggyElementPtr->current.location.y = ElementPtr->next.location.y
				+ SINE (angle, DISPLAY_TO_WORLD (CHENJESU_OFFSET + DOGGY_OFFSET));
		DoggyElementPtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.special;
		DoggyElementPtr->current.image.frame = StarShipPtr->RaceDescPtr->ship_data.special[0];

		SetVelocityVector (&DoggyElementPtr->velocity,
				DOGGY_SPEED, NORMALIZE_FACING (ANGLE_TO_FACING (angle)));

		SetElementStarShip (DoggyElementPtr, StarShipPtr);

		ProcessSound (SetAbsSoundIndex (
						/* RELEASE_DOGGY */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 4), DoggyElementPtr);

		UnlockElement (hDoggyElement);
	}
}
Beispiel #6
0
static void
crystal_postprocess (ELEMENT *ElementPtr)
{
#define FRAGMENT_HITS 1
#define FRAGMENT_DAMAGE 2
#define FRAGMENT_OFFSET 2
#define NUM_FRAGMENTS 8
	STARSHIP *StarShipPtr;
	MISSILE_BLOCK MissileBlock;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	MissileBlock.cx = ElementPtr->next.location.x;
	MissileBlock.cy = ElementPtr->next.location.y;
	MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.weapon;
	MissileBlock.index = 1;
	MissileBlock.sender = ElementPtr->playerNr;
	MissileBlock.flags = IGNORE_SIMILAR;
	MissileBlock.pixoffs = 0;
	MissileBlock.speed = FRAGMENT_SPEED;
	MissileBlock.hit_points = FRAGMENT_HITS;
	MissileBlock.damage = FRAGMENT_DAMAGE;
	MissileBlock.life = FRAGMENT_LIFE;
	MissileBlock.preprocess_func = NULL;
	MissileBlock.blast_offs = FRAGMENT_OFFSET;

	for (MissileBlock.face = 0;
			MissileBlock.face < ANGLE_TO_FACING (FULL_CIRCLE);
			MissileBlock.face +=
			(ANGLE_TO_FACING (FULL_CIRCLE) / NUM_FRAGMENTS))
	{
		HELEMENT hFragment;

		hFragment = initialize_missile (&MissileBlock);
		if (hFragment)
		{
			ELEMENT *FragPtr;

			LockElement (hFragment, &FragPtr);
			SetElementStarShip (FragPtr, StarShipPtr);
			UnlockElement (hFragment);
			PutElement (hFragment);
		}
	}

	ProcessSound (SetAbsSoundIndex (
					/* CRYSTAL_FRAGMENTS */
			StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);
}
Beispiel #7
0
static void
androsynth_postprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
			/* take care of blazer effect */
	if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special)
	{
#define BLAZER_DEGENERATION (-1)
		if ((StarShipPtr->cur_status_flags & SPECIAL)
				|| StarShipPtr->RaceDescPtr->ship_info.energy_level == 0)
		{
			StarShipPtr->RaceDescPtr->characteristics.energy_regeneration =
					(BYTE)BLAZER_DEGENERATION;
			StarShipPtr->energy_counter = ENERGY_WAIT;

			if (StarShipPtr->cur_status_flags & SPECIAL)
			{
				ProcessSound (SetAbsSoundIndex (
						StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1),
						ElementPtr);  /* COMET_ON */
				ElementPtr->turn_wait = 0;
				ElementPtr->thrust_wait = 0;
				StarShipPtr->RaceDescPtr->characteristics.special_wait =
						StarShipPtr->RaceDescPtr->characteristics.turn_wait;
				ElementPtr->mass_points = BLAZER_MASS;
				StarShipPtr->RaceDescPtr->characteristics.turn_wait
						= BLAZER_TURN_WAIT;
				/* Save the current collision func because we were not the
				 * ones who set it */
				StarShipPtr->RaceDescPtr->data = (intptr_t)
						ElementPtr->collision_func;
				ElementPtr->collision_func = blazer_collision;
			}
		}

		if (StarShipPtr->RaceDescPtr->ship_info.energy_level == 0)
				/* if blazer wasn't able to change back into ship
				 * give it a little more juice to try to get out
				 * of its predicament.
				 */
		{
			DeltaEnergy (ElementPtr, -BLAZER_DEGENERATION);
			StarShipPtr->energy_counter = 1;
		}
	}
}
Beispiel #8
0
static void
spawn_butt_missile (ELEMENT *ShipPtr)
{
#define SPATHI_REAR_OFFSET 20
#define DISCRIMINATOR_LIFE 30
#define DISCRIMINATOR_HITS 1
#define DISCRIMINATOR_DAMAGE 2
#define DISCRIMINATOR_OFFSET 4
	HELEMENT ButtMissile;
	STARSHIP *StarShipPtr;
	MISSILE_BLOCK ButtMissileBlock;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	ButtMissileBlock.cx = ShipPtr->next.location.x;
	ButtMissileBlock.cy = ShipPtr->next.location.y;
	ButtMissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special;
	ButtMissileBlock.face = ButtMissileBlock.index =
			NORMALIZE_FACING (StarShipPtr->ShipFacing
			+ ANGLE_TO_FACING (HALF_CIRCLE));
	ButtMissileBlock.sender = ShipPtr->playerNr;
	ButtMissileBlock.flags = 0;
	ButtMissileBlock.pixoffs = SPATHI_REAR_OFFSET;
	ButtMissileBlock.speed = DISCRIMINATOR_SPEED;
	ButtMissileBlock.hit_points = DISCRIMINATOR_HITS;
	ButtMissileBlock.damage = DISCRIMINATOR_DAMAGE;
	ButtMissileBlock.life = DISCRIMINATOR_LIFE;
	ButtMissileBlock.preprocess_func = butt_missile_preprocess;
	ButtMissileBlock.blast_offs = DISCRIMINATOR_OFFSET;
	ButtMissile = initialize_missile (&ButtMissileBlock);
	if (ButtMissile)
	{
		ELEMENT *ButtPtr;

		LockElement (ButtMissile, &ButtPtr);
		ButtPtr->turn_wait = TRACK_WAIT;
		SetElementStarShip (ButtPtr, StarShipPtr);

		ProcessSound (SetAbsSoundIndex (
					/* LAUNCH_BUTT_MISSILE */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ButtPtr);

		UnlockElement (ButtMissile);
		PutElement (ButtMissile);
	}
}
Beispiel #9
0
void
DoInput (void *pInputState, BOOLEAN resetInput)
{
	if (resetInput)
		FlushInput ();

	do
	{
		MENU_SOUND_FLAGS soundFlags;
		Async_process ();
		TaskSwitch ();

		UpdateInputState ();

#if DEMO_MODE || CREATE_JOURNAL
		if (ArrowInput != DemoInput)
#endif
		{
#if CREATE_JOURNAL
			JournalInput (InputState);
#endif /* CREATE_JOURNAL */
		}

		soundFlags = MenuKeysToSoundFlags (&PulsedInputState);
			
		if (MenuSounds && (soundFlags & (sound_0 | sound_1)))
		{
			SOUND S;

			S = MenuSounds;
			if (soundFlags & sound_1)
				S = SetAbsSoundIndex (S, MENU_SOUND_SUCCESS);

			PlaySoundEffect (S, 0, NotPositional (), NULL, 0);
		}

		if (inputCallback)
			inputCallback ();

	} while (((INPUT_STATE_DESC*)pInputState)->InputFunc (pInputState));

	if (resetInput)
		FlushInput ();
}
Beispiel #10
0
static void
syreen_postprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	if ((StarShipPtr->cur_status_flags & SPECIAL)
			&& StarShipPtr->special_counter == 0
			&& DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST))
	{
		ProcessSound (SetAbsSoundIndex (
						/* SYREEN_SONG */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);
		spawn_crew (ElementPtr);

		StarShipPtr->special_counter =
				StarShipPtr->RaceDescPtr->characteristics.special_wait;
	}
}
Beispiel #11
0
static void
doggy_death (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	ProcessSound (SetAbsSoundIndex (
					/* DOGGY_DIES */
			StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 3), ElementPtr);

	ElementPtr->state_flags &= ~DISAPPEARING;
	ElementPtr->state_flags |= NONSOLID | FINITE_LIFE;
	ElementPtr->life_span = 6;
	{
		ElementPtr->preprocess_func = animate;
	}
	ElementPtr->death_func = NULL;
	ElementPtr->collision_func = NULL;
	ZeroVelocityComponents (&ElementPtr->velocity);

	ElementPtr->turn_wait = ElementPtr->next_turn = 0;
}
Beispiel #12
0
static void
doggy_collision (ELEMENT *ElementPtr0, POINT *pPt0,
		ELEMENT *ElementPtr1, POINT *pPt1)
{
	collision (ElementPtr0, pPt0, ElementPtr1, pPt1);
	if ((ElementPtr1->state_flags & PLAYER_SHIP)
			&& !elementsOfSamePlayer (ElementPtr0, ElementPtr1))
	{
		STARSHIP *StarShipPtr;

		GetElementStarShip (ElementPtr0, &StarShipPtr);
		ProcessSound (SetAbsSoundIndex (
						/* DOGGY_STEALS_ENERGY */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr0);
		GetElementStarShip (ElementPtr1, &StarShipPtr);
		if (StarShipPtr->RaceDescPtr->ship_info.energy_level < ENERGY_DRAIN)
			DeltaEnergy (ElementPtr1, -StarShipPtr->RaceDescPtr->ship_info.energy_level);
		else
			DeltaEnergy (ElementPtr1, -ENERGY_DRAIN);
	}
	if (ElementPtr0->thrust_wait <= COLLISION_THRUST_WAIT)
		ElementPtr0->thrust_wait += COLLISION_THRUST_WAIT << 1;
}
Beispiel #13
0
void
crew_collision (ELEMENT *ElementPtr0, POINT *pPt0,
		ELEMENT *ElementPtr1, POINT *pPt1)
{
	if ((ElementPtr1->state_flags & PLAYER_SHIP)
			&& ElementPtr1->life_span >= NORMAL_LIFE
			&& ElementPtr0->hit_points > 0)
	{
		STARSHIP *StarShipPtr;

		GetElementStarShip (ElementPtr1, &StarShipPtr);
		if (!(StarShipPtr->RaceDescPtr->ship_info.ship_flags & CREW_IMMUNE))
		{
			ProcessSound (SetAbsSoundIndex (GameSounds, GRAB_CREW), ElementPtr1);
			DeltaCrew (ElementPtr1, 1);
		}
	}

	ElementPtr0->hit_points = 0;
	ElementPtr0->life_span = 0;
	ElementPtr0->state_flags |= COLLISION | DISAPPEARING | NONSOLID;
	(void) pPt0;  /* Satisfying compiler (unused parameter) */
	(void) pPt1;  /* Satisfying compiler (unused parameter) */
}
Beispiel #14
0
static void
ilwrath_preprocess (PELEMENT ElementPtr)
{
	ELEMENT_FLAGS status_flags;
	STARSHIPPTR StarShipPtr;
	PPRIMITIVE lpPrim;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	status_flags = StarShipPtr->cur_status_flags;
	lpPrim = &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex];
	if (GetPrimType (lpPrim) == STAMPFILL_PRIM)
	{
		COLOR Color;
		BOOLEAN weapon_discharge;

		Color = GetPrimColor (lpPrim);
		weapon_discharge = ((status_flags & WEAPON)
				&& StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST);
		if (weapon_discharge
				|| (StarShipPtr->special_counter == 0
				&& ((status_flags & SPECIAL) || Color != BLACK_COLOR)))
		{
			if (Color == BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F))
				SetPrimType (lpPrim, STAMP_PRIM);
			else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B))
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
			else if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03))
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B));
			else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09))
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
			else if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01))
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09));
			else
			{
				ProcessSound (SetAbsSoundIndex (
								/* CLOAKING_OFF */
						StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr);
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
				if (weapon_discharge)
				{
					COUNT facing;

					facing = StarShipPtr->ShipFacing;
					if (TrackShip (ElementPtr, &facing) >= 0)
					{
#define LOOK_AHEAD 4
						ELEMENTPTR eptr;
						SIZE dx0, dy0, dx1, dy1;
						VELOCITY_DESC v;

						LockElement (ElementPtr->hTarget, &eptr);
						v = eptr->velocity;
						GetNextVelocityComponents (&v, &dx0, &dy0, LOOK_AHEAD);
						v = ElementPtr->velocity;
						GetNextVelocityComponents (&v, &dx1, &dy1, LOOK_AHEAD);
						dx0 = (eptr->current.location.x + dx0)
								- (ElementPtr->current.location.x + dx1);
						dy0 = (eptr->current.location.y + dy0)
								- (ElementPtr->current.location.y + dy1);
						UnlockElement (ElementPtr->hTarget);

						StarShipPtr->ShipFacing =
								NORMALIZE_FACING (
								ANGLE_TO_FACING (ARCTAN (dx0, dy0))
								);
#ifdef NOTYET
						if (ElementPtr->thrust_wait == 0
								&& (StarShipPtr->cur_status_flags & THRUST))
						{
							COUNT last_facing;

							do
							{
								VELOCITY_DESC temp_v;

								last_facing = StarShipPtr->ShipFacing;
								inertial_thrust (ElementPtr);
								temp_v = ElementPtr->velocity;
								ElementPtr->velocity = v;

								dx0 += dx1;
								dy0 += dy1;
								GetNextVelocityComponents (&temp_v,
										&dx1, &dy1, LOOK_AHEAD);
								dx0 -= dx1;
								dy0 -= dy1;
								StarShipPtr->ShipFacing =
										NORMALIZE_FACING (
										ANGLE_TO_FACING (ARCTAN (dx0, dy0))
										);
							} while (StarShipPtr->ShipFacing != last_facing);
						}
#endif /* NOTYET */
						if (ElementPtr->turn_wait == 0)
							++ElementPtr->turn_wait;
						ElementPtr->next.image.frame =
								SetAbsFrameIndex (ElementPtr->next.image.frame,
								StarShipPtr->ShipFacing);
					}
					ElementPtr->hTarget = 0;
				}
			}

			ElementPtr->state_flags |= CHANGING;
			status_flags &= ~SPECIAL;
			StarShipPtr->special_counter = 0;
		}
		else if (Color != BLACK_COLOR)
		{
			if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01))
			{
				SetPrimColor (lpPrim, BLACK_COLOR);
				Untarget (ElementPtr);
			}
			else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09))
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
			else if (Color == BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03))
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09));
			else if (Color == BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B))
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
			else
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B));

			ElementPtr->state_flags |= CHANGING;
		}
	}

	if ((status_flags & SPECIAL)
			&& StarShipPtr->special_counter == 0
			&& DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST))
	{
		SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
		SetPrimType (lpPrim, STAMPFILL_PRIM);

		ProcessSound (SetAbsSoundIndex (
						/* CLOAKING_ON */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);
		StarShipPtr->special_counter =
				StarShipPtr->RaceDescPtr->characteristics.special_wait;

		ElementPtr->state_flags |= CHANGING;
	}
}
Beispiel #15
0
// When hit by Baul spray, gas clouds explodes transforming into a lethal shockwave.
static void
generate_shockwave (ELEMENT *ElementPtr, BYTE which_player)
{
	STARSHIP *StarShipPtr;
	
	GetElementStarShip (ElementPtr, &StarShipPtr);
	
	// Gas is still 'solid' when it's hit by the spray. Let's make a shockwave and kill the gas cloud. 
	if (!(ElementPtr->state_flags & NONSOLID))
	{
		HELEMENT hShockwave;
				
		hShockwave = AllocElement ();
		if (hShockwave)
		{
			ELEMENT *ShockwavePtr;
			STARSHIP *StarShipPtr;
			
			GetElementStarShip (ElementPtr, &StarShipPtr);
			
			PutElement (hShockwave);
			LockElement (hShockwave, &ShockwavePtr);
			SetElementStarShip (ShockwavePtr, StarShipPtr);
			ShockwavePtr->hit_points = ShockwavePtr->mass_points = 0;
			ShockwavePtr->playerNr = which_player;
			ShockwavePtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID | IGNORE_SIMILAR;
			ShockwavePtr->life_span = SHOCKWAVE_FRAMES;
			SetPrimType (&(GLOBAL (DisplayArray))[ShockwavePtr->PrimIndex], STAMP_PRIM);
			ShockwavePtr->current.image.farray = StarShipPtr->RaceDescPtr->ship_data.special;
			ShockwavePtr->current.image.frame = SetAbsFrameIndex(StarShipPtr->RaceDescPtr->ship_data.special[0], LAST_GAS_INDEX);
			ShockwavePtr->next.image.frame = SetAbsFrameIndex(ElementPtr->current.image.frame, LAST_GAS_INDEX);
			ShockwavePtr->current.location = ElementPtr->current.location;
			ShockwavePtr->preprocess_func = shockwave_preprocess;
			ShockwavePtr->postprocess_func = NULL;
			ShockwavePtr->death_func = NULL;
			ZeroVelocityComponents (&ShockwavePtr->velocity);
			UnlockElement (hShockwave);
		}
		
		// Gas dies on the next turn.
		ElementPtr->state_flags |= NONSOLID;
		
		// Explosion sounds.
		ProcessSound (SetAbsSoundIndex (StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr);
		ProcessSound (SetAbsSoundIndex (GameSounds, TARGET_DAMAGED_FOR_6_PLUS_PT), ElementPtr);
	}

	{
		// This is called during PostProcessQueue(), close to or at the end,
		// for the temporary shockwave element to apply the damage.
		// The effects are not seen until the next frame.
		HELEMENT hElement, hNextElement;
		
		for (hElement = GetHeadElement (); hElement != 0; hElement = hNextElement)
		{
			ELEMENT *ObjPtr;
			
			LockElement (hElement, &ObjPtr);
			hNextElement = GetSuccElement (ObjPtr);
			
			if (IS_GAS (ObjPtr))
			{
				SIZE delta_x, delta_y;
				DWORD dist;
				
				if ((delta_x = ObjPtr->next.location.x - ElementPtr->next.location.x) < 0) delta_x = -delta_x;
				if ((delta_y = ObjPtr->next.location.y - ElementPtr->next.location.y) < 0) delta_y = -delta_y;
				
				delta_x = WORLD_TO_DISPLAY (delta_x);
				delta_y = WORLD_TO_DISPLAY (delta_y);
				
				if (delta_x <= SHOCKWAVE_RANGE && delta_y <= SHOCKWAVE_RANGE
					&& (dist = (DWORD)(delta_x * delta_x) + (DWORD)(delta_y * delta_y)) <= (DWORD)(SHOCKWAVE_RANGE * SHOCKWAVE_RANGE))
				{
					SIZE destruction;
					
					destruction = ((MAX_DESTRUCTION * (SHOCKWAVE_RANGE - square_root (dist))) / SHOCKWAVE_RANGE) + 1;
					
					// The shockwave is delayed according to how far it is from the shockwave that set it off.
					ObjPtr->life_span = (10 / destruction);
					ObjPtr->death_func = generate_shockwave_2;
					ObjPtr->playerNr = which_player;
				}
			}
			else if (CollidingElement (ObjPtr) || ORZ_MARINE (ObjPtr))
			{
				SIZE delta_x, delta_y;
				DWORD dist;
				
				if ((delta_x = ObjPtr->next.location.x - ElementPtr->next.location.x) < 0) delta_x = -delta_x;
				if ((delta_y = ObjPtr->next.location.y - ElementPtr->next.location.y) < 0) delta_y = -delta_y;
				
				delta_x = WORLD_TO_DISPLAY (delta_x);
				delta_y = WORLD_TO_DISPLAY (delta_y);
				
				if (delta_x <= SHOCKWAVE_RANGE && delta_y <= SHOCKWAVE_RANGE
					&& (dist = (DWORD)(delta_x * delta_x) + (DWORD)(delta_y * delta_y)) <= (DWORD)(SHOCKWAVE_RANGE * SHOCKWAVE_RANGE))
				{
					SIZE destruction;
					
					destruction = ((MAX_DESTRUCTION * (SHOCKWAVE_RANGE - square_root (dist))) / SHOCKWAVE_RANGE) + 1;
					
					if (ObjPtr->state_flags & PLAYER_SHIP && ObjPtr->playerNr != which_player)
					{
						STARSHIP *EnemyShipPtr;
						
						GetElementStarShip (ObjPtr, &EnemyShipPtr);
						
						// Deal damage to ships except shield-using Yehat & Utwig.
						if (!((EnemyShipPtr->SpeciesID == YEHAT_ID || EnemyShipPtr->SpeciesID == UTWIG_ID) 
							  && ObjPtr->life_span > NORMAL_LIFE))
						{
							if (!DeltaCrew (ObjPtr, -destruction))
								ObjPtr->life_span = 0;
						}
						// Charge Utwig shield.
						else if (EnemyShipPtr->SpeciesID == UTWIG_ID && ObjPtr->life_span > NORMAL_LIFE)
							ObjPtr->life_span += destruction;
					}
					else if (!GRAVITY_MASS (ObjPtr->mass_points) && ObjPtr->playerNr != which_player)
					{
						if ((BYTE)destruction < ObjPtr->hit_points)
							ObjPtr->hit_points -= (BYTE)destruction;
						else
						{
							ObjPtr->hit_points = 0;
							ObjPtr->life_span = 0;
						}
					}
				}
			}
			
			UnlockElement (hElement);
		}
	}
}
Beispiel #16
0
static void
spawn_point_defense (PELEMENT ElementPtr)
{
	STARSHIPPTR StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	if (ElementPtr->state_flags & PLAYER_SHIP)
	{
		HELEMENT hDefense;

		hDefense = AllocElement ();
		if (hDefense)
		{
			ELEMENTPTR DefensePtr;

			LockElement (hDefense, &DefensePtr);
			DefensePtr->state_flags = APPEARING | NONSOLID | FINITE_LIFE |
					(ElementPtr->state_flags & (GOOD_GUY | BAD_GUY));
			{
				DefensePtr->death_func = spawn_point_defense;
			}
			GetElementStarShip (ElementPtr, &StarShipPtr);
			SetElementStarShip (DefensePtr, StarShipPtr);
			UnlockElement (hDefense);

			PutElement (hDefense);
		}
	}
	else
	{
		BOOLEAN PaidFor;
		HELEMENT hObject, hNextObject;
		ELEMENTPTR ShipPtr;

		PaidFor = FALSE;

		LockElement (StarShipPtr->hShip, &ShipPtr);
		for (hObject = GetTailElement (); hObject; hObject = hNextObject)
		{
			ELEMENTPTR ObjectPtr;

			LockElement (hObject, &ObjectPtr);
			hNextObject = GetPredElement (ObjectPtr);
			if (ObjectPtr != ShipPtr && CollidingElement (ObjectPtr) &&
					!OBJECT_CLOAKED (ObjectPtr))
			{
#define LASER_RANGE (UWORD)100
				SIZE delta_x, delta_y;

				delta_x = ObjectPtr->next.location.x -
						ShipPtr->next.location.x;
				delta_y = ObjectPtr->next.location.y -
						ShipPtr->next.location.y;
				if (delta_x < 0)
					delta_x = -delta_x;
				if (delta_y < 0)
					delta_y = -delta_y;
				delta_x = WORLD_TO_DISPLAY (delta_x);
				delta_y = WORLD_TO_DISPLAY (delta_y);
				if ((UWORD)delta_x <= LASER_RANGE &&
						(UWORD)delta_y <= LASER_RANGE &&
						(UWORD)delta_x * (UWORD)delta_x +
						(UWORD)delta_y * (UWORD)delta_y <=
						LASER_RANGE * LASER_RANGE)
				{
					HELEMENT hPointDefense;
					LASER_BLOCK LaserBlock;

					if (!PaidFor)
					{
						if (!DeltaEnergy (ShipPtr, -SPECIAL_ENERGY_COST))
							break;

						ProcessSound (SetAbsSoundIndex (
										/* POINT_DEFENSE_LASER */
								StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1));
						StarShipPtr->special_counter =
								StarShipPtr->RaceDescPtr->characteristics.special_wait;
						PaidFor = TRUE;
					}

					LaserBlock.cx = ShipPtr->next.location.x;
					LaserBlock.cy = ShipPtr->next.location.y;
					LaserBlock.face = 0;
					LaserBlock.ex = ObjectPtr->next.location.x
							- ShipPtr->next.location.x;
					LaserBlock.ey = ObjectPtr->next.location.y
							- ShipPtr->next.location.y;
					LaserBlock.sender = (ShipPtr->state_flags & (GOOD_GUY | BAD_GUY))
							| IGNORE_SIMILAR;
					LaserBlock.pixoffs = 0;
					LaserBlock.color = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F);
					hPointDefense = initialize_laser (&LaserBlock);
					if (hPointDefense)
					{
						ELEMENTPTR PDPtr;

						LockElement (hPointDefense, &PDPtr);
						SetElementStarShip (PDPtr, StarShipPtr);
						PDPtr->hTarget = 0;
						UnlockElement (hPointDefense);

						PutElement (hPointDefense);
					}
				}
			}
			UnlockElement (hObject);
		}
		UnlockElement (StarShipPtr->hShip);
	}
}
Beispiel #17
0
static void
thraddash_preprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	if (!(StarShipPtr->cur_status_flags & SPECIAL))
	{
		if ((StarShipPtr->old_status_flags & SPECIAL)
				&& (StarShipPtr->cur_status_flags & SHIP_AT_MAX_SPEED))
			StarShipPtr->cur_status_flags |= SHIP_BEYOND_MAX_SPEED;
	}
	else if (DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST))
	{
		COUNT max_thrust, thrust_increment;
		STATUS_FLAGS thrust_status;
		HELEMENT hTrailElement;

		if (!(StarShipPtr->old_status_flags & SPECIAL))
			StarShipPtr->cur_status_flags &=
					~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED);

		if (ElementPtr->thrust_wait == 0)
			++ElementPtr->thrust_wait;

		thrust_increment =
				StarShipPtr->RaceDescPtr->characteristics.thrust_increment;
		max_thrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust;
		StarShipPtr->RaceDescPtr->characteristics.thrust_increment =
				SPECIAL_THRUST_INCREMENT;
		StarShipPtr->RaceDescPtr->characteristics.max_thrust =
				SPECIAL_MAX_THRUST;

		thrust_status = inertial_thrust (ElementPtr);
		StarShipPtr->cur_status_flags &=
				~(SHIP_AT_MAX_SPEED
				| SHIP_BEYOND_MAX_SPEED
				| SHIP_IN_GRAVITY_WELL);
		StarShipPtr->cur_status_flags |= thrust_status;

		StarShipPtr->RaceDescPtr->characteristics.thrust_increment =
				thrust_increment;
		StarShipPtr->RaceDescPtr->characteristics.max_thrust = max_thrust;

		{
			MISSILE_BLOCK MissileBlock;

			MissileBlock.cx = ElementPtr->next.location.x;
			MissileBlock.cy = ElementPtr->next.location.y;
			MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special;
			MissileBlock.face = 0;
			MissileBlock.index = GetFrameCount (
					StarShipPtr->RaceDescPtr->ship_data.special[0]
					) - 1;
			MissileBlock.sender = ElementPtr->playerNr;
			MissileBlock.flags = IGNORE_SIMILAR;
			MissileBlock.pixoffs = 0;
			MissileBlock.speed = 0;
			MissileBlock.hit_points = NAPALM_HITS;
			MissileBlock.damage = NAPALM_DAMAGE;
			MissileBlock.life = NAPALM_LIFE;
			MissileBlock.preprocess_func = flame_napalm_preprocess;
			MissileBlock.blast_offs = NAPALM_OFFSET;

			hTrailElement = initialize_missile (&MissileBlock);
			if (hTrailElement)
			{
				ELEMENT *TrailElementPtr;

				LockElement (hTrailElement, &TrailElementPtr);
				SetElementStarShip (TrailElementPtr, StarShipPtr);
				TrailElementPtr->hTarget = 0;

				/* turn_wait is abused here to store the speed of the decay
				 * animation */
				TrailElementPtr->turn_wait = NAPALM_DECAY_RATE;

				TrailElementPtr->state_flags |= NONSOLID;
				SetPrimType (
						&(GLOBAL (DisplayArray))[TrailElementPtr->PrimIndex],
						NO_PRIM
						);

						/* normally done during preprocess, but because
						 * object is being inserted at head rather than
						 * appended after tail it may never get preprocessed.
						 */
				TrailElementPtr->next = TrailElementPtr->current;
				TrailElementPtr->state_flags |= PRE_PROCESS;

				UnlockElement (hTrailElement);
				InsertElement (hTrailElement, GetHeadElement ());

				ProcessSound (SetAbsSoundIndex (
						StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);
			}
		}
	}
}
Beispiel #18
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;
    }
}
Beispiel #19
0
void
ship_death (ELEMENT *ShipPtr)
{
	STARSHIP *StarShipPtr;
	STARSHIP *VictoriousStarShipPtr;
	HELEMENT hElement, hNextElement;
	ELEMENT *ElementPtr;

	StopDitty ();
	StopMusic ();

	GetElementStarShip (ShipPtr, &StarShipPtr);
	
	// JMS: Make sure the Foon-foon's spinning blade sound ends when the ship dies.
	if (StarShipPtr->SpeciesID == FOONFOON_ID)
	{
		COUNT i;
		
		for (i = FIRST_SFX_CHANNEL; i <= LAST_SFX_CHANNEL; ++i)
		{
			ELEMENT *posobj;
			if (!ChannelPlaying(i))
				continue;
			
			posobj = GetPositionalObject (i);
			
			if (posobj)
				StopSource (i);
		}
	}

	if (ShipPtr->mass_points <= MAX_SHIP_MASS)
	{	// Not running away and not reincarnating (Pkunk)
		// When a ship tries to run away, it is (dis)counted in DoRunAway(),
		// so when it dies while running away, we will not count it again
		assert (StarShipPtr->playerNr >= 0);
		battle_counter[StarShipPtr->playerNr]--;
	}

	VictoriousStarShipPtr = NULL;
	for (hElement = GetHeadElement (); hElement; hElement = hNextElement)
	{
		LockElement (hElement, &ElementPtr);
		if ((ElementPtr->state_flags & PLAYER_SHIP)
				&& ElementPtr != ShipPtr
						/* and not running away */
				&& ElementPtr->mass_points <= MAX_SHIP_MASS)
		{
			GetElementStarShip (ElementPtr, &VictoriousStarShipPtr);
			if (VictoriousStarShipPtr->RaceDescPtr->ship_info.crew_level == 0)
				VictoriousStarShipPtr = NULL;

			UnlockElement (hElement);
			break;
		}
		hNextElement = GetSuccElement (ElementPtr);
		UnlockElement (hElement);
	}

	StarShipPtr->cur_status_flags &= ~PLAY_VICTORY_DITTY;

	DeltaEnergy (ShipPtr,
			-(SIZE)StarShipPtr->RaceDescPtr->ship_info.energy_level);

	ShipPtr->life_span = NUM_EXPLOSION_FRAMES * 3;
	ShipPtr->state_flags &= ~DISAPPEARING;
	ShipPtr->state_flags |= FINITE_LIFE | NONSOLID;
	ShipPtr->postprocess_func = PostProcessStatus;
	ShipPtr->death_func = cleanup_dead_ship;
	ShipPtr->hTarget = 0;
	ZeroVelocityComponents (&ShipPtr->velocity);
	if (ShipPtr->crew_level) /* only happens for shofixti self-destruct */
	{
		PlaySound (SetAbsSoundIndex (
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1),
				CalcSoundPosition (ShipPtr), ShipPtr,
				GAME_SOUND_PRIORITY + 1);

		DeltaCrew (ShipPtr, -(SIZE)ShipPtr->crew_level);
		if (VictoriousStarShipPtr == NULL)
		{	// No ships left alive after a Shofixti Glory device,
			// thus Shofixti wins
			VictoriousStarShipPtr = StarShipPtr;
		}
	}
	else
	{
		ShipPtr->preprocess_func = explosion_preprocess;

		PlaySound (SetAbsSoundIndex (GameSounds, SHIP_EXPLODES),
				CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1);
	}

	if (VictoriousStarShipPtr != NULL)
		VictoriousStarShipPtr->cur_status_flags |= PLAY_VICTORY_DITTY;

	// The winner is set once per battle. If both ships die, this function is
	// called twice, once for each ship. We need to preserve the winner
	// determined on the first call.
	if (winnerStarShip == NULL)
		winnerStarShip = VictoriousStarShipPtr;

	if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE)
		MeleeShipDeath (StarShipPtr);
}
Beispiel #20
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);
	}
}
static void
ilwrath_preprocess (ELEMENT *ElementPtr)
{
	STATUS_FLAGS status_flags;
	STARSHIP *StarShipPtr;
	PRIMITIVE *lpPrim;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	status_flags = StarShipPtr->cur_status_flags;
	lpPrim = &(GLOBAL (DisplayArray))[ElementPtr->PrimIndex];
	if (GetPrimType (lpPrim) == STAMPFILL_PRIM)
	{
		Color color;
		BOOLEAN weapon_discharge;

		color = GetPrimColor (lpPrim);
		weapon_discharge = ((status_flags & WEAPON)
				&& StarShipPtr->RaceDescPtr->ship_info.energy_level >= WEAPON_ENERGY_COST);
	
		if (
			weapon_discharge
			|| (
				StarShipPtr->special_counter == 0
				&& ( 
					((!sameColor(color, BLACK_COLOR)) && (!sameColor(color, INVIS_COLOR)))
					|| status_flags & SPECIAL
				)
			)
		)
		{
			if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F)))
				SetPrimType (lpPrim, STAMP_PRIM);
			else if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)))
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
			else if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)))
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B));
			else if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)))
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
			else if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)))
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09));
			else
			{
				ProcessSound (SetAbsSoundIndex (
						/* CLOAKING_OFF */
					StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 2), ElementPtr);
			
				SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
			}
			
			ElementPtr->state_flags |= CHANGING;
			status_flags &= ~SPECIAL;
			StarShipPtr->special_counter = 0;
		}
		else if ( (!sameColor (color, BLACK_COLOR))
				&& (!sameColor (color, INVIS_COLOR)))
		{
			if (sameColor (color, BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)))
			{
				if(PlayerControl[ElementPtr->playerNr] & HUMAN_CONTROL)
					SetPrimColor (lpPrim, INVIS_COLOR);
				else
					SetPrimColor (lpPrim, BLACK_COLOR);
				Untarget (ElementPtr);
			}
			else if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09)))
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
			else if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)))
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x1F), 0x09));
			else if (sameColor (color,
					BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B)))
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
			else
				SetPrimColor (lpPrim,
						BUILD_COLOR (MAKE_RGB15 (0x0A, 0x1F, 0x1F), 0x0B));

			ElementPtr->state_flags |= CHANGING;
		}
	}

	if ((status_flags & SPECIAL)
			&& StarShipPtr->special_counter == 0
			&& DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST))
	{
		SetPrimColor (lpPrim, BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
		SetPrimType (lpPrim, STAMPFILL_PRIM);

		ProcessSound (SetAbsSoundIndex (
						/* CLOAKING_ON */
				StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1),
				ElementPtr);
		StarShipPtr->special_counter =
				StarShipPtr->RaceDescPtr->characteristics.special_wait;

		ElementPtr->state_flags |= CHANGING;
	}
}
Beispiel #22
0
static void
arilou_preprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	if (!(ElementPtr->state_flags & NONSOLID))
	{
		if (ElementPtr->thrust_wait == 0)
		{
			ZeroVelocityComponents (&ElementPtr->velocity);
			StarShipPtr->cur_status_flags &= ~SHIP_AT_MAX_SPEED;
		}

		if ((StarShipPtr->cur_status_flags & SPECIAL)
				&& StarShipPtr->special_counter == 0
				&& DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST))
		{
			/* Special key is pressed; start teleport */
#define HYPER_LIFE 5
			ZeroVelocityComponents (&ElementPtr->velocity);
			StarShipPtr->cur_status_flags &=
					~(SHIP_AT_MAX_SPEED | LEFT | RIGHT | THRUST | WEAPON);

			ElementPtr->state_flags |= NONSOLID | FINITE_LIFE | CHANGING;
			ElementPtr->life_span = HYPER_LIFE;

			ElementPtr->next.image.farray =
					StarShipPtr->RaceDescPtr->ship_data.special;
			ElementPtr->next.image.frame =
					StarShipPtr->RaceDescPtr->ship_data.special[0];

			ProcessSound (SetAbsSoundIndex (
							/* HYPERJUMP */
					StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);
			StarShipPtr->special_counter =
					StarShipPtr->RaceDescPtr->characteristics.special_wait;
		}
	}
	else if (ElementPtr->next.image.farray == StarShipPtr->RaceDescPtr->ship_data.special)
	{
		COUNT life_span;

		StarShipPtr->cur_status_flags =
				(StarShipPtr->cur_status_flags
				& ~(LEFT | RIGHT | THRUST | WEAPON | SPECIAL))
				| (StarShipPtr->old_status_flags
				& (LEFT | RIGHT | THRUST | WEAPON | SPECIAL));
		++StarShipPtr->weapon_counter;
		++StarShipPtr->special_counter;
		++StarShipPtr->energy_counter;
		++ElementPtr->turn_wait;
		++ElementPtr->thrust_wait;

		if ((life_span = ElementPtr->life_span) == NORMAL_LIFE)
		{
			/* Ending teleport */
			ElementPtr->state_flags &= ~(NONSOLID | FINITE_LIFE);
			ElementPtr->state_flags |= APPEARING;
			ElementPtr->current.image.farray =
					ElementPtr->next.image.farray =
					StarShipPtr->RaceDescPtr->ship_data.ship;
			ElementPtr->current.image.frame =
					ElementPtr->next.image.frame =
					SetAbsFrameIndex (StarShipPtr->RaceDescPtr->ship_data.ship[0],
					StarShipPtr->ShipFacing);
			InitIntersectStartPoint (ElementPtr);
		}
		else
		{
			/* Teleporting in progress */
			--life_span;
			if (life_span != 2)
			{
				if (life_span < 2)
					ElementPtr->next.image.frame =
							DecFrameIndex (ElementPtr->next.image.frame);
				else
					ElementPtr->next.image.frame =
							IncFrameIndex (ElementPtr->next.image.frame);
			}
			else
			{
				ElementPtr->next.location.x =
						WRAP_X (DISPLAY_ALIGN_X (TFB_Random ()));
				ElementPtr->next.location.y =
						WRAP_Y (DISPLAY_ALIGN_Y (TFB_Random ()));
			}
		}

		ElementPtr->state_flags |= CHANGING;
	}
}
Beispiel #23
0
static void
pkunk_preprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	if (ElementPtr->state_flags & APPEARING)
	{
		HELEMENT hPhoenix = 0;

		if ((BYTE)TFB_Random () & 1)
			hPhoenix = AllocElement ();

		if (hPhoenix)
		{
			ELEMENT *PhoenixPtr;

			LockElement (hPhoenix, &PhoenixPtr);
			PhoenixPtr->playerNr = ElementPtr->playerNr;
			PhoenixPtr->state_flags = FINITE_LIFE | NONSOLID | IGNORE_SIMILAR;
			PhoenixPtr->life_span = 1;

			PhoenixPtr->death_func = intercept_pkunk_death;

			SetElementStarShip (PhoenixPtr, StarShipPtr);

			UnlockElement (hPhoenix);
			InsertElement (hPhoenix, GetHeadElement ());
		}
		StarShipPtr->RaceDescPtr->data = (intptr_t) hPhoenix;

		if (ElementPtr->hTarget == 0)
			StarShipPtr->RaceDescPtr->preprocess_func = 0;
		else
		{
			COUNT angle, facing;

			ProcessSound (SetAbsSoundIndex (
					StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1
					), ElementPtr);

			ElementPtr->life_span = PHOENIX_LIFE;
			SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex],
					NO_PRIM);
			ElementPtr->state_flags |= NONSOLID | FINITE_LIFE | CHANGING;

			facing = StarShipPtr->ShipFacing;
			for (angle = OCTANT; angle < FULL_CIRCLE; angle += QUADRANT)
			{
				StarShipPtr->ShipFacing = NORMALIZE_FACING (
						facing + ANGLE_TO_FACING (angle)
						);
				phoenix_transition (ElementPtr);
			}
			StarShipPtr->ShipFacing = facing;
		}
	}

	if (StarShipPtr->RaceDescPtr->preprocess_func)
	{
		StarShipPtr->cur_status_flags &=
				~(LEFT | RIGHT | THRUST | WEAPON | SPECIAL);

		if (ElementPtr->life_span == NORMAL_LIFE)
		{
			ElementPtr->current.image.frame =
					ElementPtr->next.image.frame =
					SetEquFrameIndex (
					ElementPtr->current.image.farray[0],
					ElementPtr->current.image.frame);
			SetPrimType (&(GLOBAL (DisplayArray))[ElementPtr->PrimIndex],
					STAMP_PRIM);
			InitIntersectStartPoint (ElementPtr);
			InitIntersectEndPoint (ElementPtr);
			InitIntersectFrame (ElementPtr);
			ZeroVelocityComponents (&ElementPtr->velocity);
			ElementPtr->state_flags &= ~(NONSOLID | FINITE_LIFE);
			ElementPtr->state_flags |= CHANGING;

			StarShipPtr->RaceDescPtr->preprocess_func = 0;
		}
	}
}
static void
thraddash_preprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;
	
	GetElementStarShip (ElementPtr, &StarShipPtr);
	
	// Switch side guns after every shot.
	if (StarShipPtr->weapon_counter == 1)
	{
		if (StarShipPtr->static_counter == 0)
			++StarShipPtr->static_counter;
		else
			StarShipPtr->static_counter = 0;
	}

	if (!(StarShipPtr->cur_status_flags & SPECIAL))
	{
		if (StarShipPtr->old_status_flags & SPECIAL
				&& StarShipPtr->cur_status_flags & SHIP_AT_MAX_SPEED)
			StarShipPtr->cur_status_flags |= SHIP_BEYOND_MAX_SPEED;
	}
	else if (StarShipPtr->RaceDescPtr->ship_info.energy_level >= SPECIAL_ENERGY_COST)
	{
		COUNT max_thrust, thrust_increment;
		STATUS_FLAGS thrust_status;
		HELEMENT hTrailElement;

		if (!(StarShipPtr->old_status_flags & SPECIAL))
			StarShipPtr->cur_status_flags &=
					~(SHIP_AT_MAX_SPEED | SHIP_BEYOND_MAX_SPEED);

		if (ElementPtr->thrust_wait == 0)
			++ElementPtr->thrust_wait;

		thrust_increment = StarShipPtr->RaceDescPtr->characteristics.thrust_increment;
		max_thrust = StarShipPtr->RaceDescPtr->characteristics.max_thrust;
		StarShipPtr->RaceDescPtr->characteristics.thrust_increment = SPECIAL_THRUST_INCREMENT;
		StarShipPtr->RaceDescPtr->characteristics.max_thrust = SPECIAL_MAX_THRUST;

		thrust_status = inertial_thrust (ElementPtr);
		StarShipPtr->cur_status_flags &=
				~(SHIP_AT_MAX_SPEED
				| SHIP_BEYOND_MAX_SPEED
				| SHIP_IN_GRAVITY_WELL);
		StarShipPtr->cur_status_flags |= thrust_status;

		StarShipPtr->RaceDescPtr->characteristics.thrust_increment = thrust_increment;
		StarShipPtr->RaceDescPtr->characteristics.max_thrust = max_thrust;
		
		// Reduce afterburner energy consumption to 2/3.
		if (StarShipPtr->special_counter == 0)
		{
			DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST);

			StarShipPtr->special_counter = 3;
		}
		else if (StarShipPtr->special_counter == 2)
			DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST);
		
		{
			MISSILE_BLOCK MissileBlock;

			MissileBlock.cx = ElementPtr->next.location.x;
			MissileBlock.cy = ElementPtr->next.location.y;
			MissileBlock.farray = StarShipPtr->RaceDescPtr->ship_data.special;
			MissileBlock.face = 0;
			MissileBlock.index = GetFrameCount (StarShipPtr->RaceDescPtr->ship_data.special[0]) - 1;
			MissileBlock.sender = ElementPtr->playerNr;
			MissileBlock.flags = IGNORE_SIMILAR;
			MissileBlock.pixoffs = 0;
			MissileBlock.speed = 0;
			MissileBlock.hit_points = NAPALM_HITS;
			MissileBlock.damage = NAPALM_DAMAGE;
			MissileBlock.life = NAPALM_LIFE;
			MissileBlock.preprocess_func = flame_napalm_preprocess;
			MissileBlock.blast_offs = NAPALM_OFFSET;

			hTrailElement = initialize_missile (&MissileBlock);
			if (hTrailElement)
			{
				ELEMENT *TrailElementPtr;

				LockElement (hTrailElement, &TrailElementPtr);
				SetElementStarShip (TrailElementPtr, StarShipPtr);
				TrailElementPtr->hTarget = 0;
				TrailElementPtr->turn_wait = NAPALM_FADE_WAIT;

				TrailElementPtr->state_flags |= NONSOLID;
				SetPrimType (
						&(GLOBAL (DisplayArray))[TrailElementPtr->PrimIndex],
						NO_PRIM
						);

						/* normally done during preprocess, but because
						 * object is being inserted at head rather than
						 * appended after tail it may never get preprocessed.
						 */
				TrailElementPtr->next = TrailElementPtr->current;
				TrailElementPtr->state_flags |= PRE_PROCESS;

				UnlockElement (hTrailElement);
				InsertElement (hTrailElement, GetHeadElement ());
				
				ProcessSound (SetAbsSoundIndex (
						/* BURNT_TOAST */
					StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), ElementPtr);
			}
		}
	}
	else if (StarShipPtr->RaceDescPtr->ship_info.energy_level < SPECIAL_ENERGY_COST)
		DeltaEnergy (ElementPtr, -SPECIAL_ENERGY_COST); /* so text will flash */
}