Example #1
0
static inline COUNT
randomFrameIndex (SEQUENCE *pSeq, COUNT from)
{
	ANIMATION_DESC *ADPtr = pSeq->ADPtr;

	return from	+ TFB_Random () % (ADPtr->NumFrames - from);
}
Example #2
0
static void
shofixti_intelligence (PELEMENT ShipPtr, PEVALUATE_DESC ObjectsOfConcern, COUNT ConcernCounter)
{
	STARSHIPPTR StarShipPtr;

	ship_intelligence (ShipPtr,
			ObjectsOfConcern, ConcernCounter);

	GetElementStarShip (ShipPtr, &StarShipPtr);
	if (StarShipPtr->special_counter == 0)
	{
		if (StarShipPtr->ship_input_state & SPECIAL)
			StarShipPtr->ship_input_state &= ~SPECIAL;
		else
		{
			PEVALUATE_DESC lpWeaponEvalDesc, lpShipEvalDesc;

			lpWeaponEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
			lpShipEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
			if (StarShipPtr->RaceDescPtr->ship_data.special[0]
					&& (GetFrameCount (StarShipPtr->RaceDescPtr->ship_data.captain_control.special)
					- GetFrameIndex (StarShipPtr->RaceDescPtr->ship_data.captain_control.special) > 5
					|| (lpShipEvalDesc->ObjectPtr != NULL_PTR
					&& lpShipEvalDesc->which_turn <= 4)
					|| (lpWeaponEvalDesc->ObjectPtr != NULL_PTR
								/* means IMMEDIATE WEAPON */
					&& (((lpWeaponEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP)
					&& ShipPtr->crew_level == 1)
					|| (PlotIntercept (lpWeaponEvalDesc->ObjectPtr, ShipPtr, 2, 0)
					&& lpWeaponEvalDesc->ObjectPtr->mass_points >= ShipPtr->crew_level
					&& (TFB_Random () & 1))))))
				StarShipPtr->ship_input_state |= SPECIAL;
		}
	}
}
Example #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;
	}
}
Example #4
0
static void
pkunk_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	STARSHIP *StarShipPtr;
	HELEMENT hPhoenix;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	hPhoenix = (HELEMENT) StarShipPtr->RaceDescPtr->data;
	if (hPhoenix && (StarShipPtr->control & STANDARD_RATING))
	{
		RemoveElement (hPhoenix);
		FreeElement (hPhoenix);
		StarShipPtr->RaceDescPtr->data = 0;
	}

	if (StarShipPtr->RaceDescPtr->ship_info.energy_level <
			StarShipPtr->RaceDescPtr->ship_info.max_energy
			&& (StarShipPtr->special_counter == 0
			|| (BYTE)TFB_Random () < 20))
		StarShipPtr->ship_input_state |= SPECIAL;
	else
		StarShipPtr->ship_input_state &= ~SPECIAL;
	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);
}
Example #5
0
static bool
GeneratePkunk_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
		COUNT *whichNode)
{
	if (matchWorld (solarSys, world, 0, MATCH_PLANET))
	{
		COUNT i;
		COUNT nodeI;
		DWORD rand_val;
		DWORD old_rand;

		old_rand = TFB_SeedRandom (
				solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]);

		nodeI = 0;
		i = 0;
		do
		{
			rand_val = TFB_Random ();
			solarSys->SysInfo.PlanetInfo.CurPt.x =
					((LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
			solarSys->SysInfo.PlanetInfo.CurPt.y =
					((LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
			// JMS: No more clear spindles!
			/*if (!GET_GAME_STATE (CLEAR_SPINDLE))
				solarSys->SysInfo.PlanetInfo.CurType = 0;
				else*/
			solarSys->SysInfo.PlanetInfo.CurType = 1;
			solarSys->SysInfo.PlanetInfo.CurDensity = 0;
			if (solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
					& (1L << i))
			{
				solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
						&= ~(1L << i);

				// JMS: No more clear spindles!
				/*if (!GET_GAME_STATE (CLEAR_SPINDLE))
				{
					SetLanderTakeoff ();

					SET_GAME_STATE (CLEAR_SPINDLE, 1);
					SET_GAME_STATE (CLEAR_SPINDLE_ON_SHIP, 1);
					}*/
			}
			if (nodeI >= *whichNode
					&& !(solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
					& (1L << i)))
				break;
			++nodeI;
		} while (++i < 16);
		*whichNode = nodeI;

		TFB_SeedRandom (old_rand);
		return true;
	}

	*whichNode = 0;
	return true;
}
Example #6
0
static inline DWORD
randomRestartRate (SEQUENCE *pSeq)
{
	ANIMATION_DESC *ADPtr = pSeq->ADPtr;

	return ADPtr->BaseRestartRate +
			TFB_Random () % (ADPtr->RandomRestartRate + 1);
}
Example #7
0
static void
arilou_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	StarShipPtr->ship_input_state |= THRUST;

	ObjectsOfConcern[ENEMY_SHIP_INDEX].MoveState = ENTICE;
	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	if (StarShipPtr->special_counter == 0)
	{
		EVALUATE_DESC *lpEvalDesc;

		StarShipPtr->ship_input_state &= ~SPECIAL;

		lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
		if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 6)
		{
			BOOLEAN IsTrackingWeapon;
			STARSHIP *EnemyStarShipPtr;

			GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr);
			if (((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags
					& SEEKING_WEAPON) &&
					lpEvalDesc->ObjectPtr->next.image.farray ==
					EnemyStarShipPtr->RaceDescPtr->ship_data.weapon) ||
					((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags
					& SEEKING_SPECIAL) &&
					lpEvalDesc->ObjectPtr->next.image.farray ==
					EnemyStarShipPtr->RaceDescPtr->ship_data.special))
				IsTrackingWeapon = TRUE;
			else
				IsTrackingWeapon = FALSE;

			// JMS: Added the GASSY_SUBSTANCE clauses to prevent 'long teleport' if Baul gas is sticking to the Arilou ship.
			if (((lpEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP) /* means IMMEDIATE WEAPON */
					|| (IsTrackingWeapon && (lpEvalDesc->which_turn == 1
					|| (lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT))) /* FIGHTERS!!! */
					|| (PlotIntercept (lpEvalDesc->ObjectPtr, ShipPtr, 3, 0)
						&& (!(lpEvalDesc->ObjectPtr->state_flags & GASSY_SUBSTANCE) // Ignore stuck gas
							|| (lpEvalDesc->ObjectPtr->state_flags & GASSY_SUBSTANCE && EnemyStarShipPtr->ship_input_state & WEAPON
								&& ObjectsOfConcern[ENEMY_SHIP_INDEX].which_turn <= 20) // If sticking to gas, teleport when Baul is near&firing primary
							|| (lpEvalDesc->ObjectPtr->state_flags & GASSY_SUBSTANCE && lpEvalDesc->ObjectPtr->state_flags & IGNORE_VELOCITY))) // non-stuck gas
					)
					&& !(TFB_Random () & 3))
			{
				StarShipPtr->ship_input_state &= ~(LEFT | RIGHT | THRUST | WEAPON);
				StarShipPtr->ship_input_state |= SPECIAL;
			}
		}
	}
	if (StarShipPtr->RaceDescPtr->ship_info.energy_level <= SPECIAL_ENERGY_COST << 1)
		StarShipPtr->ship_input_state &= ~WEAPON;
}
static void
ExitConversation (RESPONSE_REF R)
{
	SET_GAME_STATE (BATTLE_SEGUE, 1);

	if (PLAYER_SAID (R, bye_homeworld))
		NPCPhrase (GOODBYE_AND_DIE_HOMEWORLD);
	else if (PLAYER_SAID (R, bye_royalist))
		NPCPhrase (GOODBYE_AND_DIE_ROYALIST);
	else if (PLAYER_SAID (R, i_demand_you_ally_homeworld0))
	{
		NPCPhrase (ENEMY_MUST_DIE);

		SET_GAME_STATE (NO_YEHAT_ALLY_HOME, 1);
	}
	else if (PLAYER_SAID (R, bye_space))
	{
		if ((BYTE)TFB_Random () & 1)
			NPCPhrase (GOODBYE_AND_DIE_SPACE);
		else
		{
			NPCPhrase (GO_IN_PEACE);

			SET_GAME_STATE (BATTLE_SEGUE, 0);
		}
	}
	else if (PLAYER_SAID (R, not_here)
			|| PLAYER_SAID (R, not_send))
	{
		switch (GET_GAME_STATE (YEHAT_REBEL_VISITS))
		{
			case 0:
				NPCPhrase (JUST_A_TRICK_1);
				break;
			case 1:
				NPCPhrase (JUST_A_TRICK_2);
				break;
		}
		SET_GAME_STATE (YEHAT_REBEL_VISITS, 1);
	}
	else if (PLAYER_SAID (R, ok_send))
	{
		NPCPhrase (WE_REVOLT);

		SET_GAME_STATE (BATTLE_SEGUE, 0);
		SET_GAME_STATE (YEHAT_CIVIL_WAR, 1);
		SET_GAME_STATE (YEHAT_VISITS, 0);
		SET_GAME_STATE (YEHAT_HOME_VISITS, 0);
		SET_GAME_STATE (YEHAT_REBEL_VISITS, 0);
		SET_GAME_STATE (YEHAT_REBEL_INFO, 0);
		SET_GAME_STATE (YEHAT_REBEL_TOLD_PKUNK, 0);
		SET_GAME_STATE (NO_YEHAT_INFO, 0);

		AddEvent (RELATIVE_EVENT, 0, 0, 0, YEHAT_REBEL_EVENT);
	}
}
Example #9
0
static bool
GenerateSupox_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
		COUNT *whichNode)
{
	if (matchWorld (solarSys, world, 0, MATCH_PLANET))
	{
		COUNT i;
		COUNT nodeI;
		DWORD rand_val;
		DWORD old_rand;

		old_rand = TFB_SeedRandom (
				solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]);

		nodeI = 0;
		i = 0;
		do
		{
			rand_val = TFB_Random ();
			solarSys->SysInfo.PlanetInfo.CurPt.x =
					(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
			solarSys->SysInfo.PlanetInfo.CurPt.y =
					(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
			if (!GET_GAME_STATE (ULTRON_CONDITION))
				solarSys->SysInfo.PlanetInfo.CurType = 0;
			else
				solarSys->SysInfo.PlanetInfo.CurType = 1;
			solarSys->SysInfo.PlanetInfo.CurDensity = 0;
			if (solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
					& (1L << i))
			{
				solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
						&= ~(1L << i);

				if (!GET_GAME_STATE (ULTRON_CONDITION))
				{
					SetLanderTakeoff ();

					SET_GAME_STATE (ULTRON_CONDITION, 1);
				}
			}
			if (nodeI >= *whichNode
					&& !(solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
					& (1L << i)))
				break;
			++nodeI;
		} while (++i < 16);
		*whichNode = nodeI;

		TFB_SeedRandom (old_rand);
		return true;
	}

	*whichNode = 0;
	return true;
}
Example #10
0
static void
bubble_preprocess (ELEMENT *ElementPtr)
{
	BYTE thrust_wait, turn_wait;

	thrust_wait = HINIBBLE (ElementPtr->turn_wait);
	turn_wait = LONIBBLE (ElementPtr->turn_wait);
	if (thrust_wait > 0)
		--thrust_wait;
	else
	{
		ElementPtr->next.image.frame =
				IncFrameIndex (ElementPtr->current.image.frame);
		ElementPtr->state_flags |= CHANGING;

		thrust_wait = (BYTE)((COUNT)TFB_Random () & 3);
	}

	if (turn_wait > 0)
		--turn_wait;
	else
	{
		COUNT facing;
		SIZE delta_facing;

		facing = NORMALIZE_FACING (ANGLE_TO_FACING (
				GetVelocityTravelAngle (&ElementPtr->velocity)));
		if ((delta_facing = TrackShip (ElementPtr, &facing)) == -1)
			facing = (COUNT)TFB_Random ();
		else if (delta_facing <= ANGLE_TO_FACING (HALF_CIRCLE))
			facing += (COUNT)TFB_Random () & (ANGLE_TO_FACING (HALF_CIRCLE) - 1);
		else
			facing -= (COUNT)TFB_Random () & (ANGLE_TO_FACING (HALF_CIRCLE) - 1);
		SetVelocityVector (&ElementPtr->velocity,
				MISSILE_SPEED, facing);

#define TRACK_WAIT 2
		turn_wait = TRACK_WAIT;
	}

	ElementPtr->turn_wait = MAKE_BYTE (turn_wait, thrust_wait);
}
Example #11
0
void
spawn_planet (void)
{
	HELEMENT hPlanetElement;
	
	hPlanetElement = AllocElement ();
	if (hPlanetElement)
	{
		ELEMENT *PlanetElementPtr;
		extern FRAME planet[];

		LockElement (hPlanetElement, &PlanetElementPtr);
		PlanetElementPtr->playerNr = NEUTRAL_PLAYER_NUM;
		PlanetElementPtr->hit_points = 200;
		PlanetElementPtr->state_flags = APPEARING;
		PlanetElementPtr->life_span = NORMAL_LIFE + 1;
		SetPrimType (&DisplayArray[PlanetElementPtr->PrimIndex], STAMP_PRIM);
		PlanetElementPtr->current.image.farray = planet;
		PlanetElementPtr->current.image.frame =
				PlanetElementPtr->current.image.farray[0];
		PlanetElementPtr->collision_func = collision;
		PlanetElementPtr->postprocess_func =
				(void (*) (struct element *ElementPtr))CalculateGravity;
		ZeroVelocityComponents (&PlanetElementPtr->velocity);
		do
		{
			PlanetElementPtr->current.location.x =
					WRAP_X (DISPLAY_ALIGN_X (TFB_Random ()));
			PlanetElementPtr->current.location.y =
					WRAP_Y (DISPLAY_ALIGN_Y (TFB_Random ()));
		} while (CalculateGravity (PlanetElementPtr)
				|| Overlap (PlanetElementPtr));
		PlanetElementPtr->mass_points = PlanetElementPtr->hit_points;

		PlanetElementPtr->triggers_teleport_safety = TRUE;

		UnlockElement (hPlanetElement);

		PutElement (hPlanetElement);
	}
}
Example #12
0
static void
doggy_preprocess (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ElementPtr, &StarShipPtr);
	++StarShipPtr->special_counter;
	if (ElementPtr->thrust_wait > 0) /* could be non-zero after a collision */
		--ElementPtr->thrust_wait;
	else
	{
		COUNT facing, orig_facing;
		SIZE delta_facing;

		facing = orig_facing =
				NORMALIZE_FACING (ANGLE_TO_FACING (
				GetVelocityTravelAngle (&ElementPtr->velocity)
				));
		if ((delta_facing = TrackShip (ElementPtr, &facing)) < 0)
			facing = NORMALIZE_FACING (TFB_Random ());
		else
		{
			ELEMENT *ShipPtr;

			LockElement (ElementPtr->hTarget, &ShipPtr);
			facing = NORMALIZE_FACING (ANGLE_TO_FACING (
					ARCTAN (ShipPtr->current.location.x -
					ElementPtr->current.location.x,
					ShipPtr->current.location.y -
					ElementPtr->current.location.y)
					));
			delta_facing = NORMALIZE_FACING (facing -
					GetFrameIndex (ShipPtr->current.image.frame));
			UnlockElement (ElementPtr->hTarget);

			if (delta_facing > ANGLE_TO_FACING (HALF_CIRCLE - OCTANT) &&
					delta_facing < ANGLE_TO_FACING (HALF_CIRCLE + OCTANT))
			{
				if (delta_facing >= ANGLE_TO_FACING (HALF_CIRCLE))
					facing -= ANGLE_TO_FACING (QUADRANT);
				else
					facing += ANGLE_TO_FACING (QUADRANT);
			}

			facing = NORMALIZE_FACING (facing);
		}

		if (facing != orig_facing)
			SetVelocityVector (&ElementPtr->velocity,
					DOGGY_SPEED, facing);
	}
}
Example #13
0
static void
arilou_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	STARSHIP *StarShipPtr;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	StarShipPtr->ship_input_state |= THRUST;

	 ObjectsOfConcern[ENEMY_SHIP_INDEX].MoveState = ENTICE;
	ship_intelligence (ShipPtr, ObjectsOfConcern, ConcernCounter);

	if (StarShipPtr->special_counter == 0)
	{
		EVALUATE_DESC *lpEvalDesc;

		StarShipPtr->ship_input_state &= ~SPECIAL;

		lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
		if (lpEvalDesc->ObjectPtr && lpEvalDesc->which_turn <= 6)
		{
			BOOLEAN IsTrackingWeapon;
			STARSHIP *EnemyStarShipPtr;

			GetElementStarShip (lpEvalDesc->ObjectPtr, &EnemyStarShipPtr);
			if (((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags
					& SEEKING_WEAPON) &&
					lpEvalDesc->ObjectPtr->next.image.farray ==
					EnemyStarShipPtr->RaceDescPtr->ship_data.weapon) ||
					((EnemyStarShipPtr->RaceDescPtr->ship_info.ship_flags
					& SEEKING_SPECIAL) &&
					lpEvalDesc->ObjectPtr->next.image.farray ==
					EnemyStarShipPtr->RaceDescPtr->ship_data.special))
				IsTrackingWeapon = TRUE;
			else
				IsTrackingWeapon = FALSE;

			if (((lpEvalDesc->ObjectPtr->state_flags & PLAYER_SHIP) /* means IMMEDIATE WEAPON */
					|| (IsTrackingWeapon && (lpEvalDesc->which_turn == 1
					|| (lpEvalDesc->ObjectPtr->state_flags & CREW_OBJECT))) /* FIGHTERS!!! */
					|| PlotIntercept (lpEvalDesc->ObjectPtr, ShipPtr, 3, 0))
					&& !(TFB_Random () & 3))
			{
				StarShipPtr->ship_input_state &= ~(LEFT | RIGHT | THRUST | WEAPON);
				StarShipPtr->ship_input_state |= SPECIAL;
			}
		}
	}
	if (StarShipPtr->RaceDescPtr->ship_info.energy_level <= SPECIAL_ENERGY_COST << 1)
		StarShipPtr->ship_input_state &= ~WEAPON;
}
static bool
GenerateSaMatra_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
{
	GenerateDefault_generateMoons (solarSys, planet);

	if (matchWorld (solarSys, planet, 4, MATCH_PLANET))
	{
		COUNT angle;
		DWORD rand_val;

		solarSys->MoonDesc[0].data_index = SA_MATRA;
		solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS + (2 * MOON_DELTA);
		rand_val = TFB_Random ();
		angle = NORMALIZE_ANGLE (LOWORD (rand_val));
		solarSys->MoonDesc[0].location.x =
				COSINE (angle, solarSys->MoonDesc[0].radius);
		solarSys->MoonDesc[0].location.y =
				SINE (angle, solarSys->MoonDesc[0].radius);
	}

	return true;
}
Example #15
0
static void
SetupAmbientSequences (SEQUENCE *pSeq, COUNT Num)
{
	COUNT i;
	
	for (i = 0; i < Num; ++i, ++pSeq)
	{
		ANIMATION_DESC *ADPtr = &CommData.AlienAmbientArray[i];

		memset (pSeq, 0, sizeof (*pSeq));

		pSeq->ADPtr = ADPtr;
		if (ADPtr->AnimFlags & COLORXFORM_ANIM)
			pSeq->AnimType = COLOR_ANIM;
		else
			pSeq->AnimType = PICTURE_ANIM;
		pSeq->Direction = UP_DIR;
		pSeq->FramesLeft = ADPtr->NumFrames;
		// Default: first frame is neutral
		if (ADPtr->AnimFlags & RANDOM_ANIM)
		{	// Set a random frame/colormap
			pSeq->NextIndex = TFB_Random () % ADPtr->NumFrames;
		}
		else if (ADPtr->AnimFlags & YOYO_ANIM)
		{	// Skip the first frame/colormap (it's neutral)
			pSeq->NextIndex = 1;
			--pSeq->FramesLeft;
		}
		else if (ADPtr->AnimFlags & CIRCULAR_ANIM)
		{	// Exception that makes everything more painful:
			// *Last* frame is neutral
			pSeq->CurIndex = ADPtr->NumFrames - 1;
			pSeq->NextIndex = 0;
		}

		pSeq->Alarm = randomRestartRate (pSeq) + 1;
	}
}
Example #16
0
static bool
GenerateBurvixese_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
{
	GenerateDefault_generateMoons (solarSys, planet);

	if (matchWorld (solarSys, planet, 0, MATCH_PLANET))
	{
		COUNT angle;
		DWORD rand_val;

		solarSys->MoonDesc[0].data_index = SELENIC_WORLD;
		solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS
				+ (MAX_MOONS - 1) * MOON_DELTA;
		rand_val = TFB_Random ();
		angle = NORMALIZE_ANGLE (LOWORD (rand_val));
		solarSys->MoonDesc[0].location.x =
				COSINE (angle, solarSys->MoonDesc[0].radius);
		solarSys->MoonDesc[0].location.y =
				SINE (angle, solarSys->MoonDesc[0].radius);
		ComputeSpeed(&solarSys->MoonDesc[0], TRUE, 1);
	}
	return true;
}
static bool
GenerateChmmr_generateMoons (SOLARSYS_STATE *solarSys, PLANET_DESC *planet)
{
	GenerateDefault_generateMoons (solarSys, planet);

	if (matchWorld (solarSys, planet, 1, MATCH_PLANET))
	{
		COUNT angle;
		DWORD rand_val;

		solarSys->MoonDesc[0].data_index = HIERARCHY_STARBASE;
		solarSys->MoonDesc[0].radius = MIN_MOON_RADIUS;
		rand_val = TFB_Random ();
		angle = NORMALIZE_ANGLE (LOWORD (rand_val));
		solarSys->MoonDesc[0].location.x =
				COSINE (angle, solarSys->MoonDesc[0].radius);
		solarSys->MoonDesc[0].location.y =
				SINE (angle, solarSys->MoonDesc[0].radius);
		ComputeSpeed(&solarSys->MoonDesc[0], TRUE, 1);
	}

	return true;
}
Example #18
0
void
GeneratePkunk (BYTE control)
{
	switch (control)
	{
		case GENERATE_ENERGY:
			if (pSolarSysState->pOrbitalDesc == &pSolarSysState->PlanetDesc[0])
			{
				COUNT i, which_node;
				DWORD rand_val, old_rand;

				old_rand = TFB_SeedRandom (
						pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]
						);

				which_node = i = 0;
				do
				{
					rand_val = TFB_Random ();
					pSolarSysState->SysInfo.PlanetInfo.CurPt.x =
							(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
					pSolarSysState->SysInfo.PlanetInfo.CurPt.y =
							(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
					if (!GET_GAME_STATE (CLEAR_SPINDLE))
						pSolarSysState->SysInfo.PlanetInfo.CurType = 0;
					else
						pSolarSysState->SysInfo.PlanetInfo.CurType = 1;
					pSolarSysState->SysInfo.PlanetInfo.CurDensity = 0;
					if (pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
							& (1L << i))
					{
						pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
								&= ~(1L << i);

						if (!GET_GAME_STATE (CLEAR_SPINDLE))
						{
							((PPLANETSIDE_DESC)pMenuState->ModuleFrame)->InTransit = TRUE;

							SET_GAME_STATE (CLEAR_SPINDLE, 1);
							SET_GAME_STATE (CLEAR_SPINDLE_ON_SHIP, 1);
						}
					}
					if (which_node >= pSolarSysState->CurNode
							&& !(pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
							& (1L << i)))
						break;
					++which_node;
				} while (++i < 16);
				pSolarSysState->CurNode = which_node;

				TFB_SeedRandom (old_rand);
				break;
			}
			pSolarSysState->CurNode = 0;
			break;
		case GENERATE_PLANETS:
		{
			COUNT angle;

			GenerateRandomIP (GENERATE_PLANETS);
			pSolarSysState->PlanetDesc[0].data_index = WATER_WORLD;
			pSolarSysState->PlanetDesc[0].NumPlanets = 1;
			pSolarSysState->PlanetDesc[0].radius = EARTH_RADIUS * 104L / 100;
			angle = ARCTAN (
					pSolarSysState->PlanetDesc[0].location.x,
					pSolarSysState->PlanetDesc[0].location.y
					);
			pSolarSysState->PlanetDesc[0].location.x =
					COSINE (angle, pSolarSysState->PlanetDesc[0].radius);
			pSolarSysState->PlanetDesc[0].location.y =
					SINE (angle, pSolarSysState->PlanetDesc[0].radius);
			break;
		}
		case GENERATE_ORBITAL:
			if (pSolarSysState->pOrbitalDesc == &pSolarSysState->PlanetDesc[0])
			{
				if (ActivateStarShip (PKUNK_SHIP, SPHERE_TRACKING))
				{
					NotifyOthers (PKUNK_SHIP, (BYTE)~0);
					PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
					ReinitQueue (&GLOBAL (npc_built_ship_q));

					CloneShipFragment (PKUNK_SHIP,
							&GLOBAL (npc_built_ship_q), INFINITE_FLEET);

					pSolarSysState->MenuState.Initialized += 2;
					GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
					SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
					InitCommunication (PKUNK_CONVERSATION);
					pSolarSysState->MenuState.Initialized -= 2;

					if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
					{
						GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY;
						ReinitQueue (&GLOBAL (npc_built_ship_q));
						GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP);
					}
					break;
				}
				else
				{
					LoadStdLanderFont (&pSolarSysState->SysInfo.PlanetInfo);
					pSolarSysState->PlanetSideFrame[1] =
							CaptureDrawable (
							LoadGraphic (RUINS_MASK_PMAP_ANIM)
							);
					pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
							CaptureStringTable (
									LoadStringTable (PKUNK_RUINS_STRTAB)
									);
					if (GET_GAME_STATE (CLEAR_SPINDLE))
						pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
								SetAbsStringTableIndex (
								pSolarSysState->SysInfo.PlanetInfo.DiscoveryString,
								1
								);
				}
			}
		default:
			GenerateRandomIP (control);
			break;
	}
}
Example #19
0
static COUNT
CalcLifeForms (SYSTEM_INFO *SysInfoPtr, COUNT which_life)
{
	COUNT num_life_forms;

	num_life_forms = 0;
	if (PLANSIZE (SysInfoPtr->PlanetInfo.PlanDataPtr->Type) == GAS_GIANT)
		SysInfoPtr->PlanetInfo.LifeChance = -1;
	else
	{
#define MIN_LIFE_CHANCE 10
		SIZE life_var;

		life_var = 0;

		if (SysInfoPtr->PlanetInfo.SurfaceTemperature < -151)
			life_var -= 300;
		else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < -51)
			life_var -= 100;
		else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 0)
			life_var += 100;
		else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 50)
			life_var += 300;
		else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 150)
			life_var += 50;
		else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 250)
			life_var -= 100;
		else if (SysInfoPtr->PlanetInfo.SurfaceTemperature < 500)
			life_var -= 400;
		else
			life_var -= 800;

		if (SysInfoPtr->PlanetInfo.AtmoDensity == 0)
			life_var -= 1000;
		else if (SysInfoPtr->PlanetInfo.AtmoDensity < 15)
			life_var += 100;
		else if (SysInfoPtr->PlanetInfo.AtmoDensity < 30)
			life_var += 200;
		else if (SysInfoPtr->PlanetInfo.AtmoDensity < 100)
			life_var += 300;
		else if (SysInfoPtr->PlanetInfo.AtmoDensity < 1000)
			life_var += 150;
		else if (SysInfoPtr->PlanetInfo.AtmoDensity < 2500)
			;
		else
			life_var -= 100;

