Exemplo n.º 1
0
void EnergyGaugeRenderer::render(S32 energy)
{
   // Create fade
   static const F32 colors[] = {
      Colors::blue.r, Colors::blue.g, Colors::blue.b, 1,   // Fade from
      Colors::blue.r, Colors::blue.g, Colors::blue.b, 1,
      Colors::cyan.r, Colors::cyan.g, Colors::cyan.b, 1,   // Fade to
      Colors::cyan.r, Colors::cyan.g, Colors::cyan.b, 1,
   };

   GaugeRenderer::render(energy, Ship::EnergyMax, colors, GaugeBottomMargin, GaugeHeight, Ship::EnergyCooldownThreshold);

#ifdef SHOW_SERVER_SITUATION
   ServerGame *serverGame = GameManager::getServerGame();

   if((serverGame && serverGame->getClientInfo(0)->getConnection()->getControlObject()))
   {
      S32 actDiff = static_cast<Ship *>(serverGame->getClientInfo(0)->getConnection()->getControlObject())->getEnergy();
      S32 p = F32(actDiff) / Ship::EnergyMax * GaugeWidth;
      glColor(Colors::magenta);
      drawVertLine(xul + p, yul - SafetyLineExtend - 1, yul + GaugeHeight + SafetyLineExtend);

      //Or, perhaps, just this:
      //renderGauge(energy, Ship::EnergyMax, Colors::blue, Colors::cyan, GaugeBottomMargin, GaugeHeight);
   }
#endif
}
Exemplo n.º 2
0
// Scenario 11 -- Player is editing loadout when level changes --> TEST NOT COMPLETE!!!!
static void doScenario11(GamePair &gamePair)
{
   ClientGame *clientGame = gamePair.getClient(0);
   ServerGame *serverGame = gamePair.server;
   serverGame->setGameTime(.5);     // 30 seconds

   GameUserInterface *gameUI = clientGame->getUIManager()->getUI<GameUserInterface>();
   ASSERT_FALSE(gameUI->isHelperActive(HelperMenu::LoadoutHelperType));

   gameUI->activateHelper(HelperMenu::LoadoutHelperType);
   ASSERT_TRUE(gameUI->isHelperActive(HelperMenu::LoadoutHelperType));
   ASSERT_EQ("", serverGame->getClientInfo(0)->getOnDeckLoadout().toString(true));   // Prove there's no on deck loadout

   // See static const OverlayMenuItem loadoutModuleMenuItems[] in loadoutHelper.cpp
   // Feed the UI some keys... like we're configuring a loadout!  
   gameUI->onKeyDown(KEY_1);     gameUI->onKeyDown(KEY_3);                                // First 2 modules...
   gameUI->onKeyDown(KEY_1);     gameUI->onKeyDown(KEY_2);     gameUI->onKeyDown(KEY_3);  // ...then 3 weapons
   ASSERT_FALSE(gameUI->isHelperActive(HelperMenu::LoadoutHelperType));

   gamePair.idle(10, 10);
   // Check the on deck loadout on server -- does not get set on the client
   ASSERT_EQ("Turbo,Repair,Phaser,Bouncer,Triple", serverGame->getClientInfo(0)->getOnDeckLoadout().toString(true));

   gameUI->activateHelper(HelperMenu::LoadoutHelperType);
   ASSERT_TRUE(gameUI->isHelperActive(HelperMenu::LoadoutHelperType));
   gamePair.idle(100, 350);        // Idle until game ends

   gameUI->onKeyDown(KEY_1);     gameUI->onKeyDown(KEY_4);
   gameUI->onKeyDown(KEY_1);     gameUI->onKeyDown(KEY_2);     gameUI->onKeyDown(KEY_3);

   ASSERT_FALSE(gameUI->isHelperActive(HelperMenu::LoadoutHelperType));

   gamePair.idle(10, 10);   
   ASSERT_EQ("Turbo,Sensor,Phaser,Bouncer,Triple", serverGame->getClientInfo(0)->getOnDeckLoadout().toString(true));
}
Exemplo n.º 3
0
// Scenario 1: Player is idle and gets suspended -- no other players in game
static void doScenario1(GamePair &gamePair)
{
   ClientGame *clientGame = gamePair.getClient(0);
   ServerGame *serverGame = gamePair.server;

   // Idle for a while -- ship should become spawn delayed.  GameConnection::SPAWN_DELAY_TIME is measured in ms.
   gamePair.idle(10, GameConnection::SPAWN_DELAY_TIME / 10);

   ASSERT_TRUE(serverGame->getClientInfo(0)->isPlayerInactive());    // No input from player, should be flagged as inactive
   // Note that spawn delay does not get set until the delayed ship tries to spawn, even if player is marked as inactive

   // Kill the ship again -- should be delayed when it tries to respawn because client has been inactive
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   EXPECT_EQ(1, fillVector.size());    // Should only be one ship

   Ship *ship = static_cast<Ship *>(fillVector[0]);      // Server's copy of the ship

   killShip(ship);

   gamePair.idle(10, GameType::RespawnDelay / 10 + 5);
   // Since server has received no input from client for GameConnection::SPAWN_DELAY_TIME ms, and ship has attempted to respawn, should be spawn-delayed
   ASSERT_TRUE(serverGame->getClientInfo(0)->isSpawnDelayed());
   ASSERT_TRUE(clientGame->isSpawnDelayed());      // Status should have propagated to client by now

   // At this point, client and server are both aware that the spawn is delayed due to player inactivity

   gamePair.idle(10, 10);              // Idle 10x
   // If spawn were not delayed, ship would have respawned.  Check for it on the server.
   // (Dead ship may linger on client while exploding, so we won't check there.)
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(0, fillVector.size());                   // Ship is spawn delayed and won't spawn... hence no ships
   ASSERT_EQ(0, serverGame->getClientInfo(0)->getReturnToGameTime());      // No returnToGamePenalty in this scenario
   ASSERT_EQ(0, clientGame->getReturnToGameDelay());
   ASSERT_FALSE(static_cast<FullClientInfo *>(serverGame->getClientInfo(0))->hasReturnToGamePenalty());   // No penalty in the works

   // Undelay spawn
   clientGame->undelaySpawn();         // This is what gets run when player presses a key
   gamePair.idle(10, 5);               // Idle 5x; give things time to propagate

   ASSERT_FALSE(serverGame->getClientInfo(0)->isSpawnDelayed());     // Player should no longer be spawn delayed
   ASSERT_FALSE(clientGame->inReturnToGameCountdown());
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());    // Ship should have spawned and be available on client and server
   fillVector.clear();
   clientGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());    // Ship should have spawned and be available on client and server
}
Exemplo n.º 4
0
/**
 * @luafunc table Team::getPlayers()
 *
 * @brief Get a table containing all players on a team.
 *
 * @code
 *   local players = team:getPlayers()
 *   for i, v in ipairs(players) do
 *     print(v:getName())
 *   end
 * @endcode
 *
 * @return A table of \link LuaPlayerInfo LuaPlayerInfos \endlink currently on this
 * team. 
 */
