Example #1
0
static DWORD
getStripRandomSeed (void)
{
	DWORD x, y;
	// We truncate the location because encounters move the ship slightly in
	// HSpace, and throw some other relatively immutable values in the mix to
	// vary the deal when stuck at the same general location again.
	// It is still possible but unlikely for encounters to move the ship into
	// another truncation sector so the player could choose from 2 deals.
	x = LOGX_TO_UNIVERSE (GLOBAL_SIS (log_x)) / 100;
	y = LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y)) / 100;
	// prime numbers help randomness
	return y * 1013 + x + GLOBAL_SIS (NumLanders)
			+ GLOBAL_SIS (ModuleSlots[1]) + GLOBAL_SIS (ModuleSlots[4])
			+ GLOBAL_SIS (ModuleSlots[7]) + GLOBAL_SIS (ModuleSlots[10]);
}
Example #2
0
// Move the Flagship to the destination of the autopilot.
// Should only be called from HyperSpace/QuasiSpace.
// It can be called from debugHook directly after entering HS/QS though.
void
doInstantMove (void)
{
	// Move to the new location:
	if ((GLOBAL (autopilot)).x == ~0 || (GLOBAL (autopilot)).y == ~0)
	{
		// If no destination has been selected, use the current location
		// as the destination.
		(GLOBAL (autopilot)).x = LOGX_TO_UNIVERSE(GLOBAL_SIS (log_x));
		(GLOBAL (autopilot)).y = LOGY_TO_UNIVERSE(GLOBAL_SIS (log_y));
	}
	else
	{
		// A new destination has been selected.
		GLOBAL_SIS (log_x) = UNIVERSE_TO_LOGX((GLOBAL (autopilot)).x);
		GLOBAL_SIS (log_y) = UNIVERSE_TO_LOGY((GLOBAL (autopilot)).y);
	}

	// Check for a solar systems at the destination.
	if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1)
	{
		// If there's a solar system at the destination, enter it.
		CurStarDescPtr = FindStar (0, &(GLOBAL (autopilot)), 0, 0);
		if (CurStarDescPtr)
		{
			// Leave HyperSpace/QuasiSpace if we're there:
			SET_GAME_STATE (USED_BROADCASTER, 0);
			GLOBAL (CurrentActivity) &= ~IN_BATTLE;

			// Enter IP:
			GLOBAL (ShipFacing) = 0;
			GLOBAL (ip_planet) = 0;
			GLOBAL (in_orbit) = 0;
					// This causes the ship position in IP to be reset.
			GLOBAL (CurrentActivity) |= START_INTERPLANETARY;
		}
	}

	// Turn off the autopilot:
	(GLOBAL (autopilot)).x = ~0;
	(GLOBAL (autopilot)).y = ~0;
}
Example #3
0
static void
DoRescue (RESPONSE_REF R)
{
	SIZE dx, dy;
	COUNT fuel_required;

	(void) R;  // ignored
	dx = LOGX_TO_UNIVERSE (GLOBAL_SIS (log_x))
			- SOL_X;
	dy = LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y))
			- SOL_Y;
	fuel_required = square_root (
			(DWORD)((long)dx * dx + (long)dy * dy)
			) + (2 * FUEL_TANK_SCALE);

	if (StripShip (fuel_required))
	{
		Response (take_it, ExitConversation);
		Response (leave_it, ExitConversation);
	}
}
Example #4
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 #5
0
static void
sis_hyper_preprocess (ELEMENT *ElementPtr)
{
    SIZE udx, udy, dx, dy;
    SIZE AccelerateDirection;
    STARSHIP *StarShipPtr;

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

    AccelerateDirection = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

            AccelerateDirection = 0;

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

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

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

        ElementPtr->thrust_wait =
            StarShipPtr->RaceDescPtr->characteristics.thrust_wait;
    }
}
Example #6
0
/**
 * Gets the content for index and loads it into the current conversation,
 * using the voice track cb if provided, or making one itself if not.
 * 
 * The indices are:
 * - 1 000 000 : captain's name
 *   - 999 999 : ship's name
 *   - 999 998 : ship's location
 * numbers from -999 997 to 998 997 : display the name of your alliance
 * (not sure why this one option needs 1001 indices)
 * numbers from -998 996 to -1 : alien number speech (sign is flipped)
 *           0 : say and do nothing
 * positive numbers : entries from the current alien conversation's string table 
 */
void
NPCPhrase_cb (int index,  TFB_TrackCB cb)
{
	UNICODE *pStr, numbuf[400];
	void *pClip, *pTimeStamp;

	switch (index)
	{
		case GLOBAL_PLAYER_NAME:
			pStr = GLOBAL_SIS (CommanderName);
			pClip = 0;
			pTimeStamp = 0;
			break;
		case GLOBAL_SHIP_NAME:
			pStr = GLOBAL_SIS (ShipName);
			pClip = 0;
			pTimeStamp = 0;
			break;
		case GLOBAL_PLAYER_LOCATION:
		{
			SIZE dx, dy;
			COUNT adx, ady;

			dx = LOGX_TO_UNIVERSE (GLOBAL_SIS (log_x)) - 333;
			adx = dx >= 0 ? dx : -dx;
			dy = 9812 - LOGY_TO_UNIVERSE (GLOBAL_SIS (log_y));
			ady = dy >= 0 ? dy : -dy;
			sprintf (numbuf,
					"%+04d.%01u,%+04d.%01u",
					(SIZE)(dy / 10), (COUNT)(ady % 10),
					(SIZE)(dx / 10), (COUNT)(adx % 10));
			pStr = numbuf;
			pClip = 0;
			pTimeStamp = 0;
			break;
		}
		case 0:
		{
			return;
		}
		default:
			if (index < 0)
			{
				if (index > UNREASONABLE_NUMBER)
				{
					if (CommData.AlienNumberSpeech)
					{
						NPCNumberPhrase (-index, NULL);
						return;
					}
					sprintf (numbuf, "%d", -index);
				}
				else
				{
					COUNT i;
					STRING S;

					index -= GLOBAL_ALLIANCE_NAME;

					i = GET_GAME_STATE (NEW_ALLIANCE_NAME);
					S = SetAbsStringTableIndex (CommData.ConversationPhrases, (index - 1) + i);
					strcpy (numbuf, (UNICODE *)GetStringAddress (S));
					if (i == 3)
						strcat (numbuf, GLOBAL_SIS (CommanderName));
				}
				pStr = numbuf;
				pClip = 0;
				pTimeStamp = 0;
			}
			else
			{
				pStr = (UNICODE *)GetStringAddress (
						SetAbsStringTableIndex (CommData.ConversationPhrases, index - 1)
						);
				pClip = GetStringSoundClip (
						SetAbsStringTableIndex (CommData.ConversationPhrases, index - 1)
						);
				pTimeStamp = GetStringTimeStamp (
						SetAbsStringTableIndex (CommData.ConversationPhrases, index - 1)
						);
			}
			break;
	}

	if (GLOBAL (glob_flags) & VOICE_DISABLED || pClip == NULL)
		pClip = "noname.ogg";
	SpliceTrack (pClip, pStr, pTimeStamp, cb);
}