#ifndef NOTYET
		life_var += 200 + 80 + 80;
#else /* NOTYET */
		if (SysInfoPtr->PlanetInfo.SurfaceGravity < 10)
			;
		else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 35)
			life_var += 50;
		else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 75)
			life_var += 100;
		else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 150)
			life_var += 200;
		else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 400)
			life_var += 50;
		else if (SysInfoPtr->PlanetInfo.SurfaceGravity < 800)
			;
		else
			life_var -= 100;

		if (SysInfoPtr->PlanetInfo.Tectonics < 1)
			life_var += 80;
		else if (SysInfoPtr->PlanetInfo.Tectonics < 2)
			life_var += 70;
		else if (SysInfoPtr->PlanetInfo.Tectonics < 3)
			life_var += 60;
		else if (SysInfoPtr->PlanetInfo.Tectonics < 4)
			life_var += 50;
		else if (SysInfoPtr->PlanetInfo.Tectonics < 5)
			life_var += 25;
		else if (SysInfoPtr->PlanetInfo.Tectonics < 6)
			;
		else
			life_var -= 100;

		if (SysInfoPtr->PlanetInfo.Weather < 1)
			life_var += 80;
		else if (SysInfoPtr->PlanetInfo.Weather < 2)
			life_var += 70;
		else if (SysInfoPtr->PlanetInfo.Weather < 3)
			life_var += 60;
		else if (SysInfoPtr->PlanetInfo.Weather < 4)
			life_var += 50;
		else if (SysInfoPtr->PlanetInfo.Weather < 5)
			life_var += 25;
		else if (SysInfoPtr->PlanetInfo.Weather < 6)
			;
		else
			life_var -= 100;
