nav: do not avoid anyone in narrow places

nav: increase recent-probe repeat time
bot: allow to camp with secondary weapon if enough friends alive
bot:  think runs now at minimum 50fps, instead of every frame on xash3d
bot: make multilingual system work on xash3d (except menus right now)
engine: mark xash3d engine as modern game version
engine: add xash3d-specific cvars that are not  registered on goldsrc
cfg: do not spam on logs if multilingual or chatter configs not loaded because of game version
This commit is contained in:
jeefo 2023-06-13 19:55:03 +03:00
commit 690d09a5d7
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
9 changed files with 39 additions and 22 deletions

View file

@ -28,7 +28,8 @@ CR_DECLARE_SCOPED_ENUM (Var,
ReadOnly, ReadOnly,
Password, Password,
NoServer, NoServer,
GameRef GameRef,
Xash3D // registrable only on xash3d engine
) )
// supported cs's // supported cs's

View file

@ -1124,7 +1124,7 @@ void Bot::buyStuff () {
const bool teamHasGoodEconomics = bots.checkTeamEco (m_team); const bool teamHasGoodEconomics = bots.checkTeamEco (m_team);
// do this, because xash engine is not capable to run all the features goldsrc, but we have cs 1.6 on it, so buy table must be the same // do this, because xash engine is not capable to run all the features goldsrc, but we have cs 1.6 on it, so buy table must be the same
const bool isOldGame = game.is (GameFlags::Legacy) && !game.is (GameFlags::Xash3D); const bool isOldGame = game.is (GameFlags::Legacy);
const bool hasDefaultPistols = (pev->weapons & (cr::bit (Weapon::USP) | cr::bit (Weapon::Glock18))); const bool hasDefaultPistols = (pev->weapons & (cr::bit (Weapon::USP) | cr::bit (Weapon::Glock18)));
const bool isFirstRound = m_moneyAmount == mp_startmoney.int_ (); const bool isFirstRound = m_moneyAmount == mp_startmoney.int_ ();

View file

@ -33,7 +33,7 @@ void BotConfig::loadConfigs () {
} }
void BotConfig::loadMainConfig (bool isFirstLoad) { void BotConfig::loadMainConfig (bool isFirstLoad) {
if (game.is (GameFlags::Legacy) && !game.is (GameFlags::Xash3D)) { if (game.is (GameFlags::Legacy)) {
util.setNeedForWelcome (true); util.setNeedForWelcome (true);
} }
setupMemoryFiles (); setupMemoryFiles ();
@ -357,7 +357,7 @@ void BotConfig::loadChatterConfig () {
} }
else { else {
cv_radio_mode.set (1); cv_radio_mode.set (1);
logger.message ("Bots chatter communication disabled."); game.print ("Bots chatter communication disabled.");
} }
} }
@ -464,13 +464,12 @@ void BotConfig::loadLanguageConfig () {
setupMemoryFiles (); setupMemoryFiles ();
if (game.is (GameFlags::Legacy)) { if (game.is (GameFlags::Legacy)) {
logger.message ("Bots multilingual system disabled."); return; // legacy versions will use only english translation
return; // dedicated server will use only english translation
} }
String line; String line;
MemFile file; MemFile file;
// localizer inititalization // localizer initialization
if (openConfig ("lang", "Specified language not found.", &file, true)) { if (openConfig ("lang", "Specified language not found.", &file, true)) {
String temp; String temp;
Twin <String, String> lang; Twin <String, String> lang;
@ -509,14 +508,14 @@ void BotConfig::loadLanguageConfig () {
void BotConfig::loadAvatarsConfig () { void BotConfig::loadAvatarsConfig () {
setupMemoryFiles (); setupMemoryFiles ();
if (game.is (GameFlags::Legacy)) { if (game.is (GameFlags::Legacy) || game.is (GameFlags::Xash3D)) {
return; return;
} }
String line; String line;
MemFile file; MemFile file;
// avatars inititalization // avatars initialization
if (openConfig ("avatars", "Avatars config file not found. Avatars will not be displayed.", &file)) { if (openConfig ("avatars", "Avatars config file not found. Avatars will not be displayed.", &file)) {
m_avatars.clear (); m_avatars.clear ();
@ -580,7 +579,7 @@ void BotConfig::loadDifficultyConfig () {
diff->aimError.z = values[8].float_ (); diff->aimError.z = values[8].float_ ();
}; };
// avatars inititalization // avatars initialization
if (openConfig ("difficulty", "Difficulty config file not found. Loading defaults.", &file)) { if (openConfig ("difficulty", "Difficulty config file not found. Loading defaults.", &file)) {
while (file.getLine (line)) { while (file.getLine (line)) {
@ -633,7 +632,7 @@ void BotConfig::loadCustomConfig () {
m_custom["C4ModelName"] = "c4.mdl"; m_custom["C4ModelName"] = "c4.mdl";
m_custom["AMXParachuteCvar"] = "sv_parachute"; m_custom["AMXParachuteCvar"] = "sv_parachute";
// custom inititalization // custom initialization
if (openConfig ("custom", "Custom config file not found. Loading defaults.", &file)) { if (openConfig ("custom", "Custom config file not found. Loading defaults.", &file)) {
m_custom.clear (); m_custom.clear ();
@ -664,7 +663,7 @@ void BotConfig::loadLogosConfig () {
String line; String line;
MemFile file; MemFile file;
// logos inititalization // logos initialization
if (openConfig ("logos", "Logos config file not found. Loading defaults.", &file)) { if (openConfig ("logos", "Logos config file not found. Loading defaults.", &file)) {
m_logos.clear (); m_logos.clear ();

View file

@ -7,7 +7,7 @@
#include <yapb.h> #include <yapb.h>
ConVar cv_display_menu_text ("yb_display_menu_text", "1", "Enables or disables display menu text, when players asks for menu. Useful only for Android."); ConVar cv_display_menu_text ("yb_display_menu_text", "1", "Enables or disables display menu text, when players asks for menu. Useful only for Android.", false, 0.0f, 1.0f, Var::Xash3D);
ConVar cv_password ("yb_password", "", "The value (password) for the setinfo key, if user sets correct password, he's gains access to bot commands and menus.", false, 0.0f, 0.0f, Var::Password); ConVar cv_password ("yb_password", "", "The value (password) for the setinfo key, if user sets correct password, he's gains access to bot commands and menus.", false, 0.0f, 0.0f, Var::Password);
ConVar cv_password_key ("yb_password_key", "_ybpw", "The name of setinfo key used to store password to bot commands and menus.", false); ConVar cv_password_key ("yb_password_key", "_ybpw", "The name of setinfo key used to store password to bot commands and menus.", false);
@ -1872,6 +1872,11 @@ bool BotControl::executeMenus () {
void BotControl::showMenu (int id) { void BotControl::showMenu (int id) {
static bool menusParsed = false; static bool menusParsed = false;
// xash doesn't show anything useful when menus translated by now, so disable translation for menus on xash3d
if (game.is (GameFlags::Xash3D)) {
menusParsed = true;
}
// make menus looks like we need only once // make menus looks like we need only once
if (!menusParsed) { if (!menusParsed) {
m_ignoreTranslate = false; // always translate menus m_ignoreTranslate = false; // always translate menus

View file

@ -722,6 +722,9 @@ void Game::registerCvars (bool gameVars) {
cvar_t &reg = var.reg; cvar_t &reg = var.reg;
if (var.type != Var::GameRef) { if (var.type != Var::GameRef) {
if (var.type == Var::Xash3D && !is (GameFlags::Xash3D)) {
continue;
}
self.ptr = engfuncs.pfnCVarGetPointer (reg.name); self.ptr = engfuncs.pfnCVarGetPointer (reg.name);
if (!self.ptr) { if (!self.ptr) {
@ -751,7 +754,7 @@ void Game::registerCvars (bool gameVars) {
} }
if (!self.ptr) { if (!self.ptr) {
print ("Got nullptr on cvar %s!", reg.name); logger.error ("Got nullptr on cvar %s!", reg.name);
} }
} }
} }
@ -818,7 +821,7 @@ bool Game::loadCSBinary () {
// detect xash engine // detect xash engine
if (engfuncs.pfnCVarGetPointer ("host_ver") != nullptr) { if (engfuncs.pfnCVarGetPointer ("host_ver") != nullptr) {
m_gameFlags |= (GameFlags::Legacy | GameFlags::Xash3D); m_gameFlags |= (GameFlags::Modern | GameFlags::Xash3D);
if (entity != nullptr) { if (entity != nullptr) {
m_gameFlags |= GameFlags::HasBotVoice; m_gameFlags |= GameFlags::HasBotVoice;
@ -835,6 +838,9 @@ bool Game::loadCSBinary () {
} }
else { else {
m_gameFlags |= GameFlags::Legacy; m_gameFlags |= GameFlags::Legacy;
// clear modern flag just in case
m_gameFlags &= ~GameFlags::Modern;
} }
if (is (GameFlags::Metamod)) { if (is (GameFlags::Metamod)) {
@ -874,7 +880,7 @@ bool Game::postload () {
plat.setAppName (product.name.chars ()); plat.setAppName (product.name.chars ());
// register bot cvars // register bot cvars
game.registerCvars (); registerCvars ();
// handle prefixes // handle prefixes
static StringArray prefixes = { product.cmdPri, product.cmdSec }; static StringArray prefixes = { product.cmdPri, product.cmdSec };
@ -1273,7 +1279,7 @@ template <typename S, typename M> bool LightMeasure::recursiveLightPoint (const
} }
float LightMeasure::getLightLevel (const Vector &point) { float LightMeasure::getLightLevel (const Vector &point) {
if (game.is (GameFlags::Legacy) && !game.is (GameFlags::Xash3D)) { if (game.is (GameFlags::Legacy)) {
return 0.0f; return 0.0f;
} }

View file

@ -1493,7 +1493,12 @@ void Bot::newRound () {
if (rg.chance (50)) { if (rg.chance (50)) {
pushChatterMessage (Chatter::NewRound); pushChatterMessage (Chatter::NewRound);
} }
m_updateInterval = game.is (GameFlags::Legacy | GameFlags::Xash3D) ? 0.0f : (1.0f / cr::clamp (cv_think_fps.float_ (), 30.0f, 60.0f)); auto interval = cr::clamp (cv_think_fps.float_ (), 24.0f, 90.0f);
if (game.is (GameFlags::Xash3D) && interval < 50.0f) {
interval = 50.0f; // xash works acceptable at 50fps
}
m_updateInterval = game.is (GameFlags::Legacy) ? 0.0f : 1.0f / interval;
} }
void Bot::resetPathSearchType () { void Bot::resetPathSearchType () {

View file

@ -368,7 +368,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
m_hindrance = nullptr; m_hindrance = nullptr;
float distance = cr::sqrf (348.0f); float distance = cr::sqrf (348.0f);
if (getCurrentTaskId () == Task::Attack || isOnLadder ()) { if (getCurrentTaskId () == Task::Attack || isOnLadder () || isInNarrowPlace ()) {
return; return;
} }
const auto ownPrio = bots.getPlayerPriority (ent ()); const auto ownPrio = bots.getPlayerPriority (ent ());
@ -477,7 +477,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
// not stuck? // not stuck?
if (!m_isStuck) { if (!m_isStuck) {
if (m_probeTime + rg.get (0.5f, 1.0f) < game.time ()) { if (m_probeTime + rg.get (0.75f, 1.15f) < game.time ()) {
resetCollision (); // reset collision memory if not being stuck for 0.5 secs resetCollision (); // reset collision memory if not being stuck for 0.5 secs
} }
else { else {

View file

@ -496,7 +496,7 @@ void BotSupport::installSendTo () {
m_sendToDetour.initialize ("ws2_32.dll", "sendto", sendToAddress); m_sendToDetour.initialize ("ws2_32.dll", "sendto", sendToAddress);
// enable only on modern games // enable only on modern games
if ((game.is (GameFlags::Modern) || game.is (GameFlags::Xash3D)) && (plat.nix || plat.win) && !plat.arm && !m_sendToDetour.detoured ()) { if (!game.is (GameFlags::Legacy) && (plat.nix || plat.win) && !plat.arm && !m_sendToDetour.detoured ()) {
m_sendToDetour.install (reinterpret_cast <void *> (BotSupport::sendTo), true); m_sendToDetour.install (reinterpret_cast <void *> (BotSupport::sendTo), true);
} }
} }

View file

@ -67,9 +67,10 @@ void Bot::normal_ () {
// reached node is a camp node // reached node is a camp node
if ((m_pathFlags & NodeFlag::Camp) && !game.is (GameFlags::CSDM) && cv_camping_allowed.bool_ () && !isKnifeMode ()) { if ((m_pathFlags & NodeFlag::Camp) && !game.is (GameFlags::CSDM) && cv_camping_allowed.bool_ () && !isKnifeMode ()) {
const bool allowedCampWeapon = hasPrimaryWeapon () || (hasSecondaryWeapon () && m_numFriendsLeft > game.maxClients () / 4);
// check if bot has got a primary weapon and hasn't camped before // check if bot has got a primary weapon and hasn't camped before
if (hasPrimaryWeapon () && m_timeCamping + 10.0f < game.time () && !m_hasHostage) { if (allowedCampWeapon && m_timeCamping + 10.0f < game.time () && !m_hasHostage) {
bool campingAllowed = true; bool campingAllowed = true;
// Check if it's not allowed for this team to camp here // Check if it's not allowed for this team to camp here