S32 Team::lua_getPlayers(lua_State *L)
{
   ServerGame *game = GameManager::getServerGame();

   TNLAssert(game->getPlayerCount() == game->getClientCount(), "Mismatched player counts!");

   S32 pushed = 0;

   lua_newtable(L);    // Create a table, with no slots pre-allocated for our data

   for(S32 i = 0; i < game->getClientCount(); i++)
   {
      ClientInfo *clientInfo = game->getClientInfo(i);

      if(clientInfo->getTeamIndex() == mTeamIndex)
      {
         clientInfo->getPlayerInfo()->push(L);
         pushed++;      // Increment pushed before using it because Lua uses 1-based arrays
         lua_rawseti(L, 1, pushed);
      }
   }

   for(S32 i = 0; i < game->getRobotCount(); i ++)
   {
      if(game->getBot(i)->getTeam() == mTeamIndex)
      {
         game->getBot(i)->getPlayerInfo()->push(L);
         pushed++;      // Increment pushed before using it because Lua uses 1-based arrays
         lua_rawseti(L, 1, pushed);
      }
   }

   return 1;
}
Exemplo n.º 5
0
/**
 * @luafunc table LuaGameInfo::getPlayers()
 *
 * @brief Get a list of the players in the game.
 *
 * @return A table containing the LuaPlayerInfo for each player (and robot) in
 * the game
 */
