/** * @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; }
// Makes sure that the mTeams[] structure has the proper player counts // Needs to be called manually before accessing the structure // Bot counts do work on client. Yay! // Rating may only work on server... not tested on client void Game::countTeamPlayers() const { for(S32 i = 0; i < getTeamCount(); i++) { TNLAssert(dynamic_cast<Team *>(getTeam(i)), "Invalid team"); // Assert for safety static_cast<Team *>(getTeam(i))->clearStats(); // static_cast for speed } for(S32 i = 0; i < getClientCount(); i++) { ClientInfo *clientInfo = getClientInfo(i); S32 teamIndex = clientInfo->getTeamIndex(); if(teamIndex >= 0 && teamIndex < getTeamCount()) { // Robot could be neutral or hostile, skip out-of-range team numbers TNLAssert(dynamic_cast<Team *>(getTeam(teamIndex)), "Invalid team"); Team *team = static_cast<Team *>(getTeam(teamIndex)); if(clientInfo->isRobot()) team->incrementBotCount(); else team->incrementPlayerCount(); // The following bit won't work on the client... if(isServer()) { const F32 BASE_RATING = .1f; team->addRating(max(clientInfo->getCalculatedRating(), BASE_RATING)); } } } }
// By rebuilding everything every tick, menus can be dynamically updated void PlayerMenuUserInterface::idle(U32 timeDelta) { clearMenuItems(); GameConnection *conn = getGame()->getConnectionToServer(); if(!conn) return; char c[] = "A"; // Dummy shortcut key for(S32 i = 0; i < getGame()->getClientCount(); i++) { ClientInfo *clientInfo = ((Game *)getGame())->getClientInfo(i); // Lame! strncpy(c, clientInfo->getName().getString(), 1); // Grab first char of name for a shortcut key // Will be used to show admin/player/robot prefix on menu PlayerType pt = clientInfo->isRobot() ? PlayerTypeRobot : (clientInfo->isAdmin() ? PlayerTypeAdmin : PlayerTypePlayer); PlayerMenuItem *newItem = new PlayerMenuItem(i, clientInfo->getName().getString(), playerSelectedCallback, InputCodeManager::stringToInputCode(c), pt); newItem->setUnselectedColor(getGame()->getTeamColor(clientInfo->getTeamIndex())); addMenuItem(newItem); } sortMenuItems(); if(action == PlayerActionKick) mMenuTitle = "CHOOSE PLAYER TO KICK"; else if(action == PlayerActionChangeTeam) mMenuTitle = "CHOOSE WHOSE TEAM TO CHANGE"; else TNLAssert(false, "Unknown action!"); }
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); }
// teamIndex is optional ClientGame *GamePair::addClient(ClientGame *clientGame) { ServerGame *server = GameManager::getServerGame(); clientGame->joinLocalGame(server->getNetInterface()); // Client will have owner privs! // We need to turn off TNL's bandwidth controls so our tests can run faster. FASTER!!@! clientGame->getConnectionToServer()->useZeroLatencyForTesting(); ClientInfo *clientInfo = server->findClientInfo(clientGame->getClientInfo()->getName().getString()); if(!clientInfo->isRobot()) clientInfo->getConnection()->useZeroLatencyForTesting(); return clientGame; }