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
|
|
@ -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