S32 LuaGameInfo::lua_getPlayers(lua_State *L) 
{
   ServerGame *game = mServerGame;

   S32 pushed = 0;     // Count of pushed objects

   lua_newtable(L);    // Create a table, with no slots pre-allocated for our data

   for(S32 i = 0; i < game->getClientCount(); i++)
   {
      ClientInfo *clientInfo = game->getClientInfo(i);

      if(clientInfo->getPlayerInfo() == NULL || clientInfo->isRobot())     // Skip defunct players and bots
         continue;
      
      clientInfo->getPlayerInfo()->push(L);
      pushed++;      // Increment pushed before using it because Lua uses 1-based arrays
      lua_rawseti(L, 1, pushed);
   }

   for(S32 i = 0; i < game->getRobotCount(); i ++)
   {
      game->getBot(i)->getPlayerInfo()->push(L);
      pushed++;      // Increment pushed before using it because Lua uses 1-based arrays
      lua_rawseti(L, 1, pushed);
   }

   return 1;
}
Exemplo n.º 6
0
void GamePair::addBotClientAndSetTeam(const string &name, S32 teamIndex)
{
   ServerGame *server = GameManager::getServerGame();

   server->addBot(Vector<string>(), ClientInfo::ClassRobotAddedByAutoleveler);
   // Get most recently added clientInfo
   ClientInfo *clientInfo = server->getClientInfo(server->getClientInfos()->size() - 1);
   ASSERT_TRUE(clientInfo->isRobot()) << "This is supposed to be a robot!";

   // Normally, in a game, a ship or bot would be destroyed and would respawn when their team changes, and upon
   // respawning the BfObject representing that ship would be on the correct team.  Not so here (where we are
   // taking lots of shortcuts); here we need to manually assign a new team to the robot object in addition to
   // it's more "official" setting on the ClientInfo.
   clientInfo->setTeamIndex(teamIndex);
   clientInfo->getShip()->setTeam(teamIndex);
}
Exemplo n.º 7
0
TEST(GameUserInterfaceTest, Engineer)
{
   InputCodeManager::initializeKeyNames();  

   GamePair gamePair(getLevelCodeForTestingEngineer1(), 3); // See def for description of level
   ServerGame *serverGame                  = GameManager::getServerGame();
   const Vector<ClientGame *> *clientGames = GameManager::getClientGames();
   GameSettings *clientSettings            = clientGames->first()->getSettings();
   GameUserInterface *gameUI               = clientGames->first()->getUIManager()->getUI<GameUserInterface>();

   DEFINE_KEYS_AND_EVENTS(clientSettings);

   // Idle for a while, let things settle
   GamePair::idle(10, 5);

   // Verify that engineer is enabled
   ASSERT_TRUE(serverGame->getGameType()->isEngineerEnabled()) << "Engineer should be enabled on server!";

   for(S32 i = 0; i < clientGames->size(); i++)
   {
      SCOPED_TRACE("i = " + itos(i));
      ASSERT_TRUE(clientGames->get(i)->getGameType())                      << "Clients should have a GameType by now!";
      ASSERT_TRUE(clientGames->get(i)->getGameType()->isEngineerEnabled()) << "Engineer mode not propagating to clients!";
   }

   ASSERT_TRUE(serverGame->getClientInfo(0)->getShip()->isInZone(LoadoutZoneTypeNumber)); // Check level is as we expected

   // Add engineer to current loadout
   ASSERT_FALSE(gameUI->isHelperActive(HelperMenu::LoadoutHelperType));
   gameUI->activateHelper(HelperMenu::LoadoutHelperType);
   ASSERT_TRUE(gameUI->isHelperActive(HelperMenu::LoadoutHelperType));

   gameUI->onKeyDown(LOADOUT_KEY_ENGR);      gameUI->onKeyDown(LOADOUT_KEY_REPAIR);                                           // First 2 modules...
   gameUI->onKeyDown(LOADOUT_KEY_PHASER);    gameUI->onKeyDown(LOADOUT_KEY_BOUNCE);    gameUI->onKeyDown(LOADOUT_KEY_TRIPLE); // ...then 3 weapons

   // On this level, the ship spawn is inside a loadout zone, so loadout should take effect immediately
   GamePair::idle(10, 5);
   ASSERT_EQ("Engineer,Repair,Phaser,Bouncer,Triple", serverGame->getClientInfo(0)->getShip()->getLoadoutString());
   for(S32 i = 0; i < clientGames->size(); i++)
   {
      SCOPED_TRACE("i = " + itos(i));
      ASSERT_EQ("Engineer,Repair,Phaser,Bouncer,Triple", clientGames->get(0)->getLocalPlayerShip()->getLoadoutString());
   }

   // Fly down to pick up resource item -- to get flying to work, need to create events at a very basic level
   ClientGame *clientGame = clientGames->get(0);
   Point startPos = clientGame->getLocalPlayerShip()->getActualPos();
   Event::onEvent(clientGame, &EventDownPressed);
   GamePair::idle(100, 5);
   Event::onEvent(clientGame, &EventDownReleased);
   Point endPos = clientGame->getLocalPlayerShip()->getActualPos();
   ASSERT_TRUE(startPos.distSquared(endPos) > 0) << "Ship did not move!!";
   for(S32 i = 0; i < clientGames->size(); i++)
   {
      SCOPED_TRACE("i = " + itos(i));
      ASSERT_TRUE(clientGames->get(0)->getLocalPlayerShip()->isCarryingItem(ResourceItemTypeNumber));
   }

   // Time to engineer!
   gameUI->onKeyDown(KEY_MOD1);
   ASSERT_TRUE(gameUI->isHelperActive(HelperMenu::EngineerHelperType)) << "Expect engineer helper menu to be active!";

   InputCode key = EngineerHelper::getInputCodeForOption(EngineeredTeleporterEntrance, true);
   gameUI->onKeyDown(key);
   ASSERT_FALSE(static_cast<const EngineerHelper *>(gameUI->getActiveHelper())->isMenuBeingDisplayed());
   gameUI->onKeyDown(KEY_MOD1);     // Place entrance
   gameUI->onKeyDown(KEY_MOD1);     // Place exit
   GamePair::idle(100, 5);           // Let things mellow

   for(S32 i = 0; i < clientGames->size(); i++)
   {
      SCOPED_TRACE("i = " + itos(i));
      Vector<DatabaseObject *> fillVector;
      clientGames->get(i)->getLevel()->findObjects(TeleporterTypeNumber, fillVector);
      EXPECT_EQ(1, fillVector.size()) << "Expected a teleporter!";
   }
}
Exemplo n.º 8
0
// Scenario 2: Player enters idle command, other players, so server does not suspend itself.  Since
// player used idle command, a 5 second penalty will be levied against them.
static void doScenario2(GamePair &gamePair)
{
   ServerGame *serverGame = gamePair.server;

   string player1Name = "TestPlayer0";
   ASSERT_EQ(1, gamePair.getClientCount());                          // Should have had a client here when we arrived
   ASSERT_EQ(player1Name, gamePair.getClient(0)->getPlayerName());   // With this name

   string player2Name = "TestUser2";
   gamePair.addClientAndSetTeam(player2Name.c_str(), 0);

   ClientGame *client1 = gamePair.getClient(0);
   ClientGame *client2 = gamePair.getClient(1);

   // Make sure the names are what we think they are... can't move on unless they are
   ASSERT_EQ(player1Name, client1->getPlayerName());
   ASSERT_EQ(player2Name, client2->getPlayerName());

   // Should now be 2 ships in the game -- one belonging to client1 and another belonging to client2
   gamePair.idle(10, 5);               // Idle 5x; give things time to propagate
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(2, fillVector.size());                  
   fillVector.clear();
   client1->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(2, fillVector.size());
   fillVector.clear();
   client2->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(2, fillVector.size());

   Vector<string> words;
   ChatCommands::idleHandler(client1, words);         // Make client 1 go /idle
   gamePair.idle(Ship::KillDeleteDelay / 15, 30);     // Give things time to propagate, timers to time out, etc.

   ASSERT_TRUE(serverGame->getClientInfo(0)->isSpawnDelayed());
   ASSERT_TRUE(client1->isSpawnDelayed());            // Status should have propagated to client by now
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());                   // Ship should have been killed off -- only 2nd player ship should be left
   fillVector.clear();
   client1->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(0, fillVector.size());                   // Suspended players don't see remote objects
   fillVector.clear();
   client2->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   //ASSERT_EQ(1, fillVector.size());                   // Player 2 should see self

   ASSERT_TRUE(client2->findClientInfo(client1->getPlayerName())->isSpawnDelayed());    // Check that other player knows our status

   // ReturnToGame penalty has been set, but won't start to count down until ship attempts to spawn
   ASSERT_FALSE(client1->inReturnToGameCountdown());
   ASSERT_TRUE(static_cast<FullClientInfo *>(serverGame->getClientInfo(0))->hasReturnToGamePenalty()); // Penalty has been primed
   ASSERT_EQ(0, serverGame->getClientInfo(0)->getReturnToGameTime());

   // Player presses a key to rejoin the game; there should be a SPAWN_UNDELAY_TIMER_DELAY ms penalty incurred for using /idle
   ASSERT_FALSE(serverGame->isSuspended()) << "Game is suspended -- subsequent tests will fail";
   client1->undelaySpawn();                                                // Simulate effects of key press
   gamePair.idle(10, 10);                                                  // Idle; give things time to propagate
   ASSERT_TRUE(serverGame->getClientInfo(0)->getReturnToGameTime() > 0);   // Timers should be set and counting down
   ASSERT_TRUE(client1->inReturnToGameCountdown());

   // Check to ensure ship didn't spawn -- spawn should be delayed until penalty period has expired
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());   // (one ship for client2) 

   // Client 1 won't see spawning ship while he is suspended
   fillVector.clear();
   client1->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(0, fillVector.size());

   // Client 2 should see that client 1 has been delayed
   ASSERT_TRUE(client2->findClientInfo(player1Name.c_str())->isSpawnDelayed());

   // After some time has passed -- no longer in returnToGameCountdown period, ship should have appeared on server and client
   gamePair.idle(ClientInfo::SPAWN_UNDELAY_TIMER_DELAY / 100, 105);  // More time than SPAWN_UNDELAY_TIMER_DELAY
   ASSERT_FALSE(client1->inReturnToGameCountdown());
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(2, fillVector.size());    
   fillVector.clear();
   client1->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(2, fillVector.size());

   gamePair.removeClient(1);
}
Exemplo n.º 9
0
// Scenario 3, 4 -- Player enters /idle command, no other players, so server suspends itself
// In this case, no returnToGame penalty should be levied
// In this scenario 3, player un-idles during the suspend game timer countdown (there is a 2 second delay after all players are idle)
// In scenario 4, player enters full suspend mode before unidling
static void doScenario34(GamePair &gamePair, bool letGameSlipIntoFullSuspendMode)
{
   ClientGame *clientGame = gamePair.getClient(0);
   ServerGame *serverGame = gamePair.server;

   // Make sure we start off in a "normal" state
   ASSERT_FALSE(serverGame->isOrIsAboutToBeSuspended());
   ASSERT_FALSE(clientGame->isSpawnDelayed());         

   gamePair.idle(Ship::KillDeleteDelay / 15, 20);     // Idle; give things time to propagate
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());                   // Now that player 2 has left, should only be one ship
   fillVector.clear();
   clientGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());

   Vector<string> words;
   ChatCommands::idleHandler(clientGame, words);
   gamePair.idle(10, 10);     // Idle; give things time to propagate, timers to time out, etc.
   ASSERT_TRUE(serverGame->getClientInfo(0)->isSpawnDelayed());
   ASSERT_TRUE(serverGame->isOrIsAboutToBeSuspended());
   EXPECT_FALSE(serverGame->isSuspended());
   ASSERT_TRUE(clientGame->isSpawnDelayed());         // Status should have propagated to client by now
   EXPECT_FALSE(clientGame->isSuspended());

   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(0, fillVector.size());                   // No ships remaining in game -- don't check client as it may have exploding ship there
   fillVector.clear();

   // ReturnToGame penalty has been set, but won't start to count down until ship attempts to spawn
   ASSERT_FALSE(clientGame->inReturnToGameCountdown());
   ASSERT_TRUE(static_cast<FullClientInfo *>(serverGame->getClientInfo(0))->hasReturnToGamePenalty()); // Penalty has been primed
   ASSERT_EQ(0, serverGame->getClientInfo(0)->getReturnToGameTime());

   if(letGameSlipIntoFullSuspendMode)
		gamePair.idle(ServerGame::PreSuspendSettlingPeriod / 20, 25);

   // Player presses a key to rejoin the game; since game was suspended, player can resume without penalty
   ASSERT_TRUE(serverGame->isOrIsAboutToBeSuspended()) << "Game should be suspended";

   if(letGameSlipIntoFullSuspendMode)
   {
      // In here, game is suspended

      EXPECT_TRUE(serverGame->isSuspended());
      EXPECT_TRUE(clientGame->isSuspended());

      // Check if server clocks are still counting down... should be stopped
      S32 snow = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 cnow = clientGame->getGameType()->getRemainingGameTimeInMs();
      gamePair.idle(10, 10);
      S32 slater = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 clater = clientGame->getGameType()->getRemainingGameTimeInMs();
      EXPECT_EQ(snow, slater) << "Looks like server clock is still running (should be stopped)!";
      EXPECT_EQ(cnow, clater) << "Looks like client clock is still running (should be stopped)!";
   }
   else
   {
      // In here, game is not (yet) suspended, but is in the 2 second cooldown period that comes after 
      // all players have left or are idle, but before full suspension

      EXPECT_FALSE(serverGame->isSuspended());
      EXPECT_FALSE(clientGame->isSuspended());

      // Check if clocks are still counting down... should be still running
      S32 snow = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 cnow = clientGame->getGameType()->getRemainingGameTimeInMs();
      gamePair.idle(10, 10);
      S32 slater = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 clater = clientGame->getGameType()->getRemainingGameTimeInMs();
      EXPECT_NE(snow, slater) << "Looks like server clock is stopped (should be running)!";
      EXPECT_NE(cnow, clater) << "Looks like client clock is stopped (should be running)!";
   }

   clientGame->undelaySpawn();                                          // Simulate effects of key press
   gamePair.idle(10, 5);                                                // Idle; give things time to propagate
   ASSERT_FALSE(serverGame->isOrIsAboutToBeSuspended());

   ASSERT_EQ(0, serverGame->getClientInfo(0)->getReturnToGameTime());   // No returnToGame penalty
   ASSERT_FALSE(clientGame->inReturnToGameCountdown());

   gamePair.idle(Ship::KillDeleteDelay / 15, 20);     // Idle; give dead ships time to be cleaned up

   // Check to ensure ship spawned
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());   
   fillVector.clear();
   clientGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());

   ASSERT_FALSE(serverGame->isOrIsAboutToBeSuspended());
   ASSERT_FALSE(clientGame->isSpawnDelayed());         
}