Beispiel #1
0
static BOOLEAN
DeltaSupportCrew (SIZE crew_delta)
{
	BOOLEAN ret = FALSE;
	UNICODE buf[40];
	HSTARSHIP hTemplate;
	SHIP_FRAGMENTPTR StarShipPtr, TemplatePtr;

	StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
			&GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame);
	hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q),
			GET_RACE_ID (StarShipPtr));
	TemplatePtr = (SHIP_FRAGMENTPTR)LockStarShip (
			&GLOBAL (avail_race_q), hTemplate);

	StarShipPtr->ShipInfo.crew_level += crew_delta;

	if (StarShipPtr->ShipInfo.crew_level == 0)
		StarShipPtr->ShipInfo.crew_level = 1;
	else if (StarShipPtr->ShipInfo.crew_level >
			TemplatePtr->RaceDescPtr->ship_info.crew_level &&
			crew_delta > 0)
		StarShipPtr->ShipInfo.crew_level -= crew_delta;
	else
	{
		if (StarShipPtr->ShipInfo.crew_level >=
				TemplatePtr->RaceDescPtr->ship_info.crew_level)
			sprintf (buf, "%u", StarShipPtr->ShipInfo.crew_level);
		else
			sprintf (buf, "%u/%u",
					StarShipPtr->ShipInfo.crew_level,
					TemplatePtr->RaceDescPtr->ship_info.crew_level);

		DrawStatusMessage (buf);
		DeltaSISGauges (-crew_delta, 0, 0);
		if (crew_delta)
		{
			RECT r;

			r.corner.x = 2;
			r.corner.y = 130;
			r.extent.width = STATUS_MESSAGE_WIDTH;
			r.extent.height = STATUS_MESSAGE_HEIGHT;
			SetContext (StatusContext);
			SetFlashRect (&r, (FRAME)0);
		}
		ret = TRUE;
	}

	UnlockStarShip (&GLOBAL (avail_race_q), hTemplate);
	UnlockStarShip (&GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame);

	return ret;
}
Beispiel #2
0
static HSTARSHIP
MatchSupportShip (PMENU_STATE pMS)
{
	PPOINT pship_pos;
	HSTARSHIP hStarShip, hNextShip;

	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)),
			pship_pos = (PPOINT)pMS->flash_frame0;
			hStarShip; hStarShip = hNextShip, ++pship_pos)
	{
		SHIP_FRAGMENTPTR StarShipPtr;

		StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
				&GLOBAL (built_ship_q), hStarShip);

		if (pship_pos->x == pMS->first_item.x
				&& pship_pos->y == pMS->first_item.y)
		{
			UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);
			return hStarShip;
		}

		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);
	}

	return 0;
}
Beispiel #3
0
static void
RosterCleanup (PMENU_STATE pMS)
{
	if (pMS->flash_task)
	{
		UnlockMutex (GraphicsLock);
		ConcludeTask (pMS->flash_task);
		LockMutex (GraphicsLock);
		pMS->flash_task = 0;
	}

	if (pMS->CurFrame)
	{
		STAMP s;
		SHIP_FRAGMENTPTR StarShipPtr;

		SetContext (StatusContext);
		s.origin = pMS->first_item;
		StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
				&GLOBAL (built_ship_q), (HSTARSHIP)pMS->CurFrame);
		s.frame = StarShipPtr->ShipInfo.icons;
		UnlockStarShip (&GLOBAL (built_ship_q), (HSTARSHIP)pMS->CurFrame);
		if (!(pMS->CurState & SHIP_TOGGLE))
			DrawStamp (&s);
		else
		{
			SetContextForeGroundColor (WHITE_COLOR);
			DrawFilledStamp (&s);
		}
	}
}
Beispiel #4
0
static COUNT
queueIndexFromShip (HSTARSHIP hShip)
{
	COUNT result;
	STARSHIP *StarShipPtr = LockStarShip (queue, hShip);
	result = StarShipPtr->index;
	UnlockStarShip (queue, hShip);
}
Beispiel #5
0
HSTARSHIP
CloneShipFragment (COUNT index, PQUEUE pDstQueue, BYTE crew_level)
{
	HSTARSHIP hStarShip, hBuiltShip;
	SHIP_FRAGMENTPTR TemplatePtr;

	if ((hStarShip = GetStarShipFromIndex (&GLOBAL (avail_race_q), index)) == 0)
		return (0);

	TemplatePtr = (SHIP_FRAGMENTPTR)LockStarShip (
			&GLOBAL (avail_race_q), hStarShip
			);
	hBuiltShip =
			Build (pDstQueue,
			TemplatePtr->RaceResIndex,
			TemplatePtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY),
			(BYTE)(index == SAMATRA_SHIP ?
					0 : NameCaptain (pDstQueue, (STARSHIPPTR)TemplatePtr)));
	if (hBuiltShip)
	{
		SHIP_FRAGMENTPTR ShipFragPtr;

		ShipFragPtr = (SHIP_FRAGMENTPTR)LockStarShip (pDstQueue, hBuiltShip);
		ShipFragPtr->ShipInfo = TemplatePtr->ShipInfo;
		if (crew_level)
			ShipFragPtr->ShipInfo.crew_level = crew_level;
		ShipFragPtr->ShipInfo.energy_level = 0;
		ShipFragPtr->ShipInfo.ship_flags = 0;
		ShipFragPtr->ShipInfo.var1 = ShipFragPtr->ShipInfo.var2 = 0;
		ShipFragPtr->ShipInfo.loc.x = ShipFragPtr->ShipInfo.loc.y = 0;
		SET_RACE_ID (ShipFragPtr, (BYTE)index);
		UnlockStarShip (pDstQueue, hBuiltShip);
	}
	UnlockStarShip (
			&GLOBAL (avail_race_q), hStarShip
			);

	return (hBuiltShip);
}
Beispiel #6
0
static void
init_probe (void)
{
	BYTE b0, b1, b2, b3;
	HSTARSHIP hStarShip;

	b0 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS0);
	b1 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS1);
	b2 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS2);
	b3 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS3);
	GLOBAL (BattleGroupRef) = MAKE_DWORD (
			MAKE_WORD (b0, b1), MAKE_WORD (b2, b3)
			);
	if (GLOBAL (BattleGroupRef) == 0)
	{
		CloneShipFragment (URQUAN_PROBE_SHIP,
				&GLOBAL (npc_built_ship_q), 0);

		GLOBAL (BattleGroupRef) = PutGroupInfo (~0L, 1);
		b0 = LOBYTE (LOWORD (GLOBAL (BattleGroupRef)));
		b1 = HIBYTE (LOWORD (GLOBAL (BattleGroupRef)));
		b2 = LOBYTE (HIWORD (GLOBAL (BattleGroupRef)));
		b3 = HIBYTE (HIWORD (GLOBAL (BattleGroupRef)));
		SET_GAME_STATE (URQUAN_PROBE_GRPOFFS0, b0);
		SET_GAME_STATE (URQUAN_PROBE_GRPOFFS1, b1);
		SET_GAME_STATE (URQUAN_PROBE_GRPOFFS2, b2);
		SET_GAME_STATE (URQUAN_PROBE_GRPOFFS3, b3);
	}

	if (!GET_GAME_STATE (PROBE_MESSAGE_DELIVERED)
			&& GetGroupInfo (GLOBAL (BattleGroupRef), (BYTE)~0)
			&& (hStarShip = GetHeadLink (
					&GLOBAL (npc_built_ship_q)
					)))
	{
		SHIP_FRAGMENTPTR FragPtr;

		FragPtr = (SHIP_FRAGMENTPTR)LockStarShip (
				&GLOBAL (npc_built_ship_q), hStarShip
				);
		SET_GROUP_MISSION (FragPtr, IN_ORBIT);
		SET_GROUP_LOC (FragPtr, 2 + 1); /* orbitting earth */
		SET_GROUP_DEST (FragPtr, 2 + 1); /* orbitting earth */
		FragPtr->ShipInfo.loc.x = FragPtr->ShipInfo.loc.y = 0;
		FragPtr->ShipInfo.group_counter = 0;
		UnlockStarShip (
				&GLOBAL (npc_built_ship_q), hStarShip
				);
	}
}
Beispiel #7
0
static HSTARSHIP
BuildSIS (void)
{
	HSTARSHIP hStarShip;
	STARSHIP *StarShipPtr;

	hStarShip = Build (&race_q[0], SIS_SHIP_ID);
	if (!hStarShip)
		return 0;
	StarShipPtr = LockStarShip (&race_q[0], hStarShip);
	StarShipPtr->playerNr = RPG_PLAYER_NUM;
	StarShipPtr->captains_name_index = 0;
	UnlockStarShip (&race_q[0], hStarShip);

	return hStarShip;
}
Beispiel #8
0
HSTARSHIP
BuildSIS (void)
{
	HSTARSHIP hStarShip;
	STARSHIP *StarShipPtr;

	hStarShip = Build (&race_q[0], SIS_SHIP_ID);
	if (!hStarShip)
		return 0;
	StarShipPtr = LockStarShip (&race_q[0], hStarShip);
	StarShipPtr->which_side = GOOD_GUY;
	StarShipPtr->captains_name_index = 0;
	UnlockStarShip (&race_q[0], hStarShip);

	return hStarShip;
}
Beispiel #9
0
HSTARSHIP
GetStarShipFromIndex (PQUEUE pShipQ, COUNT Index)
{
	HSTARSHIP hStarShip, hNextShip;

	for (hStarShip = GetHeadLink (pShipQ);
			Index > 0 && hStarShip; hStarShip = hNextShip, --Index)
	{
		STARSHIPPTR StarShipPtr;

		StarShipPtr = LockStarShip (pShipQ, hStarShip);
		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockStarShip (pShipQ, hStarShip);
	}

	return (hStarShip);
}
Beispiel #10
0
BYTE
NameCaptain (PQUEUE pQueue, STARSHIPPTR StarShipPtr)
{
	BYTE name_index;
	HSTARSHIP hStarShip;

	do
	{
		HSTARSHIP hNextShip;

		name_index = PickCaptainName ();
		for (hStarShip = GetHeadLink (pQueue); hStarShip; hStarShip = hNextShip)
		{
			STARSHIPPTR TestShipPtr;

			TestShipPtr = LockStarShip (pQueue, hStarShip);
			hNextShip = _GetSuccLink (TestShipPtr);
			if (TestShipPtr->RaceResIndex == StarShipPtr->RaceResIndex)
			{
				BOOLEAN SameName;

				if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE)
					SameName = (BOOLEAN)(
							name_index == TestShipPtr->captains_name_index
							);
				else
					SameName = (BOOLEAN)(
							name_index == StarShipCaptain (TestShipPtr)
							);

				if (SameName)
				{
					UnlockStarShip (pQueue, hStarShip);
					break;
				}
			}
			UnlockStarShip (pQueue, hStarShip);
		}
	} while (hStarShip);

	return (name_index);
}
Beispiel #11
0
// Returns the <index>th available ship in the queue.
static HSTARSHIP
MeleeShipByUsedIndex (const QUEUE *queue, COUNT index)
{
	HSTARSHIP hShip;
	HSTARSHIP hNextShip;
	
	for (hShip = GetHeadLink (queue); hShip != 0; hShip = hNextShip)
	{
		STARSHIP *StarShipPtr = LockStarShip (queue, hShip);
		if ((StarShipPtr->SpeciesID != NO_ID) && index-- == 0)
		{
			UnlockStarShip (queue, hShip);
			break;
		}
		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockStarShip (queue, hShip);
	}

	return hShip;
}
Beispiel #12
0
COUNT
GetIndexFromStarShip (PQUEUE pShipQ, HSTARSHIP hStarShip)
{
	COUNT Index;

	Index = 0;
	while (hStarShip != GetHeadLink (pShipQ))
	{
		HSTARSHIP hNextShip;
		STARSHIPPTR StarShipPtr;

		StarShipPtr = LockStarShip (pShipQ, hStarShip);
		hNextShip = _GetPredLink (StarShipPtr);
		UnlockStarShip (pShipQ, hStarShip);

		hStarShip = hNextShip;
		++Index;
	}

	return (Index);
}
Beispiel #13
0
static int
flash_ship_task (void *data)
{
	DWORD TimeIn;
	COLOR c;
	Task task = (Task) data;

	c = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x00, 0x00), 0x24);
	TimeIn = GetTimeCounter ();
	while (!Task_ReadState (task, TASK_EXIT))
	{
		STAMP s;
		SHIP_FRAGMENTPTR StarShipPtr;
		COLOR OldColor;
		CONTEXT OldContext;

		LockMutex (GraphicsLock);
		s.origin = pMenuState->first_item;
		StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
				&GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame);
		s.frame = StarShipPtr->ShipInfo.icons;
		UnlockStarShip (&GLOBAL (built_ship_q),
				(HSTARSHIP)pMenuState->CurFrame);
		OldContext = SetContext (StatusContext);
		if (c >= BUILD_COLOR (MAKE_RGB15 (0x1F, 0x19, 0x19), 0x24))
			c = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x00, 0x00), 0x24);
		else
			c += BUILD_COLOR (MAKE_RGB15 (0x00, 0x02, 0x02), 0x00);
		OldColor = SetContextForeGroundColor (c);
		DrawFilledStamp (&s);
		SetContextForeGroundColor (OldColor);
		SetContext (OldContext);
		UnlockMutex (GraphicsLock);
		SleepThreadUntil (TimeIn + ONE_SECOND / 15);
		TimeIn = GetTimeCounter ();
	}
	FinishTask (task);
	return 0;
}
Beispiel #14
0
HSTARSHIP
Build (PQUEUE pQueue, DWORD RaceResIndex, COUNT which_player, BYTE
		captains_name_index)
{
	HSTARSHIP hNewShip;

	if ((hNewShip = AllocStarShip (pQueue)) != 0)
	{
		STARSHIPPTR StarShipPtr;

		StarShipPtr = LockStarShip (pQueue, hNewShip);
		memset (StarShipPtr, 0, GetLinkSize (pQueue));

		StarShipPtr->RaceResIndex = RaceResIndex;
		OwnStarShip (StarShipPtr, which_player, captains_name_index);

		UnlockStarShip (pQueue, hNewShip);
		PutQueue (pQueue, hNewShip);
	}

	return (hNewShip);
}
Beispiel #15
0
static COUNT
GetRaceQueueValue (const QUEUE *queue) {
	COUNT result;
	HSTARSHIP hBattleShip, hNextShip;

	result = 0;
	for (hBattleShip = GetHeadLink (queue);
			hBattleShip != 0; hBattleShip = hNextShip)
	{
		STARSHIP *StarShipPtr = LockStarShip (queue, hBattleShip);
		hNextShip = _GetSuccLink (StarShipPtr);
		
		if (StarShipPtr->SpeciesID == NO_ID)
			continue;  // Not active any more.

		result += StarShipPtr->ship_cost;

		UnlockStarShip (queue, hBattleShip);
	}

	return result;
}
Beispiel #16
0
// Returns the <index>th ship in the queue, or 0 if it is not available.
static HSTARSHIP
MeleeShipByQueueIndex (const QUEUE *queue, COUNT index)
{
	HSTARSHIP hShip;
	HSTARSHIP hNextShip;
	
	for (hShip = GetHeadLink (queue); hShip != 0; hShip = hNextShip)
	{
		STARSHIP *StarShipPtr = LockStarShip (queue, hShip);
		if (StarShipPtr->index == index)
		{
			hNextShip = hShip;
			if (StarShipPtr->SpeciesID == NO_ID)
				hShip = 0;
			UnlockStarShip (queue, hNextShip);
			break;
		}
		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockStarShip (queue, hShip);
	}

	return hShip;
}
Beispiel #17
0
// Put the ship icons in the PickMeleeFrame, and create a queue
// for each player.
// XXX TODO: split off creating the queue into a separate function.
void
FillPickMeleeFrame (MeleeSetup *setup)
{
	COUNT i;
	CONTEXT OldContext;

	OldContext = SetContext (OffScreenContext);

	for (i = 0; i < NUM_SIDES; ++i)
	{
		COUNT side;
		COUNT sideI;
		RECT r;
		TEXT t;
		STAMP s;
		UNICODE buf[30];
		FleetShipIndex index;

		sideI = GetPlayerOrder (i);
		side = !sideI;

		s.frame = SetAbsFrameIndex (PickMeleeFrame, side);
		SetContextFGFrame (s.frame);

		GetFrameRect (s.frame, &r);
		t.baseline.x = r.extent.width >> 1;
		t.baseline.y = r.extent.height - NAME_AREA_HEIGHT + RES_SCALE(4);

		r.corner.x += RES_SCALE(2);
		r.corner.y += RES_SCALE(2);
		r.extent.width -= RES_SCALE((2 * 2) + (RES_DESCALE(ICON_WIDTH) + 2) + 1); // JMS_GFX
		r.extent.height -= RES_SCALE(2 * 2) + NAME_AREA_HEIGHT; // JMS_GFX
		SetContextForeGroundColor (PICK_BG_COLOR);
		DrawFilledRectangle (&r);

		r.corner.x += RES_SCALE(2); // JMS_GFX
		r.extent.width += RES_SCALE((RES_DESCALE(ICON_WIDTH) + 2) - (2 * 2)); // JMS_GFX
		r.corner.y += r.extent.height;
		r.extent.height = NAME_AREA_HEIGHT;
		DrawFilledRectangle (&r);

		// Team name at the bottom of the frame:
		t.align = ALIGN_CENTER;
		t.pStr = MeleeSetup_getTeamName (setup, sideI);
		t.CharCount = (COUNT) ~0;
		SetContextFont (TinyFont);
		SetContextForeGroundColor (PICKSHIP_TEAM_NAME_TEXT_COLOR);
		font_DrawText (&t);

		// Total team value of the starting team:
		sprintf (buf, "%u", MeleeSetup_getFleetValue (setup, sideI));
		t.baseline.x = RES_SCALE(4);
		t.baseline.y = RES_SCALE(7);
		t.align = ALIGN_LEFT;
		t.pStr = buf;
		t.CharCount = (COUNT)~0;
		SetContextForeGroundColor (PICKSHIP_TEAM_START_VALUE_COLOR);
		font_DrawText (&t);

		assert (CountLinks (&race_q[side]) == 0);

		for (index = 0; index < MELEE_FLEET_SIZE; index++)
		{
			MeleeShip StarShip;

			StarShip = MeleeSetup_getShip (setup, sideI, index);
			if (StarShip == MELEE_NONE)
				continue;

			{
				BYTE row, col;
				BYTE ship_cost;
				HMASTERSHIP hMasterShip;
				HSTARSHIP hBuiltShip;
				MASTER_SHIP_INFO *MasterPtr;
				STARSHIP *BuiltShipPtr;
				BYTE captains_name_index;

				hMasterShip = GetStarShipFromIndex (&master_q, StarShip);
				MasterPtr = LockMasterShip (&master_q, hMasterShip);

				captains_name_index = NameCaptain (&race_q[side],
						MasterPtr->SpeciesID);
				hBuiltShip = Build (&race_q[side], MasterPtr->SpeciesID);

				// Draw the icon.
				row = PickMelee_GetShipRow (index);
				col = PickMelee_GetShipColumn (index);
				s.origin.x = RES_SCALE(4) + ((ICON_WIDTH + RES_SCALE(2)) * col); // JMS_GFX
				s.origin.y = RES_SCALE(10) + ((ICON_HEIGHT + RES_SCALE(2)) * row);
				s.frame = MasterPtr->ShipInfo.icons;
				DrawStamp (&s);

				ship_cost = MasterPtr->ShipInfo.ship_cost;
				UnlockMasterShip (&master_q, hMasterShip);

				BuiltShipPtr = LockStarShip (&race_q[side], hBuiltShip);
				BuiltShipPtr->index = index;
				BuiltShipPtr->ship_cost = ship_cost;
				BuiltShipPtr->playerNr = side;
				BuiltShipPtr->captains_name_index = captains_name_index;
				// The next ones are not used in Melee
				BuiltShipPtr->crew_level = 0;
				BuiltShipPtr->max_crew = 0;
				BuiltShipPtr->race_strings = 0;
				BuiltShipPtr->icons = 0;
				BuiltShipPtr->RaceDescPtr = 0;
				UnlockStarShip (&race_q[side], hBuiltShip);
			}
		}
	}

	SetContext (OldContext);
}
Beispiel #18
0
static void
ProcessInput (void)
{
	BOOLEAN CanRunAway;
	size_t sideI;

#ifdef NETPLAY
	netInput ();
#endif

	CanRunAway = RunAwayAllowed ();
		
	for (sideI = 0; sideI < NUM_SIDES; sideI++)
	{
		HSTARSHIP hBattleShip, hNextShip;
		size_t cur_player = battleInputOrder[sideI];

		for (hBattleShip = GetHeadLink (&race_q[cur_player]);
				hBattleShip != 0; hBattleShip = hNextShip)
		{
			BATTLE_INPUT_STATE InputState;
			STARSHIP *StarShipPtr;

			StarShipPtr = LockStarShip (&race_q[cur_player], hBattleShip);
			hNextShip = _GetSuccLink (StarShipPtr);

			if (StarShipPtr->hShip)
			{
				// TODO: review and see if we have to do this every frame, or
				//   if we can do this once somewhere
				StarShipPtr->control = PlayerControl[cur_player];
				
				InputState = PlayerInput[cur_player]->handlers->frameInput (
						PlayerInput[cur_player], StarShipPtr);

#if CREATE_JOURNAL
				JournalInput (InputState);
#endif /* CREATE_JOURNAL */
#ifdef NETPLAY
				if (!(PlayerControl[cur_player] & NETWORK_CONTROL))
				{
					BattleInputBuffer *bib = getBattleInputBuffer(cur_player);
					Netplay_NotifyAll_battleInput (InputState);
					flushPacketQueues ();

					BattleInputBuffer_push (bib, InputState);
							// Add this input to the end of the buffer.
					BattleInputBuffer_pop (bib, &InputState);
							// Get the input from the front of the buffer.
				}
#endif

				StarShipPtr->ship_input_state = 0;
				if (StarShipPtr->RaceDescPtr->ship_info.crew_level)
				{
					if (InputState & BATTLE_LEFT)
						StarShipPtr->ship_input_state |= LEFT;
					else if (InputState & BATTLE_RIGHT)
						StarShipPtr->ship_input_state |= RIGHT;
					if (InputState & BATTLE_THRUST)
						StarShipPtr->ship_input_state |= THRUST;
					if (InputState & BATTLE_WEAPON)
						StarShipPtr->ship_input_state |= WEAPON;
					if (InputState & BATTLE_SPECIAL)
						StarShipPtr->ship_input_state |= SPECIAL;
					if (InputState & BATTLE_DOWN)
						StarShipPtr->ship_input_state |= DOWN; // JMS_KEYS: Down key is now in use!

					if (CanRunAway && cur_player == 0 &&
							(InputState & BATTLE_ESCAPE))
						DoRunAway (StarShipPtr);
				}
			}

			UnlockStarShip (&race_q[cur_player], hBattleShip);
		}
	}
	
#ifdef NETPLAY
	flushPacketQueues ();
#endif

	if (GLOBAL (CurrentActivity) & (CHECK_LOAD | CHECK_ABORT))
		GLOBAL (CurrentActivity) &= ~IN_BATTLE;
}
Beispiel #19
0
COUNT
ActivateStarShip (COUNT which_ship, SIZE state)
{
	HSTARSHIP hStarShip, hNextShip;

	hStarShip = GetStarShipFromIndex (
			&GLOBAL (avail_race_q), which_ship
			);
	if (hStarShip)
	{
		switch (state)
		{
			case SPHERE_TRACKING:
			case SPHERE_KNOWN:
			{
				EXTENDED_SHIP_FRAGMENTPTR StarShipPtr;

				StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip (
						&GLOBAL (avail_race_q), hStarShip
						);
				if (state == SPHERE_KNOWN)
					which_ship = StarShipPtr->ShipInfo.known_strength;
				else if (StarShipPtr->ShipInfo.actual_strength == 0)
				{
					if (!(StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY)))
						which_ship = 0;
				}
				else if (StarShipPtr->ShipInfo.known_strength == 0
						&& StarShipPtr->ShipInfo.actual_strength != (COUNT)~0)
				{
					StarShipPtr->ShipInfo.known_strength = 1;
					StarShipPtr->ShipInfo.known_loc =
							StarShipPtr->ShipInfo.loc;
				}
				UnlockStarShip (
						&GLOBAL (avail_race_q), hStarShip
						);
				return (which_ship);
			}
			case ESCORT_WORTH:
				which_ship = 0;
			case ESCORTING_FLAGSHIP:
			{
				COUNT ShipCost[] =
				{
					RACE_SHIP_COST
				};

				for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
						hStarShip; hStarShip = hNextShip)
				{
					BYTE ship_type;
					SHIP_FRAGMENTPTR StarShipPtr;

					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (built_ship_q), hStarShip
							);
					hNextShip = _GetSuccLink (StarShipPtr);
					if (state == ESCORT_WORTH)
						which_ship += ShipCost[GET_RACE_ID (StarShipPtr)];
					else
						ship_type = GET_RACE_ID (StarShipPtr);
					UnlockStarShip (
							&GLOBAL (built_ship_q), hStarShip
							);

					if (state != ESCORT_WORTH
							&& (COUNT)ship_type == which_ship)
						return (1);
				}

				return (state == ESCORTING_FLAGSHIP ? 0 : which_ship);
			}
			case FEASIBILITY_STUDY:
				return (MAX_BUILT_SHIPS
						- CountLinks (&GLOBAL (built_ship_q)));
			default:
			{
				SHIP_FRAGMENTPTR StarShipPtr;

				if (state <= 0)
				{
					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
					if (state == CHECK_ALLIANCE)
					{
						state = StarShipPtr->ShipInfo.ship_flags
								& (GOOD_GUY | BAD_GUY);
						UnlockStarShip (
								&GLOBAL (avail_race_q), hStarShip
								);
						return ((COUNT)state);
					}
					else if (StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY))
					{
						StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY);
						if (state == 0)
							StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY;
						else
						{
							StarShipPtr->ShipInfo.ship_flags |= BAD_GUY;
							if (which_ship == ORZ_SHIP)
							{
								BOOLEAN ShipRemoved;

								ShipRemoved = FALSE;
								for (hStarShip = GetHeadLink (
										&GLOBAL (built_ship_q
										)); hStarShip; hStarShip = hNextShip)
								{
									BOOLEAN RemoveShip;
									SHIP_FRAGMENTPTR StarShipPtr;

									StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
											&GLOBAL (built_ship_q),
											hStarShip
											);
									hNextShip = _GetSuccLink (StarShipPtr);
									RemoveShip = (BOOLEAN)(
											GET_RACE_ID (StarShipPtr) == ORZ_SHIP
											);
									UnlockStarShip (
											&GLOBAL (built_ship_q),
											hStarShip
											);

									if (RemoveShip)
									{
										ShipRemoved = TRUE;

										RemoveQueue (
												&GLOBAL (built_ship_q),
												hStarShip
												);
										FreeStarShip (
												&GLOBAL (built_ship_q),
												hStarShip
												);
									}
								}
								
								if (ShipRemoved)
								{
									SetSemaphore (GraphicsSem);
									DeltaSISGauges (UNDEFINED_DELTA,
											UNDEFINED_DELTA, UNDEFINED_DELTA);
									ClearSemaphore (GraphicsSem);
								}
							}
						}
					}
					UnlockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
				}
				else
				{
					BYTE which_window;
						COUNT i;

					which_window = 0;
					for
						(
								i = 0;
								
								i < (COUNT)state
							&&
								(
										hStarShip = CloneShipFragment
										(
												(COUNT)which_ship,
												(PQUEUE)(&GLOBAL (built_ship_q)),
												(BYTE)
												(
														(
																which_ship == SPATHI_SHIP &&
																								GET_GAME_STATE (FOUND_PLUTO_SPATHI)
														) == 1 ? 1 : 0
												)
										)
								);

							i++
						)
					{
						HSTARSHIP hOldShip;

						RemoveQueue (
								&GLOBAL (built_ship_q),
								hStarShip
								);

						while ((hOldShip = GetStarShipFromIndex (
								&GLOBAL (built_ship_q),
								which_window++
								)))
						{
							BYTE win_loc;

							StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
									&GLOBAL (built_ship_q), hOldShip
									);
							win_loc = GET_GROUP_LOC (StarShipPtr);
							UnlockStarShip (
									&GLOBAL (built_ship_q), hOldShip
									);
							if (which_window <= win_loc)
								break;
						}

						StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
								&GLOBAL (built_ship_q), hStarShip
								);
						SET_GROUP_LOC (StarShipPtr, which_window - 1);
						if (which_ship == SPATHI_SHIP
								&& GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1)
						{
							OwnStarShip (StarShipPtr,
									GOOD_GUY,
									NAME_OFFSET + NUM_CAPTAINS_NAMES);
						}
						UnlockStarShip (
								&GLOBAL (built_ship_q), hStarShip
								);

						InsertQueue (
								&GLOBAL (built_ship_q),
								hStarShip, hOldShip
								);
					}

					SetSemaphore (GraphicsSem);
					DeltaSISGauges (UNDEFINED_DELTA,
							UNDEFINED_DELTA, UNDEFINED_DELTA);
					ClearSemaphore (GraphicsSem);
					return (i);
				}
				break;
			}
		}

		return (1);
	}

	return (0);
}
Beispiel #20
0
static BOOLEAN
DoModifyRoster (PMENU_STATE pMS)
{
	BYTE NewState;
	SBYTE sx, sy;
	RECT r;
	STAMP s;
	SHIP_FRAGMENTPTR StarShipPtr;
	BOOLEAN select, cancel, up, down, horiz;

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		LockMutex (GraphicsLock);
		RosterCleanup (pMS);
		UnlockMutex (GraphicsLock);
		pMS->CurFrame = 0;

		return FALSE;
	}

	select = PulsedInputState.menu[KEY_MENU_SELECT];
	cancel = PulsedInputState.menu[KEY_MENU_CANCEL];
	up = PulsedInputState.menu[KEY_MENU_UP];
	down = PulsedInputState.menu[KEY_MENU_DOWN];
	horiz = PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT];

	if (pMS->Initialized && (pMS->CurState & SHIP_TOGGLE))
	{
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
				MENU_SOUND_SELECT | MENU_SOUND_CANCEL);
	}
	else
	{
		SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
	}

	if (!pMS->Initialized)
	{
		pMS->InputFunc = DoModifyRoster;
		pMS->Initialized = TRUE;

		pMS->CurState = NewState = 0;
		LockMutex (GraphicsLock);
		SetContext (StatusContext);
		goto SelectSupport;
	}
	else if (cancel && !(pMS->CurState & SHIP_TOGGLE))
	{
		LockMutex (GraphicsLock);
		SetFlashRect (NULL_PTR, (FRAME)0);
		RosterCleanup (pMS);
		pMS->CurFrame = 0;
		DrawStatusMessage (NULL_PTR);
		UnlockMutex (GraphicsLock);

		return FALSE;
	}
	else if (select || cancel)
	{
		LockMutex (GraphicsLock);
		pMS->CurState ^= SHIP_TOGGLE;
		if (!(pMS->CurState & SHIP_TOGGLE))
			SetFlashRect (NULL_PTR, (FRAME)0);
		else
		{
			RosterCleanup (pMS);

			r.corner.x = 2;
			r.corner.y = 130;
			r.extent.width = STATUS_MESSAGE_WIDTH;
			r.extent.height = STATUS_MESSAGE_HEIGHT;
			SetContext (StatusContext);
			SetFlashRect (&r, (FRAME)0);
		}
		UnlockMutex (GraphicsLock);
	}
	else if (pMS->CurState & SHIP_TOGGLE)
	{
		SIZE delta = 0;
		BOOLEAN failed = FALSE;

		if (up)
		{
			sy = -1;
			if (GLOBAL_SIS (CrewEnlisted))
				delta = 1;
			else
				failed = TRUE;
		}
		else if (down)
		{
			sy = 1;
			if (GLOBAL_SIS (CrewEnlisted) < GetCPodCapacity (NULL_PTR))
				delta = -1;
			else
				failed = TRUE;
		}
		
		if (delta != 0)
		{
			LockMutex (GraphicsLock);
			failed = !DeltaSupportCrew (delta);
			UnlockMutex (GraphicsLock);
		}
		if (failed)
		{	// not enough room or crew
			PlayMenuSound (MENU_SOUND_FAILURE);
		}
	}
	else
	{
		PPOINT pship_pos;

		NewState = pMS->CurState;
		sx = (SBYTE)((pMS->delta_item + 1) >> 1);
		if (horiz)
		{
			pship_pos = (PPOINT)pMS->flash_frame1;
			if (NewState == (BYTE)(sx - 1))
				NewState = (BYTE)(pMS->delta_item - 1);
			else if (NewState >= (BYTE)sx)
			{
				NewState -= sx;
				if (pship_pos[NewState].y < pship_pos[pMS->CurState].y)
					++NewState;
			}
			else
			{
				NewState += sx;
				if (NewState != (BYTE)sx
						&& pship_pos[NewState].y > pship_pos[pMS->CurState].y)
					--NewState;
			}
		}
		else if (down)
		{
			sy = 1;
			if (++NewState == (BYTE)pMS->delta_item)
				NewState = (BYTE)(sx - 1);
			else if (NewState == (BYTE)sx)
				NewState = 0;
		}
		else if (up)
		{
			sy = -1;
			if (NewState == 0)
				NewState += sx - 1;
			else if (NewState == (BYTE)sx)
				NewState = (BYTE)(pMS->delta_item - 1);
			else
				--NewState;
		}

		if (NewState != pMS->CurState)
		{
			LockMutex (GraphicsLock);
			SetContext (StatusContext);
			s.origin = pMS->first_item;
			StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
					&GLOBAL (built_ship_q),
					(HSTARSHIP)pMS->CurFrame
					);
			s.frame = StarShipPtr->ShipInfo.icons;
			UnlockStarShip (
					&GLOBAL (built_ship_q),
					(HSTARSHIP)pMS->CurFrame
					);
			DrawStamp (&s);
SelectSupport:
			pship_pos = (PPOINT)pMS->flash_frame1;
			pMS->first_item = pship_pos[NewState];
			pMS->CurFrame = (FRAME)MatchSupportShip (pMS);

			DeltaSupportCrew (0);
			UnlockMutex (GraphicsLock);

			pMS->CurState = NewState;
		}

		if (pMS->flash_task == 0)
			pMS->flash_task = AssignTask (flash_ship_task, 2048,
					"flash roster menu");
	}

	return TRUE;
}
/*
 * What this function does depends on the value of the 'state' argument:
 * SPHERE_TRACKING:
 * 	The sphere of influence for the race for 'which_ship' will be shown
 * 	on the starmap in the future.
 * 	The value returned is 'which_ship', unless the type of ship is only
 * 	available in SuperMelee, in which case 0 is returned.
 * SPHERE_KNOWN:
 * 	The size of the fleet of the race of 'which_ship' when the starmap was
 * 	last checked is returned.
 * ESCORT_WORTH:
 * 	The total value of all the ships escorting the SIS is returned.
 * 	'which_ship' is ignored.
 * ESCORTING_FLAGSHIP:
 * 	Test if a ship of type 'which_ship' is among the escorts of the SIS
 * 	0 is returned if false, 1 if true.
 * FEASIBILITY_STUDY:
 * 	Test if the SIS can have an escort of type 'which_ship'.
 * 	0 is returned if 'which_ship' is not available.
 * 	Otherwise, the number of ships that can be added is returned.
 * CHECK_ALLIANCE:
 * 	Test the alliance status of the race of 'which_ship'.
 *      Either GOOD_GUY (allied) or BAD_GUY (not allied) is returned.
 * 0:
 * 	Ally with the race of 'which_ship'. This makes their ship available
 *  for building in the shipyard.
 * -1:
 * 	End an alliance with the race of 'which_ship'. This ends the possibility
 * 	of building their ships in the shipyard. For the Orz also the ships the
 * 	player has with him will disappear.
 * any other positive number:
 * 	Give the player this much ships of type 'which_ship'. If it's
 */
