fix: android builds unable to load anything due to #498
fix: simd sse4.2 is now required for _mm_dp_ps, due to strange behavior on some cpus (ref #506) refactor: cosmetic changes all over the code linkage: do not flush linkent export table on changelevel manager: do not allow to create bots while analyzing map conifg: notify user about probably outdated configs, not just error in config file
This commit is contained in:
parent
bcb5b954cb
commit
d234a3f156
15 changed files with 91 additions and 55 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 72b32ac851400c6abb2332299d42f62b871620dd
|
Subproject commit 2265a4cc6b4b7da30a86b068382c0754399870d9
|
||||||
|
|
@ -449,6 +449,6 @@ constexpr auto kSecondaryWeaponMask = (cr::bit (Weapon::P228) | cr::bit (Weapon:
|
||||||
constexpr auto kPrimaryWeaponMinIndex = 7;
|
constexpr auto kPrimaryWeaponMinIndex = 7;
|
||||||
|
|
||||||
// grenade model names
|
// grenade model names
|
||||||
static constexpr StringRef kExplosiveModelName = "hegrenade.mdl";
|
inline constexpr StringRef kExplosiveModelName = "hegrenade.mdl";
|
||||||
static constexpr StringRef kFlashbangModelName = "flashbang.mdl";
|
inline constexpr StringRef kFlashbangModelName = "flashbang.mdl";
|
||||||
static constexpr StringRef kSmokeModelName = "smokegrenade.mdl";
|
inline constexpr StringRef kSmokeModelName = "smokegrenade.mdl";
|
||||||
|
|
|
||||||
|
|
@ -182,11 +182,6 @@ public:
|
||||||
static int CR_STDCALL closeHandler (SharedLibrary::Handle module) {
|
static int CR_STDCALL closeHandler (SharedLibrary::Handle module) {
|
||||||
return instance ().close (module);
|
return instance ().close (module);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
void flush () {
|
|
||||||
m_exports.clear ();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// expose global
|
// expose global
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ public:
|
||||||
static constexpr StringRef email { "yapb@jeefo.net" };
|
static constexpr StringRef email { "yapb@jeefo.net" };
|
||||||
static constexpr StringRef url { "https://yapb.jeefo.net/" };
|
static constexpr StringRef url { "https://yapb.jeefo.net/" };
|
||||||
static constexpr StringRef download { "yapb.jeefo.net" };
|
static constexpr StringRef download { "yapb.jeefo.net" };
|
||||||
|
static constexpr StringRef upload { "yapb.jeefo.net/upload" };
|
||||||
static constexpr StringRef logtag { "YB" };
|
static constexpr StringRef logtag { "YB" };
|
||||||
static constexpr StringRef dtime { __DATE__ " " __TIME__ };
|
static constexpr StringRef dtime { __DATE__ " " __TIME__ };
|
||||||
static constexpr StringRef date { __DATE__ };
|
static constexpr StringRef date { __DATE__ };
|
||||||
|
|
@ -53,6 +54,8 @@ public:
|
||||||
~Folders () = default;
|
~Folders () = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static constexpr StringRef bot { "yapb" };
|
||||||
|
static constexpr StringRef addons { "addons" };
|
||||||
static constexpr StringRef config { "conf" };
|
static constexpr StringRef config { "conf" };
|
||||||
static constexpr StringRef data { "data" };
|
static constexpr StringRef data { "data" };
|
||||||
static constexpr StringRef lang { "lang" };
|
static constexpr StringRef lang { "lang" };
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,10 @@ public:
|
||||||
String buildPath (int32_t type, bool isMemoryLoad = false);
|
String buildPath (int32_t type, bool isMemoryLoad = false);
|
||||||
|
|
||||||
// get's relative path against bot library (bot library should reside in bin dir)
|
// get's relative path against bot library (bot library should reside in bin dir)
|
||||||
String getRunningPath ();
|
StringRef getRunningPath ();
|
||||||
|
|
||||||
// same as above, but with valve-specific filesystem paths (loadfileforme)
|
// same as above, but with valve-specific filesystem paths (loadfileforme)
|
||||||
String getRunningPathVFS ();
|
StringRef getRunningPathVFS ();
|
||||||
|
|
||||||
// converts storage option to storage filename
|
// converts storage option to storage filename
|
||||||
int32_t storageToBotFile (int32_t options);
|
int32_t storageToBotFile (int32_t options);
|
||||||
|
|
|
||||||
|
|
@ -274,9 +274,9 @@ void GraphAnalyze::displayOverlayMessage () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
constexpr StringRef analyzeHudMesssage =
|
constexpr StringRef analyzeHudMesssage =
|
||||||
"+--------------------------------------------------------+\n"
|
"+-----------------------------------------------------------------+\n"
|
||||||
" Map analysis for bots is in progress. Please Wait.. \n"
|
" Map analysis for bots is in progress. Please Wait.. \n"
|
||||||
"+--------------------------------------------------------+\n";
|
"+-----------------------------------------------------------------+\n";
|
||||||
|
|
||||||
static hudtextparms_t textParams {};
|
static hudtextparms_t textParams {};
|
||||||
|
|
||||||
|
|
@ -346,7 +346,7 @@ void GraphAnalyze::flood (const Vector &pos, const Vector &next, float range) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAnalyze::setUpdateInterval () {
|
void GraphAnalyze::setUpdateInterval () {
|
||||||
const auto frametime (globals->frametime);
|
const auto frametime = globals->frametime;
|
||||||
|
|
||||||
if ((cv_graph_analyze_fps.float_ () + frametime) <= 1.0f / frametime) {
|
if ((cv_graph_analyze_fps.float_ () + frametime) <= 1.0f / frametime) {
|
||||||
m_updateInterval = game.time () + frametime * 0.06f;
|
m_updateInterval = game.time () + frametime * 0.06f;
|
||||||
|
|
@ -358,16 +358,16 @@ void GraphAnalyze::markGoals () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto updateNodeFlags = [] (int type, const char *entity) {
|
auto updateNodeFlags = [] (int type, StringRef classname) {
|
||||||
game.searchEntities ("classname", entity, [&] (edict_t *ent) {
|
game.searchEntities ("classname", classname, [&] (edict_t *ent) {
|
||||||
for (auto &path : graph) {
|
for (auto &path : graph) {
|
||||||
const auto &absOrigin = path.origin + Vector (1.0f, 1.0f, 1.0f);
|
const auto &bb = path.origin + Vector (1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
if (ent->v.absmin.x > absOrigin.x || ent->v.absmin.y > absOrigin.y) {
|
if (ent->v.absmin.x > bb.x || ent->v.absmin.y > bb.y) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->v.absmax.x < absOrigin.x || ent->v.absmax.y < absOrigin.y) {
|
if (ent->v.absmax.x < bb.x || ent->v.absmax.y < bb.y) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
path.flags |= type;
|
path.flags |= type;
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ bool Bot::checkBodyParts (edict_t *target) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Vector dir = (target->v.origin - pev->origin).normalize2d ();
|
Vector dir = (target->v.origin - pev->origin).normalize2d_apx ();
|
||||||
|
|
||||||
Vector perp (-dir.y, dir.x, 0.0f);
|
Vector perp (-dir.y, dir.x, 0.0f);
|
||||||
spot = target->v.origin + Vector (perp.x * kEdgeOffset, perp.y * kEdgeOffset, 0);
|
spot = target->v.origin + Vector (perp.x * kEdgeOffset, perp.y * kEdgeOffset, 0);
|
||||||
|
|
@ -675,9 +675,10 @@ bool Bot::isPenetrableObstacle (const Vector &dest) {
|
||||||
obstacleDistanceSq = tr.vecEndPos.distanceSq (source);
|
obstacleDistanceSq = tr.vecEndPos.distanceSq (source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constexpr float kMaxDistanceSq = cr::sqrf (75.0f);
|
|
||||||
|
|
||||||
if (obstacleDistanceSq > 0.0f) {
|
if (obstacleDistanceSq > 0.0f) {
|
||||||
|
constexpr float kMaxDistanceSq = cr::sqrf (75.0f);
|
||||||
|
|
||||||
while (power > 0) {
|
while (power > 0) {
|
||||||
if (obstacleDistanceSq > kMaxDistanceSq) {
|
if (obstacleDistanceSq > kMaxDistanceSq) {
|
||||||
obstacleDistanceSq -= kMaxDistanceSq;
|
obstacleDistanceSq -= kMaxDistanceSq;
|
||||||
|
|
@ -1214,6 +1215,9 @@ void Bot::attackMovement () {
|
||||||
else if (usesKnife ()) {
|
else if (usesKnife ()) {
|
||||||
m_fightStyle = Fight::Strafe;
|
m_fightStyle = Fight::Strafe;
|
||||||
}
|
}
|
||||||
|
else if (usesKnife () && isInViewCone (m_enemy->v.origin) && game.is (GameFlags::CSDM) && !isInNarrowPlace ()) {
|
||||||
|
m_fightStyle = Fight::Strafe;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
m_fightStyle = Fight::Stay;
|
m_fightStyle = Fight::Stay;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -576,12 +576,15 @@ void BotConfig::loadDifficultyConfig () {
|
||||||
// currently, mindelay, maxdelay, headprob, seenthruprob, heardthruprob, recoil, aim_error {x,y,z}
|
// currently, mindelay, maxdelay, headprob, seenthruprob, heardthruprob, recoil, aim_error {x,y,z}
|
||||||
constexpr uint32_t kMaxDifficultyValues = 9;
|
constexpr uint32_t kMaxDifficultyValues = 9;
|
||||||
|
|
||||||
|
// has errors ?
|
||||||
|
int errorCount = 0;
|
||||||
|
|
||||||
// helper for parsing each level
|
// helper for parsing each level
|
||||||
auto parseLevel = [&] (int32_t level, StringRef data) {
|
auto parseLevel = [&] (int32_t level, StringRef data) {
|
||||||
auto values = data.split <String> (",");
|
auto values = data.split <String> (",");
|
||||||
|
|
||||||
if (values.length () != kMaxDifficultyValues) {
|
if (values.length () != kMaxDifficultyValues) {
|
||||||
logger.error ("Bad value for difficulty level #%d.", level);
|
++errorCount;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto diff = &m_difficulty[level];
|
auto diff = &m_difficulty[level];
|
||||||
|
|
@ -629,6 +632,11 @@ void BotConfig::loadDifficultyConfig () {
|
||||||
parseLevel (Difficulty::Expert, items[1]);
|
parseLevel (Difficulty::Expert, items[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if some errors occurred, notify user
|
||||||
|
if (errorCount > 0) {
|
||||||
|
logger.error ("Config file: difficulty.%s has a bad syntax. Probably out of date.", kConfigExtension);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -656,6 +664,9 @@ void BotConfig::loadCustomConfig () {
|
||||||
};
|
};
|
||||||
setDefaults ();
|
setDefaults ();
|
||||||
|
|
||||||
|
// has errors ?
|
||||||
|
int errorCount = 0;
|
||||||
|
|
||||||
// custom initialization
|
// 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 ();
|
||||||
|
|
@ -672,8 +683,8 @@ void BotConfig::loadCustomConfig () {
|
||||||
auto values = line.split ("=");
|
auto values = line.split ("=");
|
||||||
|
|
||||||
if (values.length () != 2) {
|
if (values.length () != 2) {
|
||||||
logger.error ("Bad configuration for custom.%s", kConfigExtension);
|
++errorCount;
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
auto kv = Twin <String, String> (values[0].trim (), values[1].trim ());
|
auto kv = Twin <String, String> (values[0].trim (), values[1].trim ());
|
||||||
|
|
||||||
|
|
@ -681,6 +692,11 @@ void BotConfig::loadCustomConfig () {
|
||||||
m_custom[kv.first] = kv.second;
|
m_custom[kv.first] = kv.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if some errors occurred, notify user
|
||||||
|
if (errorCount > 0) {
|
||||||
|
logger.error ("Config file: custom.%s has a bad syntax. Probably out of date.", kConfigExtension);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1460,10 +1460,10 @@ int BotControl::menuGraphRadius (int item) {
|
||||||
closeMenu (); // reset menu display
|
closeMenu (); // reset menu display
|
||||||
graph.setEditFlag (GraphEdit::On); // turn graph on in case
|
graph.setEditFlag (GraphEdit::On); // turn graph on in case
|
||||||
|
|
||||||
constexpr float radius[] = { 0.0f, 8.0f, 16.0f, 32.0f, 48.0f, 64.0f, 80.0f, 96.0f, 128.0f };
|
|
||||||
|
|
||||||
if (item >= 1 && item <= 9) {
|
if (item >= 1 && item <= 9) {
|
||||||
graph.setRadius (kInvalidNodeIndex, radius[item - 1]);
|
constexpr float kRadiusValues[] = { 0.0f, 8.0f, 16.0f, 32.0f, 48.0f, 64.0f, 80.0f, 96.0f, 128.0f };
|
||||||
|
|
||||||
|
graph.setRadius (kInvalidNodeIndex, kRadiusValues[item - 1]);
|
||||||
showMenu (Menu::NodeRadius);
|
showMenu (Menu::NodeRadius);
|
||||||
}
|
}
|
||||||
return BotCommandResult::Handled;
|
return BotCommandResult::Handled;
|
||||||
|
|
@ -1642,10 +1642,10 @@ int BotControl::menuCampDirections (int item) {
|
||||||
int BotControl::menuAutoPathDistance (int item) {
|
int BotControl::menuAutoPathDistance (int item) {
|
||||||
closeMenu (); // reset menu display
|
closeMenu (); // reset menu display
|
||||||
|
|
||||||
constexpr float distances[] = { 0.0f, 100.0f, 130.0f, 160.0f, 190.0f, 220.0f, 250.0f };
|
|
||||||
|
|
||||||
if (item >= 1 && item <= 7) {
|
if (item >= 1 && item <= 7) {
|
||||||
graph.setAutoPathDistance (distances[item - 1]);
|
constexpr float kDistanceValues[] = { 0.0f, 100.0f, 130.0f, 160.0f, 190.0f, 220.0f, 250.0f };
|
||||||
|
|
||||||
|
graph.setAutoPathDistance (kDistanceValues[item - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (item) {
|
switch (item) {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
ConVar cv_graph_fixcamp ("graph_fixcamp", "0", "Specifies whether bot should not 'fix' camp directions of camp waypoints when loading old PWF format.");
|
ConVar cv_graph_fixcamp ("graph_fixcamp", "0", "Specifies whether bot should not 'fix' camp directions of camp waypoints when loading old PWF format.");
|
||||||
ConVar cv_graph_url ("graph_url", product.download.chars (), "Specifies the URL from which bots will be able to download graph in case of missing local one. Set to empty, if no downloads needed.", false, 0.0f, 0.0f);
|
ConVar cv_graph_url ("graph_url", product.download.chars (), "Specifies the URL from which bots will be able to download graph in case of missing local one. Set to empty, if no downloads needed.", false, 0.0f, 0.0f);
|
||||||
ConVar cv_graph_url_upload ("graph_url_upload", "yapb.jeefo.net/upload", "Specifies the URL to which bots will try to upload the graph file to database.", false, 0.0f, 0.0f);
|
ConVar cv_graph_url_upload ("graph_url_upload", product.upload.chars (), "Specifies the URL to which bots will try to upload the graph file to database.", false, 0.0f, 0.0f);
|
||||||
ConVar cv_graph_auto_save_count ("graph_auto_save_count", "15", "Every N graph nodes placed on map, the graph will be saved automatically (without checks).", true, 0.0f, kMaxNodes);
|
ConVar cv_graph_auto_save_count ("graph_auto_save_count", "15", "Every N graph nodes placed on map, the graph will be saved automatically (without checks).", true, 0.0f, kMaxNodes);
|
||||||
ConVar cv_graph_draw_distance ("graph_draw_distance", "400", "Maximum distance to draw graph nodes from editor viewport.", true, 64.0f, 3072.0f);
|
ConVar cv_graph_draw_distance ("graph_draw_distance", "400", "Maximum distance to draw graph nodes from editor viewport.", true, 64.0f, 3072.0f);
|
||||||
|
|
||||||
|
|
@ -1848,7 +1848,7 @@ bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination,
|
||||||
|
|
||||||
game.testLine (check, down, TraceIgnore::Monsters, m_editor, &tr);
|
game.testLine (check, down, TraceIgnore::Monsters, m_editor, &tr);
|
||||||
|
|
||||||
float height = tr.flFraction * 1000.0f; // height from ground
|
const float height = tr.flFraction * 1000.0f; // height from ground
|
||||||
|
|
||||||
// is the current height greater than the step height?
|
// is the current height greater than the step height?
|
||||||
if (height < lastHeight - maxHeight) {
|
if (height < lastHeight - maxHeight) {
|
||||||
|
|
@ -2515,8 +2515,8 @@ void BotGraph::addBasic () {
|
||||||
return EntitySearchResult::Continue;
|
return EntitySearchResult::Continue;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto autoCreateForEntity = [] (int type, const char *entity) {
|
auto autoCreateForEntity = [] (int type, StringRef classname) {
|
||||||
game.searchEntities ("classname", entity, [&] (edict_t *ent) {
|
game.searchEntities ("classname", classname, [&] (edict_t *ent) {
|
||||||
Vector pos = game.getEntityOrigin (ent);
|
Vector pos = game.getEntityOrigin (ent);
|
||||||
|
|
||||||
TraceResult tr;
|
TraceResult tr;
|
||||||
|
|
|
||||||
|
|
@ -333,9 +333,6 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int interfaceVersion) {
|
||||||
RETURN_META (MRES_IGNORED);
|
RETURN_META (MRES_IGNORED);
|
||||||
}
|
}
|
||||||
dllapi.pfnServerDeactivate ();
|
dllapi.pfnServerDeactivate ();
|
||||||
|
|
||||||
// refill export table
|
|
||||||
entlink.flush ();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
table->pfnStartFrame = [] () {
|
table->pfnStartFrame = [] () {
|
||||||
|
|
|
||||||
|
|
@ -373,6 +373,11 @@ void BotManager::maintainQuota () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (analyzer.isAnalyzing ()) {
|
||||||
|
ctrl.msg ("Can't create bot during map analysis process.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// bot's creation update
|
// bot's creation update
|
||||||
if (!m_addRequests.empty () && m_maintainTime < game.time ()) {
|
if (!m_addRequests.empty () && m_maintainTime < game.time ()) {
|
||||||
const BotRequest &request = m_addRequests.popFront ();
|
const BotRequest &request = m_addRequests.popFront ();
|
||||||
|
|
|
||||||
|
|
@ -2820,7 +2820,7 @@ bool Bot::isBlockedRight () {
|
||||||
|
|
||||||
bool Bot::checkWallOnLeft () {
|
bool Bot::checkWallOnLeft () {
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
game.testLine (pev->origin, pev->origin + -pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
|
game.testLine (pev->origin, pev->origin + -pev->angles.right () * 45.0f, TraceIgnore::Monsters, ent (), &tr);
|
||||||
|
|
||||||
// check if the trace hit something...
|
// check if the trace hit something...
|
||||||
if (tr.flFraction < 1.0f) {
|
if (tr.flFraction < 1.0f) {
|
||||||
|
|
@ -2833,7 +2833,7 @@ bool Bot::checkWallOnRight () {
|
||||||
TraceResult tr {};
|
TraceResult tr {};
|
||||||
|
|
||||||
// do a trace to the right...
|
// do a trace to the right...
|
||||||
game.testLine (pev->origin, pev->origin + pev->angles.right () * 40.0f, TraceIgnore::Monsters, ent (), &tr);
|
game.testLine (pev->origin, pev->origin + pev->angles.right () * 45.0f, TraceIgnore::Monsters, ent (), &tr);
|
||||||
|
|
||||||
// check if the trace hit something...
|
// check if the trace hit something...
|
||||||
if (tr.flFraction < 1.0f) {
|
if (tr.flFraction < 1.0f) {
|
||||||
|
|
@ -3172,7 +3172,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) {
|
||||||
srcIndex = changeNodeIndex (graph.getNearestNoBuckets (pev->origin, 256.0f));
|
srcIndex = changeNodeIndex (graph.getNearestNoBuckets (pev->origin, 256.0f));
|
||||||
|
|
||||||
if (!graph.exists (srcIndex)) {
|
if (!graph.exists (srcIndex)) {
|
||||||
printf ("%s source path index not valid (%d).", __func__, srcIndex);
|
printf ("%s source path index not valid (%d).\n", __func__, srcIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3183,7 +3183,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) {
|
||||||
destIndex = graph.random ();
|
destIndex = graph.random ();
|
||||||
|
|
||||||
if (!graph.exists (destIndex)) {
|
if (!graph.exists (destIndex)) {
|
||||||
printf ("%s dest path index not valid (%d).", __func__, destIndex);
|
printf ("%s dest path index not valid (%d).\n", __func__, destIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3191,7 +3191,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) {
|
||||||
|
|
||||||
// do not process if src points to dst
|
// do not process if src points to dst
|
||||||
if (srcIndex == destIndex) {
|
if (srcIndex == destIndex) {
|
||||||
printf ("%s source path is same as dest (%d).", __func__, destIndex);
|
printf ("%s source path is same as dest (%d).\n", __func__, destIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clearSearchNodes ();
|
clearSearchNodes ();
|
||||||
|
|
@ -3246,7 +3246,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) {
|
||||||
m_kickMeFromServer = true; // bot should be kicked within main thread, not here
|
m_kickMeFromServer = true; // bot should be kicked within main thread, not here
|
||||||
|
|
||||||
// bot should not roam when this occurs
|
// bot should not roam when this occurs
|
||||||
printf ("A* Search for bot \"%s\" failed with internal pathfinder error. Seems to be graph is broken. Bot removed (re-added).", pev->netname.chars ());
|
printf ("A* Search for bot \"%s\" failed with internal pathfinder error. Seems to be graph is broken. Bot removed (re-added).\n", pev->netname.chars ());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AStarResult::Failed:
|
case AStarResult::Failed:
|
||||||
|
|
@ -3254,7 +3254,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) {
|
||||||
findShortestPath (srcIndex, destIndex); // A* found no path, try floyd pathfinder instead
|
findShortestPath (srcIndex, destIndex); // A* found no path, try floyd pathfinder instead
|
||||||
|
|
||||||
if (cv_debug.bool_ ()) {
|
if (cv_debug.bool_ ()) {
|
||||||
printf ("A* Search for bot \"%s\" has failed. Falling back to shortest-path algorithm. Seems to be graph is broken.", pev->netname.chars ());
|
printf ("A* Search for bot \"%s\" has failed. Falling back to shortest-path algorithm. Seems to be graph is broken.\n", pev->netname.chars ());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -393,11 +393,19 @@ void BotStorage::unlinkFromDisk () {
|
||||||
graph.reset (); // re-initialize points
|
graph.reset (); // re-initialize points
|
||||||
}
|
}
|
||||||
|
|
||||||
String BotStorage::getRunningPath () {
|
StringRef BotStorage::getRunningPath () {
|
||||||
// this function get's relative path against bot library (bot library should reside in bin dir)
|
// this function get's relative path against bot library (bot library should reside in bin dir)
|
||||||
|
|
||||||
static String path;
|
static String path;
|
||||||
|
|
||||||
|
// we're do not do relative (against bot's library) paths on android
|
||||||
|
if (plat.android) {
|
||||||
|
if (path.empty ()) {
|
||||||
|
path = strings.joinPath (game.getRunningModName (), folders.addons, folders.bot);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
// compute the full path to the our folder
|
// compute the full path to the our folder
|
||||||
if (path.empty ()) {
|
if (path.empty ()) {
|
||||||
path = SharedLibrary::path (&bstor);
|
path = SharedLibrary::path (&bstor);
|
||||||
|
|
@ -415,9 +423,17 @@ String BotStorage::getRunningPath () {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
String BotStorage::getRunningPathVFS () {
|
StringRef BotStorage::getRunningPathVFS () {
|
||||||
static String path;
|
static String path;
|
||||||
|
|
||||||
|
// we're do not do relative (against bot's library) paths on android
|
||||||
|
if (plat.android) {
|
||||||
|
if (path.empty ()) {
|
||||||
|
path = strings.joinPath (folders.addons, folders.bot);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
if (path.empty ()) {
|
if (path.empty ()) {
|
||||||
path = getRunningPath ();
|
path = getRunningPath ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -270,14 +270,6 @@ void BotSupport::checkWelcome () {
|
||||||
m_welcomeReceiveTime = game.time () + 2.0f + mp_freezetime.float_ (); // receive welcome message in four seconds after game has commencing
|
m_welcomeReceiveTime = game.time () + 2.0f + mp_freezetime.float_ (); // receive welcome message in four seconds after game has commencing
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy welcome message, to respect the original code
|
|
||||||
constexpr StringRef legacyWelcomeMessage = "Welcome to POD-Bot V2.5 by Count Floyd\n"
|
|
||||||
"Visit http://www.nuclearbox.com/podbot/ or\n"
|
|
||||||
" http://www.botepidemic.com/podbot for Updates\n";
|
|
||||||
|
|
||||||
// it's should be send in very rare cases
|
|
||||||
const bool sendLegacyWelcome = rg.chance (2);
|
|
||||||
|
|
||||||
if (m_welcomeReceiveTime > 0.0f && m_welcomeReceiveTime < game.time () && needToSendMsg) {
|
if (m_welcomeReceiveTime > 0.0f && m_welcomeReceiveTime < game.time () && needToSendMsg) {
|
||||||
if (!game.is (GameFlags::Mobility | GameFlags::Xash3D)) {
|
if (!game.is (GameFlags::Mobility | GameFlags::Xash3D)) {
|
||||||
game.serverCommand ("speak \"%s\"", m_sentences.random ());
|
game.serverCommand ("speak \"%s\"", m_sentences.random ());
|
||||||
|
|
@ -287,6 +279,14 @@ void BotSupport::checkWelcome () {
|
||||||
auto graphAuthor = graph.getAuthor ();
|
auto graphAuthor = graph.getAuthor ();
|
||||||
auto graphModified = graph.getModifiedBy ();
|
auto graphModified = graph.getModifiedBy ();
|
||||||
|
|
||||||
|
// legacy welcome message, to respect the original code
|
||||||
|
constexpr StringRef legacyWelcomeMessage = "Welcome to POD-Bot V2.5 by Count Floyd\n"
|
||||||
|
"Visit http://www.nuclearbox.com/podbot/ or\n"
|
||||||
|
" http://www.botepidemic.com/podbot for Updates\n";
|
||||||
|
|
||||||
|
// it's should be send in very rare cases
|
||||||
|
const bool sendLegacyWelcome = rg.chance (2);
|
||||||
|
|
||||||
if (!graphAuthor.startsWith (product.name)) {
|
if (!graphAuthor.startsWith (product.name)) {
|
||||||
authorStr.assignf ("Navigation Graph by: %s", graphAuthor);
|
authorStr.assignf ("Navigation Graph by: %s", graphAuthor);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue