Skip to content

Commit

Permalink
Add Dynamic Aim Speed
Browse files Browse the repository at this point in the history
  • Loading branch information
caxanga334 committed Jun 5, 2024
1 parent 4c9fc5d commit 7bd4f9d
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 14 deletions.
20 changes: 15 additions & 5 deletions configs/bot_difficulty.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ BotDifficultyProfiles
* "Easy" // this is a section name, it not used
* {
* "skill_level" "0" // the skill level this profile belongs to
* "aimspeed" "5" // how fast the bot aims moves towards a look goal
* "aimspeed" "5" // maximum bot aiming speed
* "initialaimspeed" "2" // initial bot aiming speed
* "aimacceleration" "1" // how fast the aim speed approaches the maximum speed
* "fov" "60" // bot field of view in degrees
* "maxvisionrange" "1024" // bot maximum vision range in Hammer Units
* "maxhearingrange" "350" // bot maximum hearing range in Hammer Units
Expand All @@ -22,7 +24,9 @@ BotDifficultyProfiles
"Easy"
{
"skill_level" "0"
"aimspeed" "5"
"aimspeed" "10"
"initialaimspeed" "1"
"aimacceleration" "0.2"
"fov" "60"
"maxvisionrange" "1024"
"maxhearingrange" "350"
Expand All @@ -31,7 +35,9 @@ BotDifficultyProfiles
"Normal"
{
"skill_level" "1"
"aimspeed" "15"
"aimspeed" "20"
"initialaimspeed" "4"
"aimacceleration" "0.3"
"fov" "90"
"maxvisionrange" "2048"
"maxhearingrange" "750"
Expand All @@ -40,7 +46,9 @@ BotDifficultyProfiles
"Hard"
{
"skill_level" "2"
"aimspeed" "25"
"aimspeed" "40"
"initialaimspeed" "6"
"aimacceleration" "0.4"
"fov" "110"
"maxvisionrange" "2048"
"maxhearingrange" "1024"
Expand All @@ -49,7 +57,9 @@ BotDifficultyProfiles
"Expert"
{
"skill_level" "3"
"aimspeed" "40"
"aimspeed" "60"
"initialaimspeed" "10"
"aimacceleration" "0.5"
"fov" "140"
"maxvisionrange" "4096"
"maxhearingrange" "2048"
Expand Down
16 changes: 12 additions & 4 deletions extension/bot/interfaces/playercontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ IPlayerController::~IPlayerController()
void IPlayerController::OnDifficultyProfileChanged()
{
auto& profile = GetBot()->GetDifficultyProfile();
m_aimspeed = profile.GetAimSpeed();
m_aimdata.maxspeed = profile.GetAimSpeed();
m_aimdata.acceleration = profile.GetAimAcceleration();
m_aimdata.base = profile.GetAimInitialSpeed();
}

void IPlayerController::Reset()
Expand All @@ -39,7 +41,9 @@ void IPlayerController::Reset()
m_steadyTimer.Invalidate();

auto& profile = GetBot()->GetDifficultyProfile();
m_aimspeed = profile.GetAimSpeed();
m_aimdata.maxspeed = profile.GetAimSpeed();
m_aimdata.acceleration = profile.GetAimAcceleration();
m_aimdata.base = profile.GetAimInitialSpeed();
}

void IPlayerController::Update()
Expand Down Expand Up @@ -104,6 +108,7 @@ void IPlayerController::RunLook()
// no need to make changes anymore
if (m_looktimer.IsElapsed())
{
m_aimdata.speed = m_aimdata.base;
return;
}

Expand Down Expand Up @@ -157,12 +162,15 @@ void IPlayerController::RunLook()
m_isOnTarget = false; // aim is off target
}

finalAngles.x = ApproachAngle(desiredAngles.x, currentAngles.x, m_aimspeed);
finalAngles.y = ApproachAngle(desiredAngles.y, currentAngles.y, m_aimspeed);
finalAngles.x = ApproachAngle(desiredAngles.x, currentAngles.x, m_aimdata.speed);
finalAngles.y = ApproachAngle(desiredAngles.y, currentAngles.y, m_aimdata.speed);

finalAngles.x = AngleNormalize(finalAngles.x);
finalAngles.y = AngleNormalize(finalAngles.y);

// Accelerate our aim
m_aimdata.speed = Approach(m_aimdata.maxspeed, m_aimdata.speed, m_aimdata.acceleration);

if (me->IsDebugging(BOTDEBUG_LOOK))
{
constexpr auto DRAW_TIME = 0.2f;
Expand Down
11 changes: 10 additions & 1 deletion extension/bot/interfaces/playercontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,25 @@ class IPlayerController : public IBotInterface, public IPlayerInput
virtual const float GetSteadyTime() const { return m_steadyTimer.HasStarted() ? m_steadyTimer.GetElapsedTime() : 0.0f; }

private:

struct AimData
{
float speed; // current aim speed
float maxspeed; // aim speed to reach
float base; // initial aim speed
float acceleration; // how fast to reach max speed
};

LookPriority m_priority; // Current look priority
CountdownTimer m_looktimer; // Timer for the current look at task
Vector m_looktarget; // Look at target (Position Vector)
CBaseHandle m_lookentity; // Look at target (Entity, overrides vector if present)
QAngle m_lastangles; // Last bot view angles
float m_aimspeed; // Look angle approach rate
bool m_isSteady; // Is the bot aim steady?
bool m_isOnTarget; // Is the bot looking at it's look timer
bool m_didLookAtTarget; // Did the bot look at it's current aim target at some point
IntervalTimer m_steadyTimer; // Aim stability timer
AimData m_aimdata;
};

inline const char* GetLookPriorityName(IPlayerController::LookPriority priority)
Expand Down
10 changes: 10 additions & 0 deletions extension/bot/interfaces/profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ SourceMod::SMCResult CDifficultyManager::ReadSMC_KeyValue(const SourceMod::SMCSt
{
m_data.minrecognitiontime = atof(value);
}
else if (strncasecmp(key, "initialaimspeed", 15) == 0)
{
m_data.aiminitialspeed = atof(value);
}
else if (strncasecmp(key, "aimacceleration", 15) == 0)
{
m_data.aimacceleration = atof(value);
}
else
{
smutils->LogError(myself, "Unknown key \"%s\" with value \"%s\" found while parsing bot difficulty profile!", key, value);
Expand All @@ -123,6 +131,8 @@ SourceMod::SMCResult CDifficultyManager::ReadSMC_LeavingSection(const SourceMod:

profile.SetSkillLevel(m_data.skill_level);
profile.SetAimSpeed(m_data.aimspeed);
profile.SetAimAcceleration(m_data.aimacceleration);
profile.SetAimInitialSpeed(m_data.aiminitialspeed);
profile.SetFOV(m_data.fov);
profile.SetMaxVisionRange(m_data.maxvisionrange);
profile.SetMaxHearingRange(m_data.maxhearingrange);
Expand Down
18 changes: 14 additions & 4 deletions extension/bot/interfaces/profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class DifficultyProfile
{
public:
DifficultyProfile() :
skill_level(-1), aimspeed(25.0f), fov(90), maxvisionrange(2048), maxhearingrange(512),
skill_level(-1), aimspeed(25.0f), aimacceleration(2.0f), aiminitialspeed(10.0f), fov(90), maxvisionrange(2048), maxhearingrange(512),
minrecognitiontime(0.3f) {}

DifficultyProfile(const DifficultyProfile& other)
Expand Down Expand Up @@ -39,17 +39,23 @@ class DifficultyProfile
inline const int GetMaxVisionRange() const { return maxvisionrange; }
inline const int GetMaxHearingRange() const { return maxhearingrange; }
inline const float GetMinRecognitionTime() const { return minrecognitiontime; }
inline const float GetAimAcceleration() const { return aimacceleration; }
inline const float GetAimInitialSpeed() const { return aiminitialspeed; }

inline void SetSkillLevel(const int skill) { skill_level = skill; }
inline void SetAimSpeed(const float speed) { aimspeed = speed; }
inline void SetFOV(const int v) { fov = v; }
inline void SetMaxVisionRange(const int range) { maxvisionrange = range; }
inline void SetMaxHearingRange(const int range) { maxhearingrange = range; }
inline void SetMinRecognitionTime(const float time) { minrecognitiontime = time; }
inline void SetAimAcceleration(const float value) { aimacceleration = value; }
inline void SetAimInitialSpeed(const float value) { aiminitialspeed = value; }

private:
int skill_level; // the skill level this profile represents
float aimspeed; // how fast the bot aim approaches a given look at vector
float aimspeed; // Aiming speed cap
float aimacceleration; // How fast the bot aim accelerates per tick
float aiminitialspeed; // Initial aim speed
int fov; // field of view in degrees
int maxvisionrange; // maximum distance the bot is able to see
int maxhearingrange; // maximum distace the bot is able to hear
Expand All @@ -61,9 +67,9 @@ class CDifficultyManager : public SourceMod::ITextListener_SMC
{
public:
CDifficultyManager() :
m_data(),
m_newprofile(false),
m_parser_header(false)
m_parser_header(false),
m_data()
{
m_profiles.reserve(64);
}
Expand Down Expand Up @@ -129,6 +135,8 @@ class CDifficultyManager : public SourceMod::ITextListener_SMC
int maxvisionrange; // maximum distance the bot is able to see
int maxhearingrange; // maximum distace the bot is able to hear
float minrecognitiontime;
float aimacceleration; // How fast the bot aim accelerates per tick
float aiminitialspeed; // Initial aim speed

// Initialize the profile data
inline void OnNew()
Expand All @@ -139,6 +147,8 @@ class CDifficultyManager : public SourceMod::ITextListener_SMC
maxvisionrange = 1500;
maxhearingrange = 750;
minrecognitiontime = 0.3f;
aimacceleration = 1.5f;
aiminitialspeed = 6.0f;
}
};

Expand Down

0 comments on commit 7bd4f9d

Please sign in to comment.