Skip to content

Commit

Permalink
Add bot_mimic
Browse files Browse the repository at this point in the history
  • Loading branch information
s1lentq committed Jun 2, 2024
1 parent fef9bf3 commit ad1c58c
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 2 deletions.
4 changes: 4 additions & 0 deletions regamedll/dlls/bot/cs_bot_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ cvar_t cv_bot_deathmatch = { "bot_deathmatch", "0", FCVAR_SERVER, 0.
cvar_t cv_bot_quota_mode = { "bot_quota_mode", "normal", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_join_delay = { "bot_join_delay", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t cv_bot_freeze = { "bot_freeze", "0", 0, 0.0f, nullptr };
cvar_t cv_bot_mimic = { "bot_mimic", "0", 0, 0.0f, nullptr };
cvar_t cv_bot_mimic_yaw_offset = { "bot_mimic_yaw_offset", "0", 0, 0.0f, nullptr };
#else
// Migrated to bot_quota_mode, use "match"
cvar_t cv_bot_quota_match = { "bot_quota_match", "0", FCVAR_SERVER, 0.0f, nullptr };
Expand Down Expand Up @@ -131,6 +133,8 @@ void Bot_RegisterCVars()
CVAR_REGISTER(&cv_bot_quota_mode);
CVAR_REGISTER(&cv_bot_join_delay);
CVAR_REGISTER(&cv_bot_freeze);
CVAR_REGISTER(&cv_bot_mimic);
CVAR_REGISTER(&cv_bot_mimic_yaw_offset);
#endif

}
Expand Down
2 changes: 2 additions & 0 deletions regamedll/dlls/bot/cs_bot_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ extern cvar_t cv_bot_deathmatch;
extern cvar_t cv_bot_quota_mode;
extern cvar_t cv_bot_join_delay;
extern cvar_t cv_bot_freeze;
extern cvar_t cv_bot_mimic;
extern cvar_t cv_bot_mimic_yaw_offset;
#else
extern cvar_t cv_bot_quota_match;
#endif
17 changes: 17 additions & 0 deletions regamedll/dlls/bot/cs_bot_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,23 @@ void CCSBotManager::ServerCommand(const char *pcmd)

BOOL CCSBotManager::ClientCommand(CBasePlayer *pPlayer, const char *pcmd)
{
#ifdef REGAMEDLL_ADD
if (pPlayer->IsBot())
return FALSE;

if (cv_bot_mimic.value == pPlayer->entindex())
{
// Bots mimic our client commands
ForEachPlayer([pPlayer, pcmd](CBasePlayer *bot)
{
if (pPlayer != bot && bot->IsBot())
bot->ClientCommand(pcmd, CMD_ARGV_(1));

return true;
});
}
#endif

return FALSE;
}

Expand Down
6 changes: 6 additions & 0 deletions regamedll/dlls/bot/cs_bot_statemachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,12 @@ void CCSBot::Attack(CBasePlayer *victim)
if (cv_bot_zombie.value != 0.0f)
return;

#ifdef REGAMEDLL_ADD
// If mimicing the player, don't attack state
if (cv_bot_mimic.value)
return;
#endif

// cannot attack if we are reloading
if (IsActiveWeaponReloading())
return;
Expand Down
6 changes: 6 additions & 0 deletions regamedll/dlls/bot/cs_bot_vision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ void CCSBot::UpdateLookAngles()
float stiffness;
float damping;

#ifdef REGAMEDLL_ADD
// If mimicing the player, don't modify the view angles
if (cv_bot_mimic.value > 0)
return;
#endif

// springs are stiffer when attacking, so we can track and move between targets better
if (IsAttacking())
{
Expand Down
9 changes: 9 additions & 0 deletions regamedll/dlls/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10717,3 +10717,12 @@ bool CBasePlayer::Kill()

return true;
}

const usercmd_t *CBasePlayer::GetLastUserCommand() const
{
#ifdef REGAMEDLL_API
return CSPlayer()->GetLastUserCommand();
#else
return nullptr;
#endif
}
1 change: 1 addition & 0 deletions regamedll/dlls/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ class CBasePlayer: public CBaseMonster {
void SetClientUserInfoModel(char *infobuffer, char *szNewModel);
void SetClientUserInfoModel_api(char *infobuffer, char *szNewModel);
void SetNewPlayerModel(const char *modelName);
const usercmd_t *GetLastUserCommand() const;
BOOL SwitchWeapon(CBasePlayerItem *pWeapon);
void CheckPowerups();
bool CanAffordPrimary();
Expand Down
56 changes: 55 additions & 1 deletion regamedll/game_shared/bot/bot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,18 @@ void CBot::ExecuteCommand()
// Adjust msec to command time interval
adjustedMSec = ThrottledMsec();

// Run mimic command
usercmd_t botCmd;
if (!RunMimicCommand(botCmd))
{
botCmd.forwardmove = m_forwardSpeed;
botCmd.sidemove = m_strafeSpeed;
botCmd.upmove = m_verticalSpeed;
botCmd.buttons = m_buttonFlags;
botCmd.impulse = 0;
botCmd.viewangles = pev->v_angle;
}

// player model is "munged"
pev->angles = pev->v_angle;
pev->angles.x /= -3.0f;
Expand All @@ -283,7 +295,49 @@ void CBot::ExecuteCommand()
#endif

// Run the command
PLAYER_RUN_MOVE(edict(), pev->v_angle, m_forwardSpeed, m_strafeSpeed, m_verticalSpeed, m_buttonFlags, 0, adjustedMSec);
PLAYER_RUN_MOVE(edict(), botCmd.viewangles, botCmd.forwardmove, botCmd.sidemove, botCmd.upmove, botCmd.buttons, 0, adjustedMSec);
}

bool CBot::RunMimicCommand(usercmd_t &botCmd)
{
#ifdef REGAMEDLL_ADD
if (cv_bot_mimic.value <= 0)
return false;

if (cv_bot_mimic.value > gpGlobals->maxClients)
return false;

CBasePlayer *pPlayer = UTIL_PlayerByIndex(cv_bot_mimic.value);
if (!pPlayer)
return false;

if (!UTIL_IsValidPlayer(pPlayer))
return false;

if (!pPlayer->IsAlive())
return false;

if (pPlayer->IsBot())
return false;

const usercmd_t *ucmd = pPlayer->GetLastUserCommand();
if (!ucmd)
return false;

botCmd = *ucmd;
botCmd.viewangles[YAW] += cv_bot_mimic_yaw_offset.value;

float mult = 8.0f;
botCmd.forwardmove *= mult;
botCmd.sidemove *= mult;
botCmd.upmove *= mult;

pev->fixangle = 0;

return true;
#else
return false;
#endif
}

void CBot::ResetCommand()
Expand Down
2 changes: 2 additions & 0 deletions regamedll/game_shared/bot/bot.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ class CBot: public CBasePlayer
void ResetCommand();
byte ThrottledMsec() const;

bool RunMimicCommand(usercmd_t &botCmd);

// returns current movement speed (for walk/run)
float GetMoveSpeed();

Expand Down
2 changes: 1 addition & 1 deletion regamedll/game_shared/bot/bot_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ inline bool IsIntersecting2D(const Vector &startA, const Vector &endA, const Vec
// Iterate over all active players in the game, invoking functor on each.
// If functor returns false, stop iteration and return false.
template <typename Functor>
bool ForEachPlayer(Functor &func)
bool ForEachPlayer(Functor func)
{
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
Expand Down
5 changes: 5 additions & 0 deletions regamedll/pm_shared/pm_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3300,6 +3300,11 @@ void EXT_FUNC __API_HOOK(PM_Move)(struct playermove_s *ppmove, int server)
{
pmove->friction = 1.0f;
}

#ifdef REGAMEDLL_API
// save the last usercmd
pmoveplayer->SetLastUserCommand(pmove->cmd);
#endif
}

NOXREF int PM_GetVisEntInfo(int ent)
Expand Down
11 changes: 11 additions & 0 deletions regamedll/public/regamedll/API/CSPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ class CCSPlayer: public CCSMonster {
EProtectionState GetProtectionState() const;
bool CheckActivityInGame();

const usercmd_t *GetLastUserCommand() const
{
return &m_LastCmd;
}

void SetLastUserCommand(const usercmd_t &ucmd)
{
m_LastCmd = ucmd;
}

public:
char m_szModel[32];
bool m_bForceShowMenu;
Expand Down Expand Up @@ -175,6 +185,7 @@ class CCSPlayer: public CCSMonster {
bool m_bPlayerDominated[MAX_CLIENTS]; // [0-31] array of state per other player whether player is dominating other players

int m_iGibDamageThreshold; // negative health to reach to gib player
usercmd_t m_LastCmd;
};

// Inlines
Expand Down

0 comments on commit ad1c58c

Please sign in to comment.