COUNT
ActivateStarShip (COUNT which_ship, SIZE state)
{
	HSTARSHIP hStarShip, hNextShip;

	hStarShip = GetStarShipFromIndex (
			&GLOBAL (avail_race_q), which_ship
			);
	if (hStarShip)
	{
		switch (state)
		{
			case SPHERE_TRACKING:
			case SPHERE_KNOWN:
			{
				EXTENDED_SHIP_FRAGMENTPTR StarShipPtr;

				StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip (
						&GLOBAL (avail_race_q), hStarShip);
				if (state == SPHERE_KNOWN)
					which_ship = StarShipPtr->ShipInfo.known_strength;
				else if (StarShipPtr->ShipInfo.actual_strength == 0)
				{
					if (!(StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY)))
						which_ship = 0;
				}
				else if (StarShipPtr->ShipInfo.known_strength == 0
						&& StarShipPtr->ShipInfo.actual_strength != (COUNT)~0)
				{
					StarShipPtr->ShipInfo.known_strength = 1;
					StarShipPtr->ShipInfo.known_loc =
							StarShipPtr->ShipInfo.loc;
				}
				UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
				return (which_ship);
			}
			case ESCORT_WORTH:
			{
				COUNT ShipCost[] =
				{
					RACE_SHIP_COST
				};
				COUNT total = 0;

				for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
						hStarShip; hStarShip = hNextShip)
				{
					SHIP_FRAGMENTPTR StarShipPtr;

					StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip (
							&GLOBAL (built_ship_q), hStarShip);
					hNextShip = _GetSuccLink (StarShipPtr);
					total += ShipCost[GET_RACE_ID (StarShipPtr)];
					UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);
				}
				return total;
			}
			case ESCORTING_FLAGSHIP:
			{
				for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
						hStarShip; hStarShip = hNextShip)
				{
					BYTE ship_type;
					SHIP_FRAGMENTPTR StarShipPtr;

					StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip (
							&GLOBAL (built_ship_q), hStarShip);
					hNextShip = _GetSuccLink (StarShipPtr);
					ship_type = GET_RACE_ID (StarShipPtr);
					UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);

					if ((COUNT) ship_type == which_ship)
						return 1;
				}
				return 0;
			}
			case FEASIBILITY_STUDY:
				return (MAX_BUILT_SHIPS
						- CountLinks (&GLOBAL (built_ship_q)));
			default:
			{
				SHIP_FRAGMENTPTR StarShipPtr;

				if (state <= 0)
				{
					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
					if (state == CHECK_ALLIANCE)
					{
						state = StarShipPtr->ShipInfo.ship_flags
								& (GOOD_GUY | BAD_GUY);
						UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
						return ((COUNT)state);
					}
					else if (StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY))
					{
						StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY);
						if (state == 0)
							StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY;
						else
						{
							StarShipPtr->ShipInfo.ship_flags |= BAD_GUY;
							if (which_ship == ORZ_SHIP)
							{
								BOOLEAN ShipRemoved;

								ShipRemoved = FALSE;
								for (hStarShip = GetHeadLink (
										&GLOBAL (built_ship_q));
										hStarShip; hStarShip = hNextShip)
								{
									BOOLEAN RemoveShip;
									SHIP_FRAGMENTPTR StarShipPtr2;

									StarShipPtr2 =
											(SHIP_FRAGMENTPTR)LockStarShip (
											&GLOBAL (built_ship_q), hStarShip);
									hNextShip = _GetSuccLink (StarShipPtr2);
									RemoveShip = (BOOLEAN) (
											GET_RACE_ID (StarShipPtr2) ==
											ORZ_SHIP);
									UnlockStarShip (&GLOBAL (built_ship_q),
											hStarShip);

									if (RemoveShip)
									{
										ShipRemoved = TRUE;

										RemoveQueue (&GLOBAL (built_ship_q),
												hStarShip);
										FreeStarShip (&GLOBAL (built_ship_q),
												hStarShip);
									}
								}
								
								if (ShipRemoved)
								{
									LockMutex (GraphicsLock);
									DeltaSISGauges (UNDEFINED_DELTA,
											UNDEFINED_DELTA, UNDEFINED_DELTA);
									UnlockMutex (GraphicsLock);
								}
							}
						}
					}
					UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
				}
				else
				{
					/* 'state > 0', add ships to the escorts */
					BYTE which_window;
					COUNT i;

					which_window = 0;
					for (i = 0; i < (COUNT)state; i++)
					{
						HSTARSHIP hOldShip;
						BYTE crewLevel;

						if (which_ship == SPATHI_SHIP &&
								GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1)
							crewLevel = 1;  // Only Fwiffo is on board.
						else
							crewLevel = 0;  // Crewed to the max
								
						hStarShip = CloneShipFragment((COUNT) which_ship,
								&GLOBAL (built_ship_q), crewLevel);
						if (!hStarShip)
							break;

						RemoveQueue (&GLOBAL (built_ship_q), hStarShip);

						while ((hOldShip = GetStarShipFromIndex (
								&GLOBAL (built_ship_q), which_window++)))
						{
							BYTE win_loc;

							StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
									&GLOBAL (built_ship_q), hOldShip);
							win_loc = GET_GROUP_LOC (StarShipPtr);
							UnlockStarShip (&GLOBAL (built_ship_q),
									hOldShip);
							if (which_window <= win_loc)
								break;
						}

						StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
								&GLOBAL (built_ship_q), hStarShip);
						SET_GROUP_LOC (StarShipPtr, which_window - 1);
						if (which_ship == SPATHI_SHIP
								&& GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1)
						{
							OwnStarShip (StarShipPtr, GOOD_GUY,
									NAME_OFFSET + NUM_CAPTAINS_NAMES);
						}
						UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);

						InsertQueue (&GLOBAL (built_ship_q), hStarShip,
								hOldShip);
					}

					LockMutex (GraphicsLock);
					DeltaSISGauges (UNDEFINED_DELTA,
							UNDEFINED_DELTA, UNDEFINED_DELTA);
					UnlockMutex (GraphicsLock);
					return (i);
				}
				break;
			}
		}

		return 1;
	}

	return 0;
}