Files
2026-05-19 19:43:23 -07:00

154 lines
3.7 KiB
C++

// Bot_Input.cpp
//
#include "precompiled.h"
#pragma hdrstop
#include "../Game_local.h"
#include "../../../engine/framework/UsercmdGen.h"
/*
==============
rvmBot::BotInputToUserCommand
==============
*/
void rvmBot::BotInputToUserCommand(bot_input_t* bi, usercmd_t* ucmd, int time)
{
idVec3 forward, right;
if( bi == NULL || ucmd == NULL )
{
return;
}
if (bi->actionflags & ACTION_DELAYEDJUMP)
{
bi->actionflags |= ACTION_JUMP;
bi->actionflags &= ~ACTION_DELAYEDJUMP;
}
if (bi->actionflags & ACTION_RESPAWN)
{
ucmd->buttons |= BUTTON_ATTACK;
}
if (bi->actionflags & ACTION_ATTACK)
{
ucmd->buttons |= BUTTON_ATTACK;
}
if (bi->actionflags & ACTION_WALK)
{
ucmd->buttons |= BUTTON_RUN;
}
ucmd->impulse = 0;
if (bi->lastWeaponNum != bi->weapon)
{
ucmd->impulse = bi->weapon;
bi->lastWeaponNum = bi->weapon;
}
idAngles botViewAngles = viewAngles;
// Slow smoothing made bots fire while their usercmd view was still several
// frames behind the computed aim, which is very noticeable when looking down
// stairs. Turn briskly in general and snap on the frames where the bot is
// actually firing.
const float turnScale = ( bi->actionflags & ACTION_ATTACK ) ? 1.0f : 0.35f;
for (int i = 0; i < 3; i++)
{
const float move = idMath::AngleDelta( bi->viewangles[i], botViewAngles[i] );
botViewAngles[i] += move * turnScale;
}
//set the view angles
//NOTE: the ucmd->angles are the angles WITHOUT the delta angles
ucmd->angles[0] = ANGLE2SHORT(botViewAngles[0] - deltaViewAngles[0]);
ucmd->angles[1] = ANGLE2SHORT(botViewAngles[1] - deltaViewAngles[1]);
ucmd->angles[2] = ANGLE2SHORT(botViewAngles[2] - deltaViewAngles[2]);
// Movement commands are relative to the view angles that are actually put into
// this usercmd, not the unsmoothed desired angles. Also keep movement on the
// horizontal plane so looking up/down at an enemy does not change speed.
idAngles moveAngles = botViewAngles;
moveAngles[PITCH] = 0.0f;
moveAngles[ROLL] = 0.0f;
moveAngles.ToVectors(&forward, &right, NULL);
idVec3 moveDir = bi->dir;
moveDir[2] = 0.0f;
if( moveDir.LengthSqr() > Square( 0.001f ) )
{
moveDir.Normalize();
}
else
{
moveDir = idVec3( 0.0f, 0.0f, 0.0f );
}
float scaledSpeed = bi->speed;
if( scaledSpeed < 0.0f )
{
scaledSpeed = 0.0f;
}
else if( scaledSpeed > 400.0f )
{
scaledSpeed = 400.0f;
}
scaledSpeed = scaledSpeed * 127.0f / 400.0f;
ucmd->forwardmove = idMath::ClampChar( DotProduct(forward, moveDir) * scaledSpeed );
ucmd->rightmove = idMath::ClampChar( DotProduct(right, moveDir) * scaledSpeed );
//normal keyboard movement
if (bi->actionflags & ACTION_MOVEFORWARD)
{
ucmd->forwardmove = idMath::ClampChar( ucmd->forwardmove + 127 );
}
if (bi->actionflags & ACTION_MOVEBACK)
{
ucmd->forwardmove = idMath::ClampChar( ucmd->forwardmove - 127 );
}
if (bi->actionflags & ACTION_MOVELEFT)
{
ucmd->rightmove = idMath::ClampChar( ucmd->rightmove - 127 );
}
if (bi->actionflags & ACTION_MOVERIGHT)
{
ucmd->rightmove = idMath::ClampChar( ucmd->rightmove + 127 );
}
if( bi->respawn )
{
ucmd->buttons |= BUTTON_ATTACK;
}
}
/*
================
rvmBot::ResetUcmd
================
*/
void rvmBot::Bot_ResetUcmd( usercmd_t& ucmd )
{
ucmd.forwardmove = 0;
ucmd.rightmove = 0;
//ucmd.upmove = 0;
ucmd.impulse = 0;
//ucmd.flags = 0;
memset( &ucmd.buttons, 0, sizeof( ucmd.buttons ) );
}
/*
========================
rvmBot::BotInputFrame
========================
*/
void rvmBot::BotInputFrame( void )
{
usercmd_t botcmd = { }; //(usercmd_t&)cmdMgr.GetUserCmdForPlayer(entityNumber); // gameLocal.usercmds[entityNumber];
Bot_ResetUcmd( botcmd );
BotInputToUserCommand( &bs.botinput, &botcmd, gameLocal.time );
networkSystem->ServerSetBotUserCommand(entityNumber, gameLocal.framenum, botcmd);
}