Пример #1
0
void free_region(region * r)
{
    if (last == r)
        last = NULL;
    free(r->display);
    if (r->land)
        free_land(r->land);

    if (r->msgs) {
        free_messagelist(r->msgs->begin);
        free(r->msgs);
        r->msgs = 0;
    }

    while (r->individual_messages) {
        struct individual_message *msg = r->individual_messages;
        r->individual_messages = msg->next;
        if (msg->msgs) {
            free_messagelist(msg->msgs->begin);
            free(msg->msgs);
        }
        free(msg);
    }

    while (r->attribs)
        a_remove(&r->attribs, r->attribs);
    while (r->resources) {
        rawmaterial *res = r->resources;
        r->resources = res->next;
        free(res);
    }

    while (r->units) {
        unit *u = r->units;
        r->units = u->next;
        uunhash(u);
        free_unit(u);
        free(u);
    }

    while (r->buildings) {
        building *b = r->buildings;
        assert(b->region == r);
        r->buildings = b->next;
        bunhash(b);                 /* must be done here, because remove_building does it, and wasn't called */
        free_building(b);
    }

    while (r->ships) {
        ship *s = r->ships;
        assert(s->region == r);
        r->ships = s->next;
        sunhash(s);
        free_ship(s);
    }

    free(r);
}
Пример #2
0
void
UninitShips (void)
{
	COUNT crew_retrieved;
	int i;
	HELEMENT hElement, hNextElement;
	STARSHIP *SPtr[NUM_PLAYERS];

	StopSound ();

	UninitSpace ();

	for (i = 0; i < NUM_PLAYERS; ++i)
		SPtr[i] = 0;

	// Count the crew floating in space.
	crew_retrieved = CountCrewElements();

	for (hElement = GetHeadElement ();
			hElement != 0; hElement = hNextElement)
	{
		ELEMENT *ElementPtr;

		LockElement (hElement, &ElementPtr);
		hNextElement = GetSuccElement (ElementPtr);
		if ((ElementPtr->state_flags & PLAYER_SHIP)
				|| ElementPtr->death_func == new_ship)
		{
			STARSHIP *StarShipPtr;

			GetElementStarShip (ElementPtr, &StarShipPtr);

			// There should only be one ship left in battle.
			// He gets the crew still floating in space.
			if (StarShipPtr->RaceDescPtr->ship_info.crew_level)
			{
				if (crew_retrieved >=
						StarShipPtr->RaceDescPtr->ship_info.max_crew -
						StarShipPtr->RaceDescPtr->ship_info.crew_level)
					StarShipPtr->RaceDescPtr->ship_info.crew_level =
							StarShipPtr->RaceDescPtr->ship_info.max_crew;
				else
					StarShipPtr->RaceDescPtr->ship_info.crew_level +=
							crew_retrieved;
			}

			/* Record crew left after battle */
			StarShipPtr->crew_level =
					StarShipPtr->RaceDescPtr->ship_info.crew_level;
			SPtr[StarShipPtr->playerNr] = StarShipPtr;
			free_ship (StarShipPtr->RaceDescPtr, TRUE, TRUE);
			StarShipPtr->RaceDescPtr = 0;
		}
		UnlockElement (hElement);
	}

	GLOBAL (CurrentActivity) &= ~IN_BATTLE;

	if (LOBYTE (GLOBAL (CurrentActivity)) == IN_ENCOUNTER
			&& !(GLOBAL (CurrentActivity) & CHECK_ABORT))
	{
		// Encounter battle in full game.
		//   Record the crew left in the last ship standing. The crew left
		//   is first recorded into STARSHIP.crew_level just a few lines
		//   above here.
		for (i = NUM_PLAYERS - 1; i >= 0; --i)
		{
			if (SPtr[i] && !FleetIsInfinite (i))
				UpdateShipFragCrew (SPtr[i]);
		}
	}

	if (LOBYTE (GLOBAL (CurrentActivity)) != IN_ENCOUNTER)
	{
		// Remove any ships left from the race queue.
		for (i = 0; i < NUM_PLAYERS; i++)
			ReinitQueue (&race_q[i]);

		if (inHQSpace ())
			FreeHyperspace ();
	}
}
Пример #3
0
void
UninitShips (void)
{
	COUNT crew_retrieved;
	SIZE i;
	HELEMENT hElement, hNextElement;
	STARSHIP *SPtr[NUM_PLAYERS];

	StopSound ();

	UninitSpace ();

	for (i = 0; i < NUM_PLAYERS; ++i)
		SPtr[i] = 0;

	// Count the crew floating in space.
	crew_retrieved = CountCrewElements();

	for (hElement = GetHeadElement ();
			hElement != 0; hElement = hNextElement)
	{
		ELEMENT *ElementPtr;
		extern void new_ship (ELEMENT *ElementPtr);

		LockElement (hElement, &ElementPtr);
		hNextElement = GetSuccElement (ElementPtr);
		if ((ElementPtr->state_flags & PLAYER_SHIP)
				|| ElementPtr->death_func == new_ship)
		{
			STARSHIP *StarShipPtr;

			GetElementStarShip (ElementPtr, &StarShipPtr);

			// There should only be one ship left in battle.
			// He gets the crew still floating in space.
			if (StarShipPtr->RaceDescPtr->ship_info.crew_level)
			{
				if (crew_retrieved >=
						StarShipPtr->RaceDescPtr->ship_info.max_crew -
						StarShipPtr->RaceDescPtr->ship_info.crew_level)
					StarShipPtr->RaceDescPtr->ship_info.crew_level =
							StarShipPtr->RaceDescPtr->ship_info.max_crew;
				else
					StarShipPtr->RaceDescPtr->ship_info.crew_level +=
							crew_retrieved;
			}

			if (StarShipPtr->RaceDescPtr->uninit_func != NULL)
				(*StarShipPtr->RaceDescPtr->uninit_func) (
						StarShipPtr->RaceDescPtr);
			/* Record crew left after battle */
			StarShipPtr->crew_level =
					StarShipPtr->RaceDescPtr->ship_info.crew_level;
			SPtr[WHICH_SIDE (ElementPtr->state_flags)] = StarShipPtr;
			free_ship (StarShipPtr->RaceDescPtr, TRUE, TRUE);
			StarShipPtr->RaceDescPtr = 0;
		}
		UnlockElement (hElement);
	}

	GLOBAL (CurrentActivity) &= ~IN_BATTLE;

	if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE)
	{
	}
	else if (LOBYTE (GLOBAL (CurrentActivity)) <= IN_ENCOUNTER
			&& !(GLOBAL (CurrentActivity) & CHECK_ABORT))
	{
		// XXX: This has no purpose for SuperMelee
		//   In full-game, the sole purpose of this is to record the crew
		//   left in the last ship standing. The crew left is first recorded
		//   into STARSHIP.crew_level just a few lines above here.
		for (i = NUM_PLAYERS - 1; i >= 0; --i)
		{
			if (SPtr[i])
				GetEncounterStarShip (SPtr[i], i);
		}
	}

	if (LOBYTE (GLOBAL (CurrentActivity)) != IN_ENCOUNTER)
	{
		// Remove any ships left from the race queue.
		for (i = 0; i < NUM_PLAYERS; i++)
			ReinitQueue (&race_q[i]);

		if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE)
			FreeHyperspace ();
	}
}
Пример #4
0
void
UninitShips (void)
{
	BYTE crew_retrieved;
	SIZE i;
	HELEMENT hElement, hNextElement;
	STARSHIPPTR SPtr[NUM_PLAYERS];

	StopSound ();

	UninitSpace ();

	for (i = 0; i < NUM_PLAYERS; ++i)
		SPtr[i] = 0;

	// Count the crew floating in space.
	crew_retrieved = 0;
	for (hElement = GetHeadElement ();
			hElement != 0; hElement = hNextElement)
	{
		ELEMENTPTR ElementPtr;
		LockElement (hElement, &ElementPtr);
		hNextElement = GetSuccElement (ElementPtr);
		if (ElementPtr->state_flags & CREW_OBJECT)
			++crew_retrieved;
		UnlockElement (hElement);
	}

	for (hElement = GetHeadElement ();
			hElement != 0; hElement = hNextElement)
	{
		ELEMENTPTR ElementPtr;
		extern void new_ship (PELEMENT ElementPtr);

		LockElement (hElement, &ElementPtr);
		hNextElement = GetSuccElement (ElementPtr);
		if ((ElementPtr->state_flags & PLAYER_SHIP)
				|| ElementPtr->death_func == new_ship)
		{
			STARSHIPPTR StarShipPtr;

			GetElementStarShip (ElementPtr, &StarShipPtr);

			// There should only be one ship left in battle.
			// He gets the crew still floating in space.
			if (StarShipPtr->RaceDescPtr->ship_info.crew_level)
			{
				if (crew_retrieved >=
						StarShipPtr->RaceDescPtr->ship_info.max_crew -
						StarShipPtr->RaceDescPtr->ship_info.crew_level)
					StarShipPtr->RaceDescPtr->ship_info.crew_level =
							StarShipPtr->RaceDescPtr->ship_info.max_crew;
				else
					StarShipPtr->RaceDescPtr->ship_info.crew_level +=
							crew_retrieved;
			}

			if (StarShipPtr->RaceDescPtr->uninit_func != NULL)
				(*StarShipPtr->RaceDescPtr->uninit_func) (
						StarShipPtr->RaceDescPtr);
			StarShipPtr->ShipFacing =
					StarShipPtr->RaceDescPtr->ship_info.var2;
			StarShipPtr->special_counter =
					StarShipPtr->RaceDescPtr->ship_info.crew_level;
			SPtr[WHICH_SIDE (ElementPtr->state_flags)] = StarShipPtr;
			free_ship (StarShipPtr, TRUE);
		}
		UnlockElement (hElement);
	}

	GLOBAL (CurrentActivity) &= ~IN_BATTLE;

	if (LOBYTE (GLOBAL (CurrentActivity)) == IN_LAST_BATTLE)
	{
	}
	else if (LOBYTE (GLOBAL (CurrentActivity)) <= IN_ENCOUNTER
			&& !(GLOBAL (CurrentActivity) & CHECK_ABORT))
	{
		for (i = NUM_PLAYERS - 1; i >= 0; --i)
		{
			if (SPtr[i])
				GetEncounterStarShip (SPtr[i], i);
		}
	}

	if (LOBYTE (GLOBAL (CurrentActivity)) != IN_ENCOUNTER)
	{
		ReinitQueue (&race_q[0]);
		ReinitQueue (&race_q[1]);

		if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE)
			FreeHyperspace ();
	}
}
Пример #5
0
// This function is called when dead ship element's life_span reaches 0
void
new_ship (ELEMENT *DeadShipPtr)
{
	STARSHIP *DeadStarShipPtr;

	GetElementStarShip (DeadShipPtr, &DeadStarShipPtr);

	if (!readyForBattleEnd ())
	{
		DeadShipPtr->state_flags &= ~DISAPPEARING;
		++DeadShipPtr->life_span;

		// Keep the winner alive longer, or in a simultaneous destruction
		// tie, keep the other dead ship alive so that readyForBattleEnd()
		// is called for only one ship at a time.
		// When a ship has been destroyed, each side of a network
		// connection waits until the other side is ready.
		// When two ships die at the same time, this is handled for one
		// ship after the other.
		checkOtherShipLifeSpan (DeadShipPtr);
		return;
	}

	// Once a ship is being picked, we do not care about the winner anymore
	winnerStarShip = NULL;

	{
		BOOLEAN RestartMusic;

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

		SetElementStarShip (DeadShipPtr, 0);
		RestartMusic = OpponentAlive (DeadStarShipPtr);

		if (DeadStarShipPtr->RaceDescPtr->uninit_func != NULL)
			(*DeadStarShipPtr->RaceDescPtr->uninit_func) (
					DeadStarShipPtr->RaceDescPtr);
		free_ship (DeadStarShipPtr->RaceDescPtr, TRUE, TRUE);
		DeadStarShipPtr->RaceDescPtr = 0;
		
		// Graphics are batched while the draw queue is processed,
		// but we are going to draw the ship selection box now
		UnbatchGraphics ();

#ifdef NETPLAY
		initBattleStateDataConnections ();
		{
			bool allOk =
					negotiateReadyConnections (true, NetState_interBattle);
					// We are already in NetState_interBattle, but all
					// sides just need to pass this checkpoint before
					// going on.
			if (!allOk)
			{
				// Some network connection has been reset.
				GLOBAL (CurrentActivity) &= ~IN_BATTLE;
				BatchGraphics ();
				return;
			}
		}
#endif  /* NETPLAY */

		if (!FleetIsInfinite (DeadStarShipPtr->playerNr))
		{	// This may be a dead ship (crew_level == 0) or a warped out ship
			UpdateShipFragCrew (DeadStarShipPtr);
			// Deactivate the ship (cannot be selected)
			DeadStarShipPtr->SpeciesID = NO_ID;
		}

		if (GetNextStarShip (DeadStarShipPtr, DeadStarShipPtr->playerNr))
		{
#ifdef NETPLAY
			{
				bool allOk =
						negotiateReadyConnections (true, NetState_inBattle);
				if (!allOk)
				{
					// Some network connection has been reset.
					GLOBAL (CurrentActivity) &= ~IN_BATTLE;
					BatchGraphics ();
					return;
				}
			}
#endif
			if (RestartMusic)
				BattleSong (TRUE);
		}
		else if (battle_counter[0] == 0 || battle_counter[1] == 0)
		{
			// One player is out of ships. The battle is over.
			GLOBAL (CurrentActivity) &= ~IN_BATTLE;
		}
#ifdef NETPLAY
		else
		{
			// Battle has been aborted.
			GLOBAL (CurrentActivity) |= CHECK_ABORT;
		}
#endif
		BatchGraphics ();
	}
}