LOL
"the Principle of Uncertainty applied to CS bots"
anyway...
I HAVE FOUND THE PROBLEM!!!!!
My bots strafe almost exactly like humans now.
In fact this problem seems to appear only when a bot zigzags, not when it starts strafing for the first time. When their strafe speed has raised to its maximum, if the bots suddently change their strafe direction, the strafe speed is not decreased to zero then increased again. And actually this is somewhat normal: humans can't press the other strafe key that fast, there is at least 0.2 second between the instant where the first strafe key is released and the second one is pressed, because usually the forward/backwards keys and the strafe left/strafe right keys are opposite altogether relatively to your fingers on the keyboard. My fix only constituted in adding a check for the last strafe time in the function that makes the bots press the movement keys. Not only it fixes things, but it makes the bot's movement look REALLY realistic!!
8D
Code:
void BotMove (player_t *pPlayer)
{
// the purpose of this function is to translate the data of the BotMove structure (timings
// at which the bot has to perform some movement - jump in 2 seconds, move forward for 5
// seconds, and so on) into the right input buttons to be passed to RunPlayerMove(), which is
// the function that asks the engine to perform the movement of the fakeclient. It also sets
// the correct values for move_speed and strafe_speed which are parameters of RunPlayerMove().
TraceResult tr;
if (DebugLevel.legs_disabled)
return; // return if we don't want the AI to move
if (pPlayer->Bot.is_controlled)
return; // if bot is bewitched, it doesn't "steer itself"
// is the bot paused ?
if (pPlayer->Bot.f_pause_time > server.time)
{
pPlayer->Bot.BotMove.f_move_speed = 0;
pPlayer->Bot.BotMove.f_strafe_speed = 0;
if (pPlayer->Bot.BotMove.f_duck_time > server.time)
{
pPlayer->pEntity->v.button |= IN_DUCK; // maintain duck button when needed
pPlayer->Bot.BotMove.f_duck_time = server.time + 0.2; // keep ducking
}
return; // don't move the bot if it should be paused
}
// may the bot jump now ?
if ((pPlayer->Bot.BotMove.f_jump_time < server.time)
&& (pPlayer->Bot.BotMove.f_jump_time + 0.1 > server.time))
pPlayer->pEntity->v.button |= IN_JUMP; // jump
// has the bot just jumped AND is bot skilled enough ?
if ((pPlayer->Bot.BotMove.f_jump_time + 0.1 < server.time)
&& (pPlayer->Bot.BotMove.f_jump_time + 0.2 > server.time)
&& (pPlayer->Bot.pProfile->skill > 1))
pPlayer->Bot.BotMove.f_duck_time = server.time + 0.2; // duck while jumping
// may the bot duck now ?
if (pPlayer->Bot.BotMove.f_duck_time > server.time)
pPlayer->pEntity->v.button |= IN_DUCK; // duck
// may the bot safely strafe left now ?
if ((pPlayer->Bot.BotMove.f_strafeleft_time > server.time)
&& (pPlayer->Bot.BotMove.f_straferight_time + 0.2 < server.time)
&& !(pPlayer->Bot.BotBody.hit_state & OBSTACLE_LEFT_FALL))
{
pPlayer->pEntity->v.button |= IN_MOVELEFT;
pPlayer->Bot.BotMove.f_strafe_speed = -pPlayer->Bot.BotMove.f_max_speed; // strafe left
}
// else may the bot safely strafe right now ?
else if ((pPlayer->Bot.BotMove.f_straferight_time > server.time)
&& (pPlayer->Bot.BotMove.f_strafeleft_time + 0.2 < server.time)
&& !(pPlayer->Bot.BotBody.hit_state & OBSTACLE_RIGHT_FALL))
{
pPlayer->pEntity->v.button |= IN_MOVERIGHT;
pPlayer->Bot.BotMove.f_strafe_speed = pPlayer->Bot.BotMove.f_max_speed; // strafe right
}
// may the bot move backwards now ?
if (((pPlayer->Bot.BotMove.f_backwards_time > server.time)
&& (pPlayer->Bot.BotMove.f_forward_time + 0.2 < server.time))
|| (pPlayer->Bot.BotMove.b_emergency_walkback))
{
pPlayer->pEntity->v.button |= IN_BACK;
pPlayer->Bot.BotMove.f_move_speed = -pPlayer->Bot.BotMove.f_max_speed; // move backwards
}
// else may the bot move forward now ?
else if ((pPlayer->Bot.BotMove.f_forward_time > server.time)
&& (pPlayer->Bot.BotMove.f_backwards_time + 0.2 < server.time))
{
pPlayer->pEntity->v.button |= IN_FORWARD;
pPlayer->Bot.BotMove.f_move_speed = pPlayer->Bot.BotMove.f_max_speed; // run forward
}
// may the bot walk now ?
if (pPlayer->Bot.BotMove.f_walk_time > server.time)
{
pPlayer->pEntity->v.button |= IN_RUN;
pPlayer->Bot.BotMove.f_move_speed /= 2; // forward walk
pPlayer->Bot.BotMove.f_strafe_speed /= 2; // side walk
}
return;
}