#endif /* NOTYET */

		SysInfoPtr->PlanetInfo.LifeChance = life_var;

		life_var = (COUNT)TFB_Random () & 1023;
		if (life_var < SysInfoPtr->PlanetInfo.LifeChance
				|| (SysInfoPtr->PlanetInfo.LifeChance < MIN_LIFE_CHANCE
				&& life_var < MIN_LIFE_CHANCE))
		{
			BYTE num_types;

			num_types = (BYTE)(((BYTE)TFB_Random () % MAX_LIFE_VARIATION) + 1);
			do
			{
				BYTE index, num_creatures, range_types;
				DWORD rand_val; // JMS_GFX: Was UWORD
				UWORD loword, hiword;
				BOOLEAN zoneA, zoneB, zoneC;

				rand_val = (UWORD)TFB_Random ();
				
				// BW: Compute which life forms should appear				
				zoneA = (LOGX_TO_UNIVERSE(GLOBAL_SIS (log_x)) + LOGY_TO_UNIVERSE(GLOBAL_SIS (log_y)) > 9000);
				zoneB = (LOGX_TO_UNIVERSE(GLOBAL_SIS (log_x)) + 3 * LOGY_TO_UNIVERSE(GLOBAL_SIS (log_y)) < 21000);
				zoneC = (3 * LOGX_TO_UNIVERSE(GLOBAL_SIS (log_x)) + LOGY_TO_UNIVERSE(GLOBAL_SIS (log_y)) < 19000);
				
				range_types = 0;
				if (zoneA)
				  range_types += NUM_CREATURE_TYPES;
				if (zoneB)
				  range_types += NUM_B_CREATURE_TYPES;
				if (zoneC)
				  range_types += NUM_C_CREATURE_TYPES;

				//index = LOBYTE (rand_val) % range_types;
				index = LOBYTE ((UWORD)rand_val) % range_types; // JMS_GFX
				
				// BW: adjust index so that it takes creatures from the correct set.
				if (!zoneA)
				  {
				    index += NUM_CREATURE_TYPES + NUM_SPECIAL_CREATURE_TYPES;
				    if (!zoneB)
				      index += NUM_B_CREATURE_TYPES;
				  }
				if (zoneA && index >= NUM_CREATURE_TYPES)
				  {
				    index += NUM_SPECIAL_CREATURE_TYPES;
				    if (!zoneB)
				      index += NUM_B_CREATURE_TYPES;
				  }
	
				// BW: Reduce amounts in the NE quadrant
				if ((GLOBAL_SIS (log_x) > UNIVERSE_TO_LOGX(5000)) && (GLOBAL_SIS (log_y) < UNIVERSE_TO_LOGY(6000)))
				  num_creatures = (BYTE)((HIBYTE ((UWORD)rand_val) % 3) + 1);
				else
				  num_creatures = (BYTE)((HIBYTE ((UWORD)rand_val) % 10) + 1);

				do
				{
					rand_val = (DWORD)TFB_Random ();
					loword = LOWORD (rand_val);
					hiword = HIWORD (rand_val);
					
					/*
					if (RESOLUTION_FACTOR == 0)
						SysInfoPtr->PlanetInfo.CurPt.x = (LOBYTE (rand_val) % (MAP_WIDTH - (8 << 1))) + 8;
					else
						SysInfoPtr->PlanetInfo.CurPt.x = rand_val % (MAP_WIDTH - (8 << 1)) + 8; // JMS_GFX: Replaced previous line with this line (BYTE was too small for 640x480 maps.)
					
					SysInfoPtr->PlanetInfo.CurPt.y = (HIBYTE (rand_val) % (MAP_HEIGHT - (8 << 1))) + 8; // JMS_GFX
					*/
					
					if (RESOLUTION_FACTOR == 0)
						SysInfoPtr->PlanetInfo.CurPt.x = (LOBYTE ((UWORD)rand_val) % (MAP_WIDTH - (8 << 1))) + 8;
					else
						SysInfoPtr->PlanetInfo.CurPt.x = loword % (MAP_WIDTH - (8 << 1)) + 8; // JMS_GFX: Replaced previous line with this line (BYTE was too small for 640x480 maps.)
					
					if (RESOLUTION_FACTOR == 0)
						SysInfoPtr->PlanetInfo.CurPt.y = (HIBYTE ((UWORD)rand_val) % (MAP_HEIGHT - (8 << 1))) + 8;
					else
						SysInfoPtr->PlanetInfo.CurPt.y = hiword % (MAP_HEIGHT - (8 << 1)) + 8;  // JMS_GFX: Replaced previous line with this line (BYTE was too small for 1280x960 maps.)
					
					SysInfoPtr->PlanetInfo.CurType = index;

					if ((num_life_forms >= which_life 
						&& !(SysInfoPtr->PlanetInfo.ScanRetrieveMask[BIOLOGICAL_SCAN] & (1L << num_life_forms)))
						|| ++num_life_forms == sizeof (DWORD) * 8)
					{
						num_types = 1;
						break;
					}
				} while (--num_creatures);
			} while (--num_types);
		}
#ifdef DEBUG_SURFACE
		else
			log_add (log_Debug, "It's dead, Jim! (%d >= %d)", life_var,
				SysInfoPtr->PlanetInfo.LifeChance);
#endif /* DEBUG_SURFACE */
	}

	return (num_life_forms);
}
Example #20
0
static void
confusion_collision (ELEMENT *ElementPtr0, POINT *pPt0,
                     ELEMENT *ElementPtr1, POINT *pPt1)
{
    if (ElementPtr1->state_flags & PLAYER_SHIP)
    {
        HELEMENT hConfusionElement, hNextElement;
        ELEMENT *ConfusionPtr;
        STARSHIP *StarShipPtr;

        GetElementStarShip (ElementPtr0, &StarShipPtr);
        for (hConfusionElement = GetHeadElement ();
                hConfusionElement; hConfusionElement = hNextElement)
        {
            LockElement (hConfusionElement, &ConfusionPtr);
            if (elementsOfSamePlayer (ConfusionPtr, ElementPtr0)
                    && ConfusionPtr->current.image.farray ==
                    StarShipPtr->RaceDescPtr->ship_data.special
                    && (ConfusionPtr->state_flags & NONSOLID))
            {
                UnlockElement (hConfusionElement);
                break;
            }
            hNextElement = GetSuccElement (ConfusionPtr);
            UnlockElement (hConfusionElement);
        }

        if (hConfusionElement || (hConfusionElement = AllocElement ()))
        {
            LockElement (hConfusionElement, &ConfusionPtr);

            if (ConfusionPtr->state_flags == 0) /* not allocated before */
            {
                InsertElement (hConfusionElement, GetHeadElement ());

                ConfusionPtr->current = ElementPtr0->next;
                ConfusionPtr->current.image.frame = SetAbsFrameIndex (
                                                        ConfusionPtr->current.image.frame, 8
                                                    );
                ConfusionPtr->next = ConfusionPtr->current;
                ConfusionPtr->playerNr = ElementPtr0->playerNr;
                ConfusionPtr->state_flags = FINITE_LIFE | NONSOLID | CHANGING;
                ConfusionPtr->preprocess_func = confuse_preprocess;
                SetPrimType (
                    &(GLOBAL (DisplayArray))[ConfusionPtr->PrimIndex],
                    NO_PRIM
                );

                SetElementStarShip (ConfusionPtr, StarShipPtr);
                GetElementStarShip (ElementPtr1, &StarShipPtr);
                ConfusionPtr->hTarget = StarShipPtr->hShip;
            }

            ConfusionPtr->life_span = 400;
            ConfusionPtr->turn_wait =
                (BYTE)(1 << ((BYTE)TFB_Random () & 1)); /* LEFT or RIGHT */

            UnlockElement (hConfusionElement);
        }

        ElementPtr0->hit_points = 0;
        ElementPtr0->life_span = 0;
        ElementPtr0->state_flags |= DISAPPEARING | COLLISION | NONSOLID;
    }
    (void) pPt0;  /* Satisfying compiler (unused parameter) */
    (void) pPt1;  /* Satisfying compiler (unused parameter) */
}
Example #21
0
static COUNT
CalcMineralDeposits (SYSTEM_INFO *SysInfoPtr, COUNT which_deposit)
{
	BYTE j;
	COUNT num_deposits;
	const ELEMENT_ENTRY *eptr;

	eptr = &SysInfoPtr->PlanetInfo.PlanDataPtr->UsefulElements[0];
	num_deposits = 0;
	j = NUM_USEFUL_ELEMENTS;
	do
	{
		BYTE num_possible;

		num_possible = (BYTE)((BYTE)TFB_Random ()
				% (DEPOSIT_QUANTITY (eptr->Density) + 1));
		while (num_possible--)
		{
#define MEDIUM_DEPOSIT_THRESHOLD 150
#define LARGE_DEPOSIT_THRESHOLD 225
			DWORD rand_val;
			UWORD loword, hiword;
			COUNT deposit_quality_fine,
						deposit_quality_gross;
			
			// JMS: For making the mineral blip smaller in case it is partially scavenged.
			SDWORD temp_deposit_quality;
			
			deposit_quality_fine = ((COUNT)TFB_Random () % 100)
			  + (
			     DEPOSIT_QUALITY (eptr->Density)
			     + SysInfoPtr->StarSize
			     ) * 50;

			// BW: Check whether we're in the NE quadrant
			if ((GLOBAL_SIS (log_x) > UNIVERSE_TO_LOGX(5000)) && (GLOBAL_SIS (log_y) < UNIVERSE_TO_LOGY(6000)))
			  {
			    deposit_quality_fine = (COUNT)(deposit_quality_fine * DEPLETION_RATE);
			  }
			
			// JMS: This makes the mineral blip smaller in case it is partially scavenged.
			temp_deposit_quality = deposit_quality_fine - (SysInfoPtr->PlanetInfo.PartiallyScavengedList[MINERAL_SCAN][which_deposit] * 10);
			if (temp_deposit_quality < 0)
				temp_deposit_quality = 0;
			
			if (deposit_quality_fine < MEDIUM_DEPOSIT_THRESHOLD)
			  deposit_quality_gross = 0;
			else if (deposit_quality_fine < LARGE_DEPOSIT_THRESHOLD)
			  deposit_quality_gross = 1;
			else
			  deposit_quality_gross = 2;
			
			rand_val = TFB_Random ();
			loword = LOWORD (rand_val);
			hiword = HIWORD (rand_val);
			
			if (RESOLUTION_FACTOR == 0)
				SysInfoPtr->PlanetInfo.CurPt.x = (LOBYTE (loword) % (MAP_WIDTH - (8 << 1))) + 8;
			else
				SysInfoPtr->PlanetInfo.CurPt.x = loword % (MAP_WIDTH - (8 << 1)) + 8; // JMS_GFX: Replaced previous line with this line (BYTE was too small for 640x480 maps.)
			
			if (RESOLUTION_FACTOR == 0)
				SysInfoPtr->PlanetInfo.CurPt.y = (HIBYTE (loword) % (MAP_HEIGHT - (8 << 1))) + 8;
			else
				SysInfoPtr->PlanetInfo.CurPt.y = hiword % (MAP_HEIGHT - (8 << 1)) + 8;  // JMS_GFX: Replaced previous line with this line (BYTE was too small for 1280x960 maps.)
			
			SysInfoPtr->PlanetInfo.CurDensity = MAKE_WORD (deposit_quality_gross, deposit_quality_fine / 10 + 1);
			SysInfoPtr->PlanetInfo.CurType = eptr->ElementType;
#ifdef DEBUG_SURFACE
			log_add (log_Debug, "\t\t%d units of %Fs",
					SysInfoPtr->PlanetInfo.CurDensity,
					Elements[eptr->ElementType].name);
#endif /* DEBUG_SURFACE */
			if ((num_deposits >= which_deposit && !(SysInfoPtr->PlanetInfo.ScanRetrieveMask[MINERAL_SCAN] & (1L << num_deposits)))
					|| ++num_deposits == sizeof (DWORD) * 8)
				goto ExitCalcMinerals;
		}
		++eptr;
	} while (--j);

ExitCalcMinerals:
	return (num_deposits);
}
Example #22
0
void
GenerateShipVault (BYTE control)
{
	switch (control)
	{
		case GENERATE_ENERGY:
			if (pSolarSysState->pOrbitalDesc->pPrevDesc == &pSolarSysState->PlanetDesc[0]
					&& pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0])
			{
				DWORD rand_val, old_rand;

				old_rand = TFB_SeedRandom (
						pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]
						);

				rand_val = TFB_Random ();
				pSolarSysState->SysInfo.PlanetInfo.CurPt.x =
						(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
				pSolarSysState->SysInfo.PlanetInfo.CurPt.y =
						(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
				pSolarSysState->SysInfo.PlanetInfo.CurDensity = 0;
				if (!GET_GAME_STATE (SHIP_VAULT_UNLOCKED))
					pSolarSysState->SysInfo.PlanetInfo.CurType = 0;
				else
					pSolarSysState->SysInfo.PlanetInfo.CurType = 1;
				pSolarSysState->CurNode = 1;
				if (pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
						& (1L << 0))
				{
					pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
							&= ~(1L << 0);
					if (GET_GAME_STATE (SYREEN_SHUTTLE_ON_SHIP))
					{
						((PLANETSIDE_DESC*)pMenuState->ModuleFrame)->InTransit = TRUE;

						SET_GAME_STATE (SHIP_VAULT_UNLOCKED, 1);
						SET_GAME_STATE (SYREEN_SHUTTLE_ON_SHIP, 0);
						SET_GAME_STATE (SYREEN_HOME_VISITS, 0);
					}
					else if (!GET_GAME_STATE (KNOW_SYREEN_VAULT))
					{
						SET_GAME_STATE (KNOW_SYREEN_VAULT, 1);
						SET_GAME_STATE (SYREEN_HOME_VISITS, 0);
					}
				}

				TFB_SeedRandom (old_rand);
				break;
			}
			pSolarSysState->CurNode = 0;
			break;
		case GENERATE_ORBITAL:
			if (pSolarSysState->pOrbitalDesc->pPrevDesc == &pSolarSysState->PlanetDesc[0]
					&& pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0])
			{
				LoadStdLanderFont (&pSolarSysState->SysInfo.PlanetInfo);
				pSolarSysState->PlanetSideFrame[1] =
						CaptureDrawable (
								LoadGraphic (VAULT_MASK_PMAP_ANIM)
								);
				pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
						CaptureStringTable (
								LoadStringTable (VAULT_STRTAB)
								);
				if (GET_GAME_STATE (SHIP_VAULT_UNLOCKED))
					pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
							SetAbsStringTableIndex (
							pSolarSysState->SysInfo.PlanetInfo.DiscoveryString,
							2
							);
				else if (GET_GAME_STATE (SYREEN_SHUTTLE_ON_SHIP))
					pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
							SetAbsStringTableIndex (
							pSolarSysState->SysInfo.PlanetInfo.DiscoveryString,
							1
							);
			}
		default:
			GenerateRandomIP (control);
			break;
	}
}
Example #23
0
static void
butt_missile_preprocess (ELEMENT *ElementPtr)
{
	if (ElementPtr->turn_wait > 0)
		--ElementPtr->turn_wait;
	else
	{
		COUNT facing;
		// COUNT num_frames;
		SIZE delta_x, delta_y, delta_facing;
		ELEMENT *EnemyPtr;

		facing = GetFrameIndex (ElementPtr->next.image.frame);
		
		if (ElementPtr->hTarget)
		{
			LockElement (ElementPtr->hTarget, &EnemyPtr);
			delta_x = EnemyPtr->current.location.x
					- ElementPtr->current.location.x;
			delta_x = WRAP_DELTA_X (delta_x);
			delta_y = EnemyPtr->current.location.y
					- ElementPtr->current.location.y;
			delta_y = WRAP_DELTA_Y (delta_y);
	
			/* num_frames = (square_root ((long)delta_x * delta_x
					+ (long)delta_y * delta_y)) / DISCRIMINATOR_SPEED;

			if (num_frames == 0)
				num_frames = 1;
	
			GetNextVelocityComponents (&EnemyPtr->velocity,
					&delta_x, &delta_y, num_frames);
	
			// Lead the target by its apparent trajectory.
			delta_x = (EnemyPtr->current.location.x + (delta_x / 2))
					- ElementPtr->current.location.x;
			delta_y = (EnemyPtr->current.location.y + (delta_y / 2))
					- ElementPtr->current.location.y; */
	
			delta_facing = NORMALIZE_FACING (
					ANGLE_TO_FACING (ARCTAN (delta_x, delta_y)) - facing);
	
			if (delta_facing > 0 && !OBJECT_CLOAKED(EnemyPtr))
			{
				if (delta_facing == ANGLE_TO_FACING (HALF_CIRCLE))
					facing += (((BYTE)TFB_Random () & 1) << 1) - 1;
				else if (delta_facing < ANGLE_TO_FACING (HALF_CIRCLE))
					++facing;
				else
					--facing;
			}
	
			ElementPtr->next.image.frame =
				SetAbsFrameIndex (ElementPtr->next.image.frame, facing);

			ElementPtr->state_flags |= CHANGING;
	
			SetVelocityVector (&ElementPtr->velocity, DISCRIMINATOR_SPEED, facing);

			UnlockElement (ElementPtr->hTarget);
		}
		else if (TrackShip (ElementPtr, &facing) > 0)
		{
			ElementPtr->next.image.frame =
					SetAbsFrameIndex (ElementPtr->next.image.frame,
					facing);
			ElementPtr->state_flags |= CHANGING;
	
			SetVelocityVector (&ElementPtr->velocity,
					DISCRIMINATOR_SPEED, facing);
		}

		ElementPtr->turn_wait = TRACK_WAIT;
	}
}
Example #24
0
static void
supox_intelligence (ELEMENT *ShipPtr, EVALUATE_DESC *ObjectsOfConcern,
		COUNT ConcernCounter)
{
	STARSHIP *StarShipPtr;
	EVALUATE_DESC *lpEvalDesc;

	GetElementStarShip (ShipPtr, &StarShipPtr);

	lpEvalDesc = &ObjectsOfConcern[ENEMY_SHIP_INDEX];
	if (StarShipPtr->special_counter || lpEvalDesc->ObjectPtr == 0)
		StarShipPtr->ship_input_state &= ~SPECIAL;
	else
	{
		BOOLEAN LinedUp;
		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);

		LinedUp = (BOOLEAN)(NORMALIZE_ANGLE (NORMALIZE_ANGLE (direction_angle
				- FACING_TO_ANGLE (StarShipPtr->ShipFacing))
				+ QUADRANT) <= HALF_CIRCLE);

		if (!LinedUp
				|| lpEvalDesc->which_turn > 20
				|| NORMALIZE_ANGLE (
				lpEvalDesc->facing
				- (FACING_TO_ANGLE (StarShipPtr->ShipFacing)
				+ HALF_CIRCLE) + OCTANT
				) > QUADRANT)
			StarShipPtr->ship_input_state &= ~SPECIAL;
		else if (LinedUp && lpEvalDesc->which_turn <= 12)
			StarShipPtr->ship_input_state |= SPECIAL;

		if (StarShipPtr->ship_input_state & SPECIAL)
			lpEvalDesc->MoveState = PURSUE;
	}

	ship_intelligence (ShipPtr,
			ObjectsOfConcern, ConcernCounter);

	if (StarShipPtr->ship_input_state & SPECIAL)
		StarShipPtr->ship_input_state |= THRUST | WEAPON;

	lpEvalDesc = &ObjectsOfConcern[ENEMY_WEAPON_INDEX];
	if (StarShipPtr->special_counter == 0
			&& lpEvalDesc->ObjectPtr
			&& lpEvalDesc->MoveState == AVOID
			&& ShipPtr->turn_wait == 0)
	{
		StarShipPtr->ship_input_state &= ~THRUST;
		StarShipPtr->ship_input_state |= SPECIAL;
		if (!(StarShipPtr->cur_status_flags & (LEFT | RIGHT)))
			StarShipPtr->ship_input_state |= 1 << ((BYTE)TFB_Random () & 1);
		else
			StarShipPtr->ship_input_state |=
					StarShipPtr->cur_status_flags & (LEFT | RIGHT);
	}
}
Example #25
0
void
GenerateBurvixes (BYTE control)
{
	COUNT i;
	DWORD rand_val;

	switch (control)
	{
		case GENERATE_ENERGY:
		{
			DWORD rand_val, old_rand;

			if (pSolarSysState->pOrbitalDesc == &pSolarSysState->PlanetDesc[0])
			{
				COUNT which_node;

				old_rand = TFB_SeedRandom (
						pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]
						);

				which_node = i = 0;
				do
				{
					rand_val = TFB_Random ();
					pSolarSysState->SysInfo.PlanetInfo.CurPt.x =
							(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
					pSolarSysState->SysInfo.PlanetInfo.CurPt.y =
							(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
					pSolarSysState->SysInfo.PlanetInfo.CurType = 1;
					pSolarSysState->SysInfo.PlanetInfo.CurDensity = 0;
					if (which_node >= pSolarSysState->CurNode
							&& !(pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
							& (1L << i)))
						break;
					++which_node;
				} while (++i < 16);
				pSolarSysState->CurNode = which_node;

				TFB_SeedRandom (old_rand);
				break;
			}
			else if (pSolarSysState->pOrbitalDesc->pPrevDesc == &pSolarSysState->PlanetDesc[0]
					&& pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0]
					&& !GET_GAME_STATE (BURVIXESE_BROADCASTERS))
			{
				old_rand = TFB_SeedRandom (
						pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]
						);

				rand_val = TFB_Random ();
				pSolarSysState->SysInfo.PlanetInfo.CurPt.x =
						(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
				pSolarSysState->SysInfo.PlanetInfo.CurPt.y =
						(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
				pSolarSysState->SysInfo.PlanetInfo.CurDensity = 0;
				pSolarSysState->SysInfo.PlanetInfo.CurType = 0;
				if (!(pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
						& (1L << 0))
						&& pSolarSysState->CurNode == (COUNT)~0)
					pSolarSysState->CurNode = 1;
				else
				{
					pSolarSysState->CurNode = 0;
					if (pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
							& (1L << 0))
					{
						SET_GAME_STATE (BURVIXESE_BROADCASTERS, 1);
						SET_GAME_STATE (BURV_BROADCASTERS_ON_SHIP, 1);
					}
				}

				TFB_SeedRandom (old_rand);
				break;
			}
			pSolarSysState->CurNode = 0;
			break;
		}
		case GENERATE_MOONS:
			GenerateRandomIP (GENERATE_MOONS);
			if (pSolarSysState->pBaseDesc == &pSolarSysState->PlanetDesc[0])
			{
				COUNT angle;

				pSolarSysState->MoonDesc[0].data_index = SELENIC_WORLD;
				pSolarSysState->MoonDesc[0].radius = MIN_MOON_RADIUS
						+ (MAX_MOONS - 1) * MOON_DELTA;
				rand_val = TFB_Random ();
				angle = NORMALIZE_ANGLE (LOWORD (rand_val));
				pSolarSysState->MoonDesc[0].location.x =
						COSINE (angle, pSolarSysState->MoonDesc[0].radius);
				pSolarSysState->MoonDesc[0].location.y =
						SINE (angle, pSolarSysState->MoonDesc[0].radius);
			}
			break;
		case GENERATE_PLANETS:
		{
			COUNT angle;

			GenerateRandomIP (GENERATE_PLANETS);

			pSolarSysState->PlanetDesc[0].data_index = REDUX_WORLD;
			pSolarSysState->PlanetDesc[0].NumPlanets = 1;
			pSolarSysState->PlanetDesc[0].radius = EARTH_RADIUS * 39L / 100;
			angle = ARCTAN (
					pSolarSysState->PlanetDesc[0].location.x,
					pSolarSysState->PlanetDesc[0].location.y
					);
			pSolarSysState->PlanetDesc[0].location.x =
					COSINE (angle, pSolarSysState->PlanetDesc[0].radius);
			pSolarSysState->PlanetDesc[0].location.y =
					SINE (angle, pSolarSysState->PlanetDesc[0].radius);
			break;
		}
		case GENERATE_ORBITAL:
		{
			rand_val = DoPlanetaryAnalysis (
					&pSolarSysState->SysInfo, pSolarSysState->pOrbitalDesc
					);

			pSolarSysState->SysInfo.PlanetInfo.ScanSeed[BIOLOGICAL_SCAN] = rand_val;
			i = (COUNT)~0;
			rand_val = GenerateLifeForms (&pSolarSysState->SysInfo, &i);

			pSolarSysState->SysInfo.PlanetInfo.ScanSeed[MINERAL_SCAN] = rand_val;
			i = (COUNT)~0;
			GenerateMineralDeposits (&pSolarSysState->SysInfo, &i);

			pSolarSysState->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN] = rand_val;
			if (pSolarSysState->pOrbitalDesc == &pSolarSysState->PlanetDesc[0])
			{
				LoadStdLanderFont (&pSolarSysState->SysInfo.PlanetInfo);
				pSolarSysState->PlanetSideFrame[1] =
						CaptureDrawable (
						LoadGraphic (RUINS_MASK_PMAP_ANIM));
				pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
						CaptureStringTable (
								LoadStringTable (BURV_RUINS_STRTAB));
				pSolarSysState->SysInfo.PlanetInfo.Weather = 0;
				pSolarSysState->SysInfo.PlanetInfo.Tectonics = 0;
			}
			else if (pSolarSysState->pOrbitalDesc->pPrevDesc == &pSolarSysState->PlanetDesc[0]
					&& pSolarSysState->pOrbitalDesc == &pSolarSysState->MoonDesc[0]
					&& !GET_GAME_STATE (BURVIXESE_BROADCASTERS))
			{
				LoadStdLanderFont (&pSolarSysState->SysInfo.PlanetInfo);
				pSolarSysState->PlanetSideFrame[1] =
						CaptureDrawable (
						LoadGraphic (BURV_BCS_MASK_PMAP_ANIM));
				pSolarSysState->SysInfo.PlanetInfo.DiscoveryString =
						CaptureStringTable (
								LoadStringTable (BURV_BCS_STRTAB));
			}
			LoadPlanet (NULL);
			break;
		}
		default:
			GenerateRandomIP (control);
			break;
	}
}
Example #26
0
static bool
GenerateBurvixese_generateEnergy (SOLARSYS_STATE *solarSys, PLANET_DESC *world,
		COUNT *whichNode)
{
	DWORD rand_val;
	DWORD old_rand;

	if (matchWorld (solarSys, world, 0, MATCH_PLANET))
	{
		COUNT nodeI;
		COUNT i;

		old_rand = TFB_SeedRandom (
				solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]);

		nodeI = 0;
		i = 0;
		do
		{
			rand_val = TFB_Random ();
			solarSys->SysInfo.PlanetInfo.CurPt.x =
					(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
			solarSys->SysInfo.PlanetInfo.CurPt.y =
					(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
			solarSys->SysInfo.PlanetInfo.CurType = 1;
			solarSys->SysInfo.PlanetInfo.CurDensity = 0;
			if (nodeI >= *whichNode
					&& !(solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
					& (1L << i)))
				break;
			++nodeI;
		} while (++i < 16);
		*whichNode = nodeI;

		TFB_SeedRandom (old_rand);
		return true;
	}

	if (matchWorld (solarSys, world, 0, 0)
			&& !GET_GAME_STATE (BURVIXESE_BROADCASTERS))
	{
		old_rand = TFB_SeedRandom (
				solarSys->SysInfo.PlanetInfo.ScanSeed[ENERGY_SCAN]);

		rand_val = TFB_Random ();
		solarSys->SysInfo.PlanetInfo.CurPt.x =
				(LOBYTE (LOWORD (rand_val)) % (MAP_WIDTH - (8 << 1))) + 8;
		solarSys->SysInfo.PlanetInfo.CurPt.y =
				(HIBYTE (LOWORD (rand_val)) % (MAP_HEIGHT - (8 << 1))) + 8;
		solarSys->SysInfo.PlanetInfo.CurDensity = 0;
		solarSys->SysInfo.PlanetInfo.CurType = 0;
		if (!(solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
				& (1L << 0))
				&& *whichNode == (COUNT)~0)
			*whichNode = 1;
		else
		{
			*whichNode = 0;
			if (solarSys->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN]
					& (1L << 0))
			{
				SET_GAME_STATE (BURVIXESE_BROADCASTERS, 1);
				SET_GAME_STATE (BURV_BROADCASTERS_ON_SHIP, 1);
			}
		}

		TFB_SeedRandom (old_rand);
		return true;
	}

	*whichNode = 0;
	return true;
}
Example #27
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;
	}
}
Example #28
0
BOOLEAN
Battle (BattleFrameCallback *callback)
{
	SIZE num_ships;

	LockMutex (GraphicsLock);

#if !(DEMO_MODE || CREATE_JOURNAL)
	if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) {
		// In Supermelee, the RNG is already initialised.
		TFB_SeedRandom (GetTimeCounter ());
	}
