/* ============== BotAIShutdown ============== */ int BotAIShutdown( int restart ) { int i; //if the game is restarted for a tournament if ( restart ) { //shutdown all the bots in the botlib for (i = 0; i < level.maxplayers; i++) { if (botstates[i] && botstates[i]->inuse) { BotAIShutdownPlayer(botstates[i]->playernum, restart); } } //don't shutdown the bot library } else { trap_BotLibShutdown(); } // BotShutdownCharacters(); //ai_char.c BotShutdownMoveAI(); //ai_move.c BotShutdownGoalAI(); //ai_goal.c BotShutdownWeaponAI(); //ai_weap.c BotShutdownWeights(); //ai_weight.c BotShutdownChatAI(); //ai_chat_sys.c //shut down bot elemantary actions EA_Shutdown(); return qtrue; }
/* ============== BotInterbreeding ============== */ void BotInterbreeding(void) { int i; trap_Cvar_Update(&bot_interbreedchar); if (!strlen(bot_interbreedchar.string)) return; //make sure we are in tournament mode if (gametype != GT_TOURNAMENT) { trap_Cvar_SetValue("g_gametype", GT_TOURNAMENT); ExitLevel(); return; } //shutdown all the bots for (i = 0; i < MAX_CLIENTS; i++) { if (botstates[i] && botstates[i]->inuse) { BotAIShutdownPlayer(botstates[i]->playernum, qfalse); } } //make sure all item weight configs are reloaded and Not shared trap_Cvar_SetValue("bot_reloadcharacters", 1); //add a number of bots using the desired bot character for (i = 0; i < bot_interbreedbots.integer; i++) { trap_Cmd_ExecuteText( EXEC_INSERT, va("addbot %s 4 free %i %s%d\n", bot_interbreedchar.string, i * 50, bot_interbreedchar.string, i) ); } // trap_Cvar_Set("bot_interbreedchar", ""); bot_interbreed = qtrue; }
/* =========== PlayerDisconnect Called when a player drops from the server. Will not be called between levels. This should NOT be called directly by any game logic, call trap_DropPlayer(), which will call this and do server system housekeeping. ============ */ void PlayerDisconnect( int playerNum ) { gentity_t *ent; gentity_t *tent; int i; // cleanup if we are kicking a bot that // hasn't spawned yet G_RemoveQueuedBotBegin( playerNum ); ent = g_entities + playerNum; if (!ent->player || ent->player->pers.connected == CON_DISCONNECTED) { return; } // stop any following players for ( i = 0 ; i < level.maxplayers ; i++ ) { if ( level.players[i].sess.sessionTeam == TEAM_SPECTATOR && level.players[i].sess.spectatorState == SPECTATOR_FOLLOW && level.players[i].sess.spectatorPlayer == playerNum ) { StopFollowing( &g_entities[i] ); } } // send effect if they were completely connected if ( ent->player->pers.connected == CON_CONNECTED && ent->player->sess.sessionTeam != TEAM_SPECTATOR ) { tent = G_TempEntity( ent->player->ps.origin, EV_PLAYER_TELEPORT_OUT ); tent->s.playerNum = ent->s.playerNum; // They don't get to take powerups with them! // Especially important for stuff like CTF flags TossPlayerItems( ent ); #ifdef MISSIONPACK TossPlayerPersistantPowerups( ent ); if( g_gametype.integer == GT_HARVESTER ) { TossPlayerCubes( ent ); } #endif } G_LogPrintf( "PlayerDisconnect: %i\n", playerNum ); // if we are playing in tourney mode and losing, give a win to the other player if ( (g_gametype.integer == GT_TOURNAMENT ) && !level.intermissiontime && !level.warmupTime && level.sortedPlayers[1] == playerNum ) { level.players[ level.sortedPlayers[0] ].sess.wins++; PlayerUserinfoChanged( level.sortedPlayers[0] ); } if( g_gametype.integer == GT_TOURNAMENT && ent->player->sess.sessionTeam == TEAM_FREE && level.intermissiontime ) { trap_Cmd_ExecuteText( EXEC_APPEND, "map_restart 0\n" ); level.restarted = qtrue; level.changemap = NULL; level.intermissiontime = 0; } trap_UnlinkEntity (ent); ent->s.modelindex = 0; ent->inuse = qfalse; ent->classname = "disconnected"; ent->player->pers.connected = CON_DISCONNECTED; ent->player->ps.persistant[PERS_TEAM] = TEAM_FREE; ent->player->sess.sessionTeam = TEAM_FREE; trap_SetConfigstring( CS_PLAYERS + playerNum, ""); CalculateRanks(); if ( ent->r.svFlags & SVF_BOT ) { BotAIShutdownPlayer( playerNum, qfalse ); } // clear player connection info level.connections[ent->player->pers.connectionNum].numLocalPlayers--; level.connections[ent->player->pers.connectionNum].localPlayerNums[ent->player->pers.localPlayerNum] = -1; ent->player->pers.localPlayerNum = ent->player->pers.connectionNum = -1; }