added support for bot's pings in scoreboard
controlled via yb_latency_display = 2 thanks to podbotmm project
This commit is contained in:
parent
973b336977
commit
8da986cf37
7 changed files with 203 additions and 42 deletions
|
|
@ -978,6 +978,9 @@ private:
|
|||
float m_buttonPushTime; // time to push the button
|
||||
float m_liftUsageTime; // time to use lift
|
||||
|
||||
int m_pingOffset[2];
|
||||
int m_ping[3]; // bots pings in scoreboard
|
||||
|
||||
Vector m_liftTravelPos; // lift travel position
|
||||
Vector m_moveAngles; // bot move angles
|
||||
bool m_moveToGoal; // bot currently moving to goal??
|
||||
|
|
@ -1288,11 +1291,15 @@ class BotManager : public Singleton <BotManager>
|
|||
{
|
||||
private:
|
||||
Array <CreateQueue> m_creationTab; // bot creation tab
|
||||
|
||||
Bot *m_bots[32]; // all available bots
|
||||
float m_maintainTime; // time to maintain bot creation quota
|
||||
|
||||
int m_lastWinner; // the team who won previous round
|
||||
int m_roundCount; // rounds passed
|
||||
|
||||
bool m_economicsGood[2]; // is team able to buy anything
|
||||
bool m_deathMsgSent; // for fakeping
|
||||
|
||||
protected:
|
||||
int CreateBot (String name, int skill, int personality, int team, int member);
|
||||
|
|
@ -1340,6 +1347,14 @@ public:
|
|||
void CheckTeamEconomics (int team);
|
||||
|
||||
static void CallGameEntity (entvars_t *vars);
|
||||
|
||||
inline void SetDeathMsgState (bool sent) { m_deathMsgSent = sent; }
|
||||
inline bool GetDeathMsgState (void) { return m_deathMsgSent; }
|
||||
|
||||
public:
|
||||
void CalculatePingOffsets (void);
|
||||
void SendPingDataOffsets (edict_t *to);
|
||||
void SendDeathMsgFix (void);
|
||||
};
|
||||
|
||||
// texts localizer
|
||||
|
|
@ -1369,14 +1384,14 @@ public:
|
|||
~NetworkMsg (void) { };
|
||||
|
||||
void Execute (void *p);
|
||||
void Reset (void) { m_message = NETMSG_UNDEFINED; m_state = 0; m_bot = NULL; };
|
||||
inline void Reset (void) { m_message = NETMSG_UNDEFINED; m_state = 0; m_bot = NULL; };
|
||||
void HandleMessageIfRequired (int messageType, int requiredType);
|
||||
|
||||
void SetMessage (int message) { m_message = message; }
|
||||
void SetBot (Bot *bot) { m_bot = bot; }
|
||||
inline void SetMessage (int message) { m_message = message; }
|
||||
inline void SetBot (Bot *bot) { m_bot = bot; }
|
||||
|
||||
int GetId (int messageType) { return m_registerdMessages[messageType]; }
|
||||
void SetId (int messageType, int messsageIdentifier) { m_registerdMessages[messageType] = messsageIdentifier; }
|
||||
inline int GetId (int messageType) { return m_registerdMessages[messageType]; }
|
||||
inline void SetId (int messageType, int messsageIdentifier) { m_registerdMessages[messageType] = messsageIdentifier; }
|
||||
};
|
||||
|
||||
// waypoint operation class
|
||||
|
|
@ -1603,12 +1618,10 @@ public:
|
|||
};
|
||||
|
||||
// prototypes of bot functions...
|
||||
extern int GetMaxClients (void);
|
||||
extern int GetWeaponReturn (bool isString, const char *weaponAlias, int weaponIndex = -1);
|
||||
extern int GetTeam (edict_t *ent);
|
||||
|
||||
extern float GetShootingConeDeviation (edict_t *ent, Vector *position);
|
||||
extern float GetWorldTime (void);
|
||||
extern float GetWaveLength (const char *fileName);
|
||||
|
||||
extern bool TryFileOpen (char *fileName);
|
||||
|
|
@ -1667,6 +1680,16 @@ static inline bool IsNullString (const char *input)
|
|||
return *input == '\0';
|
||||
}
|
||||
|
||||
static inline float GetWorldTime (void)
|
||||
{
|
||||
return g_pGlobals->time;
|
||||
}
|
||||
|
||||
static inline int GetMaxClients (void)
|
||||
{
|
||||
return g_pGlobals->maxClients;
|
||||
}
|
||||
|
||||
// very global convars
|
||||
extern ConVar yb_jasonmode;
|
||||
extern ConVar yb_communication_type;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include <../include/resource.h>
|
||||
|
||||
// generated by update tool -- do not edit --
|
||||
#define PRODUCT_BUILD_TOOL 3844
|
||||
#define PRODUCT_BUILD_TOOL 3846
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION PRODUCT_VERSION_DWORD, PRODUCT_BUILD_TOOL
|
||||
|
|
|
|||
|
|
@ -803,8 +803,8 @@ Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
|
|||
SET_CLIENT_KEYVALUE (clientIndex, buffer, "_ah", "0");
|
||||
SET_CLIENT_KEYVALUE (clientIndex, buffer, "_vgui_menus", "0");
|
||||
|
||||
if (g_gameVersion != CSV_OLD)
|
||||
SET_CLIENT_KEYVALUE (clientIndex, buffer, "*bot", const_cast <char *> (yb_latency_display.GetBool () ? "1" : "0"));
|
||||
if (g_gameVersion != CSV_OLD && yb_latency_display.GetInt () == 1)
|
||||
SET_CLIENT_KEYVALUE (clientIndex, buffer, "*bot", "1");
|
||||
|
||||
rejectReason[0] = 0; // reset the reject reason template string
|
||||
MDLL_ClientConnect (bot, "BOT", FormatBuffer ("127.0.0.%d", ENTINDEX (bot) + 100), rejectReason);
|
||||
|
|
@ -827,7 +827,6 @@ Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
|
|||
m_moneyAmount = 0;
|
||||
|
||||
m_logotypeIndex = g_randGen.Long (0, 5);
|
||||
|
||||
m_msecVal = static_cast <byte> (g_pGlobals->frametime * 1000.0);
|
||||
|
||||
// assign how talkative this bot will be
|
||||
|
|
@ -1255,3 +1254,138 @@ void Bot::StartGame (void)
|
|||
ChatMessage (CHAT_WELCOME);
|
||||
}
|
||||
}
|
||||
|
||||
void BotManager::CalculatePingOffsets (void)
|
||||
{
|
||||
if (yb_latency_display.GetInt () != 2)
|
||||
return;
|
||||
|
||||
int averagePing = 0;
|
||||
int numHumans = 0;
|
||||
|
||||
for (int i = 0; i < GetMaxClients (); i++)
|
||||
{
|
||||
edict_t *ent = INDEXENT (i + 1);
|
||||
|
||||
if (!IsValidPlayer (ent))
|
||||
continue;
|
||||
|
||||
numHumans++;
|
||||
|
||||
int ping, loss;
|
||||
PLAYER_CNX_STATS (ent, &ping, &loss);
|
||||
|
||||
if (ping < 0 || ping > 100)
|
||||
ping = g_randGen.Long (3, 15);
|
||||
|
||||
averagePing += ping;
|
||||
}
|
||||
|
||||
if (numHumans > 0)
|
||||
averagePing /= numHumans;
|
||||
else
|
||||
averagePing = g_randGen.Long (30, 40);
|
||||
|
||||
for (int i = 0; i < GetMaxClients (); i++)
|
||||
{
|
||||
Bot *bot = GetBot (i);
|
||||
|
||||
if (bot == NULL)
|
||||
continue;
|
||||
|
||||
int botPing = g_randGen.Long (averagePing - averagePing * 0.2f, averagePing + averagePing * 0.2f) + g_randGen.Long (bot->m_skill / 100 * 0.5, bot->m_skill / 100);
|
||||
|
||||
if (botPing <= 5)
|
||||
botPing = g_randGen.Long (10, 23);
|
||||
else if (botPing > 100)
|
||||
botPing = g_randGen.Long (30, 40);
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
for (bot->m_pingOffset[j] = 0; bot->m_pingOffset[j] < 4; bot->m_pingOffset[j]++)
|
||||
{
|
||||
if ((botPing - bot->m_pingOffset[j]) % 4 == 0)
|
||||
{
|
||||
bot->m_ping[j] = (botPing - bot->m_pingOffset[j]) / 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bot->m_ping[2] = botPing;
|
||||
}
|
||||
}
|
||||
|
||||
void BotManager::SendPingDataOffsets (edict_t *to)
|
||||
{
|
||||
if (yb_latency_display.GetInt () != 2)
|
||||
return;
|
||||
|
||||
if (!IsValidPlayer (to) || IsValidBot (to))
|
||||
return;
|
||||
|
||||
if (!((to->v.button & IN_SCORE) || (to->v.oldbuttons & IN_SCORE)))
|
||||
return;
|
||||
|
||||
static int sending;
|
||||
sending = 0;
|
||||
|
||||
// missing from sdk
|
||||
static const int SVC_PINGS = 17;
|
||||
|
||||
for (int i = 0; i < GetMaxClients (); i++)
|
||||
{
|
||||
Bot *bot = GetBot (i);
|
||||
|
||||
if (bot == NULL)
|
||||
continue;
|
||||
|
||||
switch (sending)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// start a new message
|
||||
MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, SVC_PINGS, NULL, to);
|
||||
WRITE_BYTE ((m_bots[i]->m_pingOffset[sending] * 64) + (1 + 2 * i));
|
||||
WRITE_SHORT (m_bots[i]->m_ping[sending]);
|
||||
|
||||
sending++;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
// append additional data
|
||||
WRITE_BYTE ((m_bots[i]->m_pingOffset[sending] * 128) + (2 + 4 * i));
|
||||
WRITE_SHORT (m_bots[i]->m_ping[sending]);
|
||||
|
||||
sending++;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// append additional data and end message
|
||||
WRITE_BYTE (4 + 8 * i);
|
||||
WRITE_SHORT (m_bots[i]->m_ping[sending]);
|
||||
WRITE_BYTE (0);
|
||||
MESSAGE_END ();
|
||||
|
||||
sending = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// end message if not yet sent
|
||||
if (sending)
|
||||
{
|
||||
WRITE_BYTE (0);
|
||||
MESSAGE_END ();
|
||||
}
|
||||
}
|
||||
|
||||
void BotManager::SendDeathMsgFix (void)
|
||||
{
|
||||
if (yb_latency_display.GetInt () == 2 && m_deathMsgSent)
|
||||
{
|
||||
m_deathMsgSent = false;
|
||||
|
||||
for (int i = 0; i < GetMaxClients (); i++)
|
||||
SendPingDataOffsets (g_clients[i].ent);
|
||||
}
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ metamod_funcs_t gMetaFunctionTable =
|
|||
NULL, // pfnGetNewDLLFunctions ()
|
||||
NULL, // pfnGetNewDLLFunctions_Post ()
|
||||
GetEngineFunctions, // pfnGetEngineFunctions ()
|
||||
NULL, // pfnGetEngineFunctions_Post ()
|
||||
GetEngineFunctions_Post, // pfnGetEngineFunctions_Post ()
|
||||
};
|
||||
|
||||
// metamod plugin information
|
||||
|
|
|
|||
|
|
@ -1155,23 +1155,17 @@ int Spawn (edict_t *ent)
|
|||
return result;
|
||||
}
|
||||
|
||||
void Touch (edict_t *pentTouched, edict_t *pentOther)
|
||||
void UpdateClientData (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd)
|
||||
{
|
||||
// this function is called when two entities' bounding boxes enter in collision. For example,
|
||||
// when a player walks upon a gun, the player entity bounding box collides to the gun entity
|
||||
// bounding box, and the result is that this function is called. It is used by the game for
|
||||
// taking the appropriate action when such an event occurs (in our example, the player who
|
||||
// is walking upon the gun will "pick it up"). Entities that "touch" others are usually
|
||||
// entities having a velocity, as it is assumed that static entities (entities that don't
|
||||
// move) will never touch anything. Hence, in our example, the pentTouched will be the gun
|
||||
// (static entity), whereas the pentOther will be the player (as it is the one moving). When
|
||||
// the two entities both have velocities, for example two players colliding, this function
|
||||
// is called twice, once for each entity moving.
|
||||
extern ConVar yb_latency_display;
|
||||
|
||||
if (yb_latency_display.GetInt () == 2)
|
||||
g_botManager->SendPingDataOffsets (const_cast <edict_t *> (ent));
|
||||
|
||||
if (g_isMetamod)
|
||||
RETURN_META (MRES_IGNORED);
|
||||
|
||||
(*g_functionTable.pfnTouch) (pentTouched, pentOther);
|
||||
(*g_functionTable.pfnUpdateClientData) (ent, sendweapons, cd);
|
||||
}
|
||||
|
||||
void ClientPutInServer (edict_t *ent)
|
||||
|
|
@ -2295,6 +2289,7 @@ void StartFrame (void)
|
|||
|
||||
CheckWelcomeMessage ();
|
||||
}
|
||||
g_botManager->SetDeathMsgState (false);
|
||||
|
||||
if (secondTimer < GetWorldTime ())
|
||||
{
|
||||
|
|
@ -2333,6 +2328,7 @@ void StartFrame (void)
|
|||
if (csdm_active != NULL && csdm_active->value > 0)
|
||||
yb_csdm_mode.SetInt (mp_freeforall != NULL && mp_freeforall->value > 0 ? 2 : 1);
|
||||
}
|
||||
g_botManager->CalculatePingOffsets ();
|
||||
}
|
||||
|
||||
extern ConVar yb_danger_factor;
|
||||
|
|
@ -2572,6 +2568,17 @@ void pfnMessageEnd (void)
|
|||
RETURN_META (MRES_IGNORED);
|
||||
|
||||
MESSAGE_END ();
|
||||
|
||||
// send latency fix
|
||||
g_botManager->SendDeathMsgFix ();
|
||||
}
|
||||
|
||||
void pfnMessageEnd_Post (void)
|
||||
{
|
||||
// send latency fix
|
||||
g_botManager->SendDeathMsgFix ();
|
||||
|
||||
RETURN_META (MRES_IGNORED);
|
||||
}
|
||||
|
||||
void pfnWriteByte (int value)
|
||||
|
|
@ -2953,7 +2960,7 @@ export int GetEntityAPI2 (gamefuncs_t *functionTable, int *interfaceVersion)
|
|||
functionTable->pfnServerDeactivate = ServerDeactivate;
|
||||
functionTable->pfnKeyValue = KeyValue;
|
||||
functionTable->pfnStartFrame = StartFrame;
|
||||
functionTable->pfnTouch = Touch;
|
||||
functionTable->pfnUpdateClientData = UpdateClientData;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -3031,6 +3038,15 @@ export int GetEngineFunctions (enginefuncs_t *functionTable, int *interfaceVersi
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
export int GetEngineFunctions_Post (enginefuncs_t *functionTable, int *interfaceVersion)
|
||||
{
|
||||
memset (functionTable, 0, sizeof (enginefuncs_t));
|
||||
|
||||
functionTable->pfnMessageEnd = pfnMessageEnd_Post;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
export int Server_GetBlendingInterface (int version, void **ppinterface, void *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[128][3][4])
|
||||
{
|
||||
// this function synchronizes the studio model animation blending interface (i.e, what parts
|
||||
|
|
|
|||
|
|
@ -274,6 +274,8 @@ void NetworkMsg::Execute (void *p)
|
|||
break;
|
||||
|
||||
case 2:
|
||||
g_botManager->SetDeathMsgState (true);
|
||||
|
||||
if (killerIndex != 0 && killerIndex != victimIndex)
|
||||
{
|
||||
edict_t *killer = INDEXENT (killerIndex);
|
||||
|
|
|
|||
|
|
@ -991,20 +991,6 @@ void ServerCommand (const char *format, ...)
|
|||
SERVER_COMMAND (FormatBuffer ("%s\n", string)); // execute command
|
||||
}
|
||||
|
||||
float GetWorldTime (void)
|
||||
{
|
||||
// this function returns engine current time on this server
|
||||
|
||||
return g_pGlobals->time;
|
||||
}
|
||||
|
||||
int GetMaxClients (void)
|
||||
{
|
||||
// this function returns current players on server
|
||||
|
||||
return g_pGlobals->maxClients;
|
||||
}
|
||||
|
||||
const char *GetMapName (void)
|
||||
{
|
||||
// this function gets the map name and store it in the map_name global string variable.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue