fix: refactoring mistake with square distances (ref #506 #495)

fix:  bot glibc dependency when SIMD is disabled
fakeping: allow to disable ping average ping calculation from human players (controllable via yb_count_players_for_fakeping)
This commit is contained in:
jeefo 2024-01-19 21:35:00 +03:00
commit d5a9253582
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
3 changed files with 39 additions and 34 deletions

@ -1 +1 @@
Subproject commit 07c54138879ea360913a594b3c11557361e20fed Subproject commit 72b32ac851400c6abb2332299d42f62b871620dd

View file

@ -627,7 +627,7 @@ bool Bot::isFriendInLineOfFire (float distance) {
} }
const auto friendDistanceSq = client.ent->v.origin.distanceSq (pev->origin); const auto friendDistanceSq = client.ent->v.origin.distanceSq (pev->origin);
if (friendDistanceSq <= distanceSq && util.getShootingCone (ent (), client.ent->v.origin) > friendDistanceSq / (friendDistanceSq + cr::sqrf (1089.0f))) { if (friendDistanceSq <= distanceSq && util.getShootingCone (ent (), client.ent->v.origin) > friendDistanceSq / (friendDistanceSq + cr::sqrf (33.0f))) {
return true; return true;
} }
} }
@ -975,9 +975,6 @@ void Bot::fireWeapons () {
// or if friend in line of fire, stop this too but do not update shoot time // or if friend in line of fire, stop this too but do not update shoot time
if (isFriendInLineOfFire (distance)) { if (isFriendInLineOfFire (distance)) {
m_fightStyle = Fight::Strafe;
m_lastFightStyleCheck = game.time ();
return; return;
} }
int selectId = Weapon::Knife, selectIndex = 0, choosenWeapon = 0; int selectId = Weapon::Knife, selectIndex = 0, choosenWeapon = 0;

View file

@ -11,6 +11,7 @@ ConVar cv_display_welcome_text ("display_welcome_text", "1", "Enables or disable
ConVar cv_enable_query_hook ("enable_query_hook", "0", "Enables or disables fake server queries response, that shows bots as real players in server browser."); ConVar cv_enable_query_hook ("enable_query_hook", "0", "Enables or disables fake server queries response, that shows bots as real players in server browser.");
ConVar cv_breakable_health_limit ("breakable_health_limit", "500.0", "Specifies the maximum health of breakable object, that bot will consider to destroy.", true, 1.0f, 3000.0); ConVar cv_breakable_health_limit ("breakable_health_limit", "500.0", "Specifies the maximum health of breakable object, that bot will consider to destroy.", true, 1.0f, 3000.0);
ConVar cv_enable_fake_steamids ("enable_fake_steamids", "0", "Allows or disallows bots to return fake steam id."); ConVar cv_enable_fake_steamids ("enable_fake_steamids", "0", "Allows or disallows bots to return fake steam id.");
ConVar cv_count_players_for_fakeping ("count_players_for_fakeping", "1", "Count player pings when calculating average ping for bots. If no, some random ping chosen for bots.");
BotSupport::BotSupport () { BotSupport::BotSupport () {
m_needToSendWelcome = false; m_needToSendWelcome = false;
@ -430,38 +431,45 @@ void BotSupport::syncCalculatePings () {
Twin <int, int> average { 0, 0 }; Twin <int, int> average { 0, 0 };
int numHumans = 0; int numHumans = 0;
// first get average ping on server, and store real client pings // only count player pings if we're allowed to
for (auto &client : m_clients) { if (cv_count_players_for_fakeping.bool_ ()) {
if (!(client.flags & ClientFlags::Used) || isFakeClient (client.ent)) { // first get average ping on server, and store real client pings
continue; for (auto &client : m_clients) {
if (!(client.flags & ClientFlags::Used) || isFakeClient (client.ent)) {
continue;
}
int ping, loss;
engfuncs.pfnGetPlayerStats (client.ent, &ping, &loss);
// @note: for those who asking on a email, we CAN call pfnGetPlayerStats hl-engine function in a separate thread
// since the function doesn't modify anything inside engine, so race-condition and crash isn't viable situation
// it's just fills ping and loss from engine structures, the only way to cause crash in separate thread
// is to call it with a invalid ``client`` pointer (on goldsrc), thus causing Con_Printf which is not compatible with
// multi-threaded environment
//
// see:
// https://github.com/dreamstalker/rehlds/blob/a680f18ee1e7eb8c39fbdc45682163ca9477d783/rehlds/engine/pr_cmds.cpp#L2735C15-L2735C32
// https://github.com/fwgs/xash3d-fwgs/blob/f5b9826fd9bbbdc5293c1ff522de11ce28d3c9f2/engine/server/sv_game.c#L4443
// store normal client ping
client.ping = getPingBitmask (client.ent, loss, ping > 0 ? ping : rg.get (8, 16)); // getting player ping sometimes fails
++numHumans;
average.first += ping;
average.second += loss;
} }
int ping, loss;
engfuncs.pfnGetPlayerStats (client.ent, &ping, &loss);
// @note: for those who asking on a email, we CAN call pfnGetPlayerStats hl-engine function in a separate thread if (numHumans > bots.getBotCount () / 4) {
// since the function doesn't modify anything inside engine, so race-condition and crash isn't viable situation average.first /= numHumans;
// it's just fills ping and loss from engine structures, the only way to cause crash in separate thread average.second /= numHumans;
// is to call it with a invalid ``client`` pointer (on goldsrc), thus causing Con_Printf which is not compatible with }
// multi-threaded environment else {
// average.first = rg.get (10, 20);
// see: average.second = rg.get (5, 10);
// https://github.com/dreamstalker/rehlds/blob/a680f18ee1e7eb8c39fbdc45682163ca9477d783/rehlds/engine/pr_cmds.cpp#L2735C15-L2735C32 }
// https://github.com/fwgs/xash3d-fwgs/blob/f5b9826fd9bbbdc5293c1ff522de11ce28d3c9f2/engine/server/sv_game.c#L4443
// store normal client ping
client.ping = getPingBitmask (client.ent, loss, ping > 0 ? ping : rg.get (8, 16)); // getting player ping sometimes fails
++numHumans;
average.first += ping;
average.second += loss;
}
if (numHumans > 0) {
average.first /= numHumans;
average.second /= numHumans;
} }
else { else {
average.first = rg.get (30, 40); average.first = rg.get (10, 20);
average.second = rg.get (5, 10); average.second = rg.get (5, 10);
} }
@ -484,7 +492,7 @@ void BotSupport::syncCalculatePings () {
if (botPing < 2) { if (botPing < 2) {
botPing = rg.get (10, 23); botPing = rg.get (10, 23);
} }
else if (botPing > 300) { else if (botPing > 100) {
botPing = rg.get (30, 40); botPing = rg.get (30, 40);
} }
client.ping = getPingBitmask (client.ent, botLoss, botPing); client.ping = getPingBitmask (client.ent, botLoss, botPing);