#else /* DEMO_MODE */
	if (BattleSeed == 0)
		BattleSeed = TFB_Random ();
	TFB_SeedRandom (BattleSeed);
	BattleSeed = TFB_Random (); /* get next battle seed */
#endif /* DEMO_MODE */

	BattleSong (FALSE);
	
	num_ships = InitShips ();

	if (instantVictory)
	{
		num_ships = 0;
		battle_counter[0] = 1;
		battle_counter[1] = 0;
		instantVictory = FALSE;
	}
	
	if (num_ships)
	{
		BATTLE_STATE bs;

		GLOBAL (CurrentActivity) |= IN_BATTLE;
		battle_counter[0] = CountLinks (&race_q[0]);
		battle_counter[1] = CountLinks (&race_q[1]);
		
		if (optMeleeScale != TFB_SCALE_STEP)
			SetGraphicScaleMode (optMeleeScale);

		setupBattleInputOrder ();
#ifdef NETPLAY
		initBattleInputBuffers ();
#ifdef NETPLAY_CHECKSUM
		initChecksumBuffers ();
#endif  /* NETPLAY_CHECKSUM */
		battleFrameCount = 0;
		ResetWinnerStarShip ();
		setBattleStateConnections (&bs);
#endif  /* NETPLAY */

		if (!selectAllShips (num_ships)) {
			GLOBAL (CurrentActivity) |= CHECK_ABORT;

			goto AbortBattle;
		}

		BattleSong (TRUE);
		bs.NextTime = 0;
#ifdef NETPLAY
		initBattleStateDataConnections ();
		{
			bool allOk = negotiateReadyConnections (true, NetState_inBattle);
			if (!allOk) {
				GLOBAL (CurrentActivity) |= CHECK_ABORT;
				goto AbortBattle;
			}
		}
#endif  /* NETPLAY */
		bs.InputFunc = DoBattle;
		bs.frame_cb = callback;
		bs.first_time = (BOOLEAN)(LOBYTE (GLOBAL (CurrentActivity)) ==
				IN_HYPERSPACE);

		UnlockMutex (GraphicsLock);
		DoInput (&bs, FALSE);
		LockMutex (GraphicsLock);

AbortBattle:
		if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE)
		{
			if (GLOBAL (CurrentActivity) & CHECK_ABORT)
			{
				// Do not return to the main menu when a game is aborted,
				// (just to the supermelee menu).
#ifdef NETPLAY
				UnlockMutex (GraphicsLock);
				waitResetConnections(NetState_inSetup);
						// A connection may already be in inSetup (set from
						// GetMeleeStarship). This is not a problem, although
						// it will generate a warning in debug mode.
				LockMutex (GraphicsLock);
#endif

				GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
			}
			else
			{
				// Show the result of the battle.
				MeleeGameOver ();
			}
		}

#ifdef NETPLAY
		uninitBattleInputBuffers();
#ifdef NETPLAY_CHECKSUM
		uninitChecksumBuffers ();
#endif  /* NETPLAY_CHECKSUM */
		setBattleStateConnections (NULL);
#endif  /* NETPLAY */

		StopDitty ();
		StopMusic ();
		StopSound ();
	}

	UninitShips ();
	FreeBattleSong ();

	UnlockMutex (GraphicsLock);
	
	return (BOOLEAN) (num_ships < 0);
}
Example #29
0
static void
gas_collision (ELEMENT *ElementPtr0, POINT *pPt0, ELEMENT *ElementPtr1, POINT *pPt1)
{
	STARSHIP *StarShipPtr;
	STARSHIP *EnemyStarShipPtr;
	BYTE	 enemyShipIsBaul = 0;
	BYTE	 enemyShipIsChmmr = 0;
	
	// This is the ship this gas cloud belongs to.
	GetElementStarShip (ElementPtr0, &StarShipPtr);
	
	// Check if the colliding element is a ship. If it is not, check if it's a projectile from Baul or Chmmr ship.
	if (!elementsOfSamePlayer(ElementPtr0, ElementPtr1) && !(ElementPtr1->state_flags & PLAYER_SHIP) 
		&& ElementPtr1->playerNr > -1)
	{
		GetElementStarShip (ElementPtr1, &EnemyStarShipPtr);
		if (EnemyStarShipPtr->SpeciesID == BAUL_ID)
			enemyShipIsBaul = 1;
		else if (EnemyStarShipPtr->SpeciesID == CHMMR_ID) 
			enemyShipIsChmmr = 1; // This is important because the gas can stick to zapsats.
	}
	
	// If colliding with Baul's spray weapon or shockwave, EXPLODE!!!
	if (ElementPtr1->current.image.farray == StarShipPtr->RaceDescPtr->ship_data.weapon
		|| (enemyShipIsBaul && ElementPtr1->current.image.farray == EnemyStarShipPtr->RaceDescPtr->ship_data.weapon))
	{
		// Move to shockwave graphics.
		ElementPtr0->current.image.frame = SetAbsFrameIndex (ElementPtr0->current.image.frame, LAST_GAS_INDEX);
		ElementPtr0->next.image.frame = SetAbsFrameIndex (ElementPtr0->current.image.frame, LAST_GAS_INDEX);
		
		// Remove the lock on enemy ship and make the gas die on next turn.
		ElementPtr0->hTarget = 0;
		ElementPtr0->life_span = 1;
		
		// Don't do the gas dissolve anim now that the shockwave appears.
		ElementPtr0->death_func = NULL;
		
		// Generate the actual shockwave.
		generate_shockwave (ElementPtr0, -1); // XXX ElementPtr1->playerNr);
	}
	// If colliding with enemy ship, stick to the ship.
	// Also stick to Chmmr's zapsats.
	else if (ElementPtr0->state_flags & IGNORE_VELOCITY
			 && ElementPtr1->playerNr != ElementPtr0->playerNr
			 && (ElementPtr1->state_flags & PLAYER_SHIP 
				 || (enemyShipIsChmmr && ElementPtr1->mass_points == 10) ))
	{
		HELEMENT hGasElement;
		HELEMENT hTargetElement;
		ELEMENT *GasPtr;
		
		// Create a new gas element which is sticking to the enemy ship.
		if ((hGasElement = AllocElement ()))
		{
			LockElement (hGasElement, &GasPtr);
			
			if (GasPtr->state_flags == 0) /* not allocated before */
			{
				InsertElement (hGasElement, GetHeadElement ());
				
				GasPtr->current = ElementPtr0->next;
				GasPtr->next = GasPtr->current;
				GasPtr->playerNr = ElementPtr0->playerNr;
				GasPtr->state_flags = FINITE_LIFE | GASSY_SUBSTANCE | CHANGING;
				GasPtr->preprocess_func = gas_preprocess;
				GasPtr->collision_func = gas_collision;
				SetPrimType (&(GLOBAL (DisplayArray))[GasPtr->PrimIndex], NO_PRIM);
				
				SetElementStarShip (GasPtr, StarShipPtr);
				GetElementStarShip (ElementPtr1, &StarShipPtr);
				
				// Ships and Chmmr Zapsats require different ways of making them the target of the gas cloud.
				if (ElementPtr1->state_flags & PLAYER_SHIP)
					GasPtr->hTarget = StarShipPtr->hShip;
				else
				{
					GasPtr->life_span = 0;
					LockElement (ElementPtr1, &hTargetElement);
					GasPtr->hTarget = hTargetElement;
				}
			}
			GasPtr->hit_points = ElementPtr0->hit_points;
			GasPtr->life_span = ElementPtr0->life_span;
			GasPtr->thrust_wait = 1;
			GasPtr->weapon_element_index = ElementPtr0->weapon_element_index;
			GasPtr->turn_wait = (BYTE)(1 << ((BYTE)TFB_Random () & 1)); /* LEFT or RIGHT */
			GasPtr->death_func = gas_death;
			
			UnlockElement (hGasElement);
		}
		
		// Erase the original gas element.
		ElementPtr0->hit_points = 0;
		ElementPtr0->life_span = 0;
		ElementPtr0->state_flags |= DISAPPEARING | COLLISION | NONSOLID;
	}
	(void) pPt0;  /* Satisfying compiler (unused parameter) */
	(void) pPt1;  /* Satisfying compiler (unused parameter) */
}
Example #30
0
static void
explosion_preprocess (ELEMENT *ShipPtr)
{
	BYTE i;

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

	do
	{
		HELEMENT hElement;

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

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