Bots will now smooth turn to new angle.

This commit is contained in:
Justin Marshall
2026-05-20 09:34:53 -07:00
parent 31a3805769
commit 8a5719143d
5 changed files with 58 additions and 11 deletions
+50 -1
View File
@@ -30,6 +30,19 @@ static bool BotDirectPathIsClear( int passEntityNum, const idVec3& from, const i
return trace.fraction >= 0.95f;
}
static idAngles BotTurnTowardAngles( const idAngles& currentAngles, const idAngles& desiredAngles, float maxTurn )
{
idAngles result = currentAngles;
for( int i = 0; i < 2; i++ )
{
float delta = idMath::AngleDelta( desiredAngles[i], currentAngles[i] );
delta = idMath::ClampFloat( -maxTurn, maxTurn, delta );
result[i] = idMath::AngleMod( currentAngles[i] + delta );
}
result[ROLL] = 0.0f;
return result;
}
static idVec3 bot_stuckOrigin[MAX_CLIENTS];
static float bot_stuckTime[MAX_CLIENTS];
static bool bot_stuckInit[MAX_CLIENTS];
@@ -226,6 +239,7 @@ rvmBot::Think
void rvmBot::BotMoveToGoalOrigin(idVec3 goalOrigin)
{
idVec3 moveDir = goalOrigin - GetPhysics()->GetOrigin();
const float goalDist = moveDir.Length();
// Usercmd forward/right movement is horizontal. Feeding pitch or a view-origin
// z delta into the movement vector makes the bot under-steer, drift, or push
@@ -239,6 +253,40 @@ void rvmBot::BotMoveToGoalOrigin(idVec3 goalOrigin)
}
else
{
if( bs.enemy < 0 && goalDist > 96.0f )
{
if( bs.move_wander_time < Bot_Time() )
{
bs.move_wander_time = Bot_Time() + idMath::FRandRange( 0.75f, 1.8f );
bs.move_wander_side = rvmBotUtil::crandom();
if( idMath::Fabs( bs.move_wander_side ) < 0.35f )
{
bs.move_wander_side = bs.move_wander_side < 0.0f ? -0.35f : 0.35f;
}
}
idVec3 forwardDir = moveDir;
forwardDir.Normalize();
idVec3 sideDir( -forwardDir[1], forwardDir[0], 0.0f );
const float wanderScale = idMath::ClampFloat( 0.0f, 64.0f, goalDist * 0.18f );
idVec3 wanderedDir = moveDir + sideDir * ( wanderScale * bs.move_wander_side );
wanderedDir[2] = 0.0f;
idVec3 testDir = wanderedDir;
if( testDir.Normalize() > 0.0f )
{
idVec3 testEnd = GetPhysics()->GetOrigin() + testDir * 56.0f;
if( BotDirectPathIsClear( entityNumber, GetPhysics()->GetOrigin() + idVec3( 0.0f, 0.0f, 24.0f ), testEnd + idVec3( 0.0f, 0.0f, 24.0f ) ) )
{
moveDir = wanderedDir;
}
else
{
bs.move_wander_side = -bs.move_wander_side;
}
}
}
bs.botinput.dir = moveDir;
bs.botinput.dir.Normalize();
bs.botinput.speed = pm_runspeed.GetInteger();
@@ -252,7 +300,8 @@ void rvmBot::BotMoveToGoalOrigin(idVec3 goalOrigin)
}
else if( moveDir.LengthSqr() > Square( 1.0f ) )
{
bs.botinput.viewangles = idAngles( 0.0f, moveDir.ToYaw(), 0.0f );
const idAngles desiredAngles( 0.0f, moveDir.ToYaw(), 0.0f );
bs.botinput.viewangles = BotTurnTowardAngles( viewAngles, desiredAngles, 22.0f );
bs.viewangles = bs.botinput.viewangles;
}
else
+4
View File
@@ -765,6 +765,8 @@ struct bot_state_t
attackcrouch_time = 0;
attackstrafe_time = 0;
attackjump_time = 0;
move_wander_time = 0;
move_wander_side = 0.0f;
firethrottleshoot_time = 0;
chase_time = 0;
thinktime = 0;
@@ -799,6 +801,8 @@ struct bot_state_t
float attackcrouch_time;
float attackstrafe_time;
float attackchase_time;
float move_wander_time;
float move_wander_side;
float firethrottlewait_time;
float firethrottleshoot_time;
float nbg_time; //nearby goal time
+2
View File
@@ -335,9 +335,11 @@ void rvmBot::BotChooseWeapon(bot_state_t* bs)
if (bs->weaponnum != newweaponnum)
{
bs->weaponchange_time = Bot_Time();
bs->botinput.lastWeaponNum = -1;
}
bs->weaponnum = newweaponnum;
bs->botinput.weapon = bs->weaponnum;
SelectWeapon(bs->weaponnum, false);
}
-10
View File
@@ -413,23 +413,13 @@ static const char* Bot_ItemWeightAlias( const char* classname )
static const itemWeightAlias_t aliases[] =
{
{ "weapon_machinegun_mp", "weapon_machinegun" },
{ "weapon_shotgun_mp", "weapon_shotgun" },
{ "weapon_rocketlauncher_mp", "weapon_rocketlauncher" },
{ "weapon_plasmagun_mp", "weapon_plasmagun" },
{ "weapon_bfg_mp", "weapon_bfg" },
{ "weapon_grenadelauncher", "weapon_rocketlauncher" },
{ "weapon_grenadelauncher_mp", "weapon_rocketlauncher" },
{ "weapon_lightning", "weapon_plasmagun" },
{ "weapon_lightning_mp", "weapon_plasmagun" },
{ "weapon_railgun", "weapon_rocketlauncher" },
{ "weapon_railgun_mp", "weapon_rocketlauncher" },
{ "weapon_fists", "weapon_pistol" },
{ "weapon_grapplinghook", "weapon_chainsaw" },
{ "weapon_nailgun", "weapon_chaingun" },
{ "weapon_nailgun_mp", "weapon_chaingun" },
{ "weapon_prox_launcher", "weapon_rocketlauncher" },
{ "weapon_prox_launcher_mp", "weapon_rocketlauncher" },
{ "team_redobelisk", "item_armor_shard" },
{ "team_blueobelisk", "item_armor_shard" },
+2
View File
@@ -8464,6 +8464,8 @@ static classVariableInfo_t bot_state_t_typeInfo[] = {
{ "float", "attackcrouch_time", (intptr_t)(&((bot_state_t *)0)->attackcrouch_time), sizeof( ((bot_state_t *)0)->attackcrouch_time ) },
{ "float", "attackstrafe_time", (intptr_t)(&((bot_state_t *)0)->attackstrafe_time), sizeof( ((bot_state_t *)0)->attackstrafe_time ) },
{ "float", "attackchase_time", (intptr_t)(&((bot_state_t *)0)->attackchase_time), sizeof( ((bot_state_t *)0)->attackchase_time ) },
{ "float", "move_wander_time", (intptr_t)(&((bot_state_t *)0)->move_wander_time), sizeof( ((bot_state_t *)0)->move_wander_time ) },
{ "float", "move_wander_side", (intptr_t)(&((bot_state_t *)0)->move_wander_side), sizeof( ((bot_state_t *)0)->move_wander_side ) },
{ "float", "firethrottlewait_time", (intptr_t)(&((bot_state_t *)0)->firethrottlewait_time), sizeof( ((bot_state_t *)0)->firethrottlewait_time ) },
{ "float", "firethrottleshoot_time", (intptr_t)(&((bot_state_t *)0)->firethrottleshoot_time), sizeof( ((bot_state_t *)0)->firethrottleshoot_time ) },
{ "float", "nbg_time", (intptr_t)(&((bot_state_t *)0)->nbg_time), sizeof( ((bot_state_t *)0)->nbg_time ) },