diff --git a/dlls/bot/bot.cpp b/dlls/bot/bot.cpp index 90f0ddd2..c6e363b8 100644 --- a/dlls/bot/bot.cpp +++ b/dlls/bot/bot.cpp @@ -251,7 +251,7 @@ void BotCreate(const char *skin, const char *name, const char *skill) for (j = i; j < length; j++) // shuffle chars left (and null) c_name[j] = c_name[j+1]; length--; - } + } } skill_level = 0; @@ -294,6 +294,7 @@ void BotCreate(const char *skin, const char *name, const char *skill) sprintf(c_index, "%d", index); bot_respawn[index].is_used = TRUE; // this slot is used + bot_respawn[index].state = BOT_IS_RESPAWNING; // don't store the name here, it might change if same as another strcpy(bot_respawn[index].skin, c_skin); @@ -337,7 +338,8 @@ void CBot::Spawn( ) // get the bot's name and save it in respawn array... strcpy(bot_respawn[respawn_index].name, STRING(pev->netname)); - bot_respawn[respawn_index].state = BOT_IDLE; + bot_respawn[respawn_index].is_used = TRUE; + bot_respawn[respawn_index].state = BOT_IS_RESPAWNING; pev->ideal_yaw = pev->v_angle.y; pev->yaw_speed = BOT_YAW_SPEED; @@ -577,7 +579,7 @@ float CBot::BotChangeYaw( float speed ) // turn from the current v_angle yaw to the ideal_yaw by selecting // the quickest way to turn to face that direction - + current = pev->v_angle.y; ideal = pev->ideal_yaw; @@ -1767,8 +1769,6 @@ void CBot::BotThink( void ) pev->health = 0; pev->deadflag = DEAD_DEAD; // make the kicked bot be dead - bot_respawn[respawn_index].is_used = FALSE; // this slot is now free - bot_respawn[respawn_index].state = BOT_IDLE; respawn_index = -1; // indicate no slot used // fall through to next if statement (respawn_index will be -1) @@ -1985,7 +1985,7 @@ void CBot::BotThink( void ) { // if there was a wall on the left over 1/2 a second ago then // 20% of the time randomly turn between 45 and 60 degrees - + if ((f_wall_on_left != 0) && (f_wall_on_left <= gpGlobals->time - 0.5) && (RANDOM_LONG(1, 100) <= 20)) @@ -2045,7 +2045,7 @@ void CBot::BotThink( void ) else if ((moved_distance <= 1) && (!bot_was_paused)) { // the bot must be stuck! - + if (BotCanJumpUp( )) // can the bot jump onto something? { pev->button |= IN_JUMP; // jump up and move forward @@ -2106,4 +2106,3 @@ void CBot::BotThink( void ) gpGlobals->frametime * 1000 ); // TheFatal - END } - diff --git a/dlls/client.cpp b/dlls/client.cpp index a0ed09f2..d984faef 100644 --- a/dlls/client.cpp +++ b/dlls/client.cpp @@ -123,9 +123,11 @@ BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddres sprintf( cmd, "kick \"%s\"\n", bot_respawn[i].name ); - bot_respawn[i].state = BOT_IDLE; - SERVER_COMMAND( cmd ); // kick the bot using (kick "name") + + bot_respawn[i].is_used = FALSE; + bot_respawn[i].state = BOT_NEED_TO_RESPAWN; + break; } } @@ -997,6 +999,7 @@ void StartFrame( void ) static float respawn_time = 0; static float previous_time = 0.0; char msg[120]; + int online = 0; // END BOT // START BOT - thanks Jehannum! @@ -1009,6 +1012,9 @@ void StartFrame( void ) if( !pPlayer ) // if invalid then continue with next index... continue; + if( pPlayer->pev->takedamage == DAMAGE_NO ) + continue; // solution to detect player not in the game + // check if this is a FAKECLIENT (i.e. is it a bot?) if( FBitSet( pPlayer->pev->flags, FL_FAKECLIENT ) ) { @@ -1017,16 +1023,20 @@ void StartFrame( void ) // call the think function for the bot... pBot->BotThink(); } + + // increase online of bots and players + online++; } // END BOT // START BOT + + // check if any players are using the botcam... if( ( g_fGameOver ) && ( respawn_time < 1.0 ) ) { // if the game is over (time/frag limit) set the respawn time... respawn_time = 5.0; - // check if any players are using the botcam... for( i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); @@ -1042,54 +1052,21 @@ void StartFrame( void ) // check if a map was changed via "map" without kicking bots... if( previous_time > gpGlobals->time ) { + respawn_time = 5.0; + bot_check_time = gpGlobals->time + 10.0; - for( index = 0; index < 32; index++ ) + // find bots used in previous session and add them to respawn queue + for( i = 0; i < 32; i++ ) { - if( ( bot_respawn[index].is_used) && // is this slot used? - ( bot_respawn[index].state != BOT_NEED_TO_RESPAWN ) ) + if( bot_respawn[i].is_used ) { - // bot has already been "kicked" by server so just set flag - bot_respawn[index].state = BOT_NEED_TO_RESPAWN; - - // if the map was changed set the respawn time... - respawn_time = 5.0; + bot_respawn[i].is_used = FALSE; + bot_respawn[i].state = BOT_NEED_TO_RESPAWN; } } } - // is new game started and time to respawn bots yet? - if( ( !g_fGameOver ) && ( respawn_time > 1.0 ) && - ( gpGlobals->time >= respawn_time ) ) - { - int index = 0; - bot_check_time = gpGlobals->time + 5.0; - - // find bot needing to be respawned... - while( ( index < 32 ) && - ( bot_respawn[index].state != BOT_NEED_TO_RESPAWN ) ) - index++; - - if( index < 32 ) - { - bot_respawn[index].state = BOT_IS_RESPAWNING; - bot_respawn[index].is_used = FALSE; // free up this slot - - // respawn 1 bot then wait a while (otherwise engine crashes) - BotCreate( bot_respawn[index].skin, - bot_respawn[index].name, - bot_respawn[index].skill ); - - respawn_time = gpGlobals->time + 1.0; // set next respawn time - } - else - { - respawn_time = 0.0; - } - } - // END BOT - //ALERT( at_console, "SV_Physics( %g, frametime %g )\n", gpGlobals->time, gpGlobals->frametime ); - if( g_pGameRules ) { g_pGameRules->Think(); @@ -1189,6 +1166,9 @@ void StartFrame( void ) { BotCreate( arg1, arg2, arg3 ); + // increase online of bots and players + online++; + // have to delay here or engine gives "Tried to write to // uninitialized sizebuf_t" error and crashes... pause_time = gpGlobals->time + 1; @@ -1306,6 +1286,9 @@ void StartFrame( void ) printf( "adding new bot...\n" ); BotCreate( arg1, arg2, arg3 ); + + // increase online of bots and players + online++; } else if( strcmp( cmd, "botskill" ) == 0 ) { @@ -1344,38 +1327,23 @@ void StartFrame( void ) // START BOT // check if time to see if a bot needs to be created... - if( bot_check_time < gpGlobals->time ) + if( online < max_bots && bot_check_time < gpGlobals->time && respawn_time <= gpGlobals->time ) { - int count = 0; - - bot_check_time = gpGlobals->time + 5.0; - - for( i = 1; i <= gpGlobals->maxClients; i++ ) + for( i = 0; i < 32; i++ ) { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - if( !pPlayer ) - continue; // if invalid then continue with next index... - - if( pPlayer->pev->takedamage == DAMAGE_NO ) - continue; // if bot was kicked, don't count as a player... - - count++; // count the number of bots and players - } - - // if there are currently less than the maximum number of "players" - // then add another bot using the default skill level... - if( count < max_bots ) - { - for( i = 0; i < 32; i++ ) + if( !bot_respawn[i].is_used && bot_respawn[i].state == BOT_NEED_TO_RESPAWN ) { - if( !bot_respawn[i].is_used && bot_respawn[i].state == BOT_IDLE) - { - BotCreate( bot_respawn[i].skin, bot_respawn[i].name, bot_respawn[i].skill ); - break; - } + BotCreate( bot_respawn[i].skin, bot_respawn[i].name, bot_respawn[i].skill ); + + online++; // increase online of bots and players + + respawn_time = gpGlobals->time + 1.0; // set next respawn time (to prevent server crash) + + break; } } + + bot_check_time = gpGlobals->time + 10.0; } previous_time = gpGlobals->time; // keep track of last time in StartFrame()