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 (); } }
// 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 (); } }