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
|
|
@ -274,9 +274,9 @@ void GraphAnalyze::displayOverlayMessage () {
|
|||
return;
|
||||
}
|
||||
constexpr StringRef analyzeHudMesssage =
|
||||
"+--------------------------------------------------------+\n"
|
||||
" Map analysis for bots is in progress. Please Wait.. \n"
|
||||
"+--------------------------------------------------------+\n";
|
||||
"+-----------------------------------------------------------------+\n"
|
||||
" Map analysis for bots is in progress. Please Wait.. \n"
|
||||
"+-----------------------------------------------------------------+\n";
|
||||
|
||||
static hudtextparms_t textParams {};
|
||||
|
||||
|
|
@ -346,7 +346,7 @@ void GraphAnalyze::flood (const Vector &pos, const Vector &next, float range) {
|
|||
}
|
||||
|
||||
void GraphAnalyze::setUpdateInterval () {
|
||||
const auto frametime (globals->frametime);
|
||||
const auto frametime = globals->frametime;
|
||||
|
||||
if ((cv_graph_analyze_fps.float_ () + frametime) <= 1.0f / frametime) {
|
||||
m_updateInterval = game.time () + frametime * 0.06f;
|
||||
|
|
@ -358,16 +358,16 @@ void GraphAnalyze::markGoals () {
|
|||
return;
|
||||
}
|
||||
|
||||
auto updateNodeFlags = [] (int type, const char *entity) {
|
||||
game.searchEntities ("classname", entity, [&] (edict_t *ent) {
|
||||
auto updateNodeFlags = [] (int type, StringRef classname) {
|
||||
game.searchEntities ("classname", classname, [&] (edict_t *ent) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
path.flags |= type;
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ bool Bot::checkBodyParts (edict_t *target) {
|
|||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
constexpr float kMaxDistanceSq = cr::sqrf (75.0f);
|
||||
|
||||
if (obstacleDistanceSq > 0.0f) {
|
||||
constexpr float kMaxDistanceSq = cr::sqrf (75.0f);
|
||||
|
||||
while (power > 0) {
|
||||
if (obstacleDistanceSq > kMaxDistanceSq) {
|
||||
obstacleDistanceSq -= kMaxDistanceSq;
|
||||
|
|
@ -1214,6 +1215,9 @@ void Bot::attackMovement () {
|
|||
else if (usesKnife ()) {
|
||||
m_fightStyle = Fight::Strafe;
|
||||
}
|
||||
else if (usesKnife () && isInViewCone (m_enemy->v.origin) && game.is (GameFlags::CSDM) && !isInNarrowPlace ()) {
|
||||
m_fightStyle = Fight::Strafe;
|
||||
}
|
||||
else {
|
||||
m_fightStyle = Fight::Stay;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -576,12 +576,15 @@ void BotConfig::loadDifficultyConfig () {
|
|||
// currently, mindelay, maxdelay, headprob, seenthruprob, heardthruprob, recoil, aim_error {x,y,z}
|
||||
constexpr uint32_t kMaxDifficultyValues = 9;
|
||||
|
||||
// has errors ?
|
||||
int errorCount = 0;
|
||||
|
||||
// helper for parsing each level
|
||||
auto parseLevel = [&] (int32_t level, StringRef data) {
|
||||
auto values = data.split <String> (",");
|
||||
|
||||
if (values.length () != kMaxDifficultyValues) {
|
||||
logger.error ("Bad value for difficulty level #%d.", level);
|
||||
++errorCount;
|
||||
return;
|
||||
}
|
||||
auto diff = &m_difficulty[level];
|
||||
|
|
@ -629,6 +632,11 @@ void BotConfig::loadDifficultyConfig () {
|
|||
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 ();
|
||||
|
||||
// has errors ?
|
||||
int errorCount = 0;
|
||||
|
||||
// custom initialization
|
||||
if (openConfig ("custom", "Custom config file not found. Loading defaults.", &file)) {
|
||||
m_custom.clear ();
|
||||
|
|
@ -672,8 +683,8 @@ void BotConfig::loadCustomConfig () {
|
|||
auto values = line.split ("=");
|
||||
|
||||
if (values.length () != 2) {
|
||||
logger.error ("Bad configuration for custom.%s", kConfigExtension);
|
||||
return;
|
||||
++errorCount;
|
||||
continue;
|
||||
}
|
||||
auto kv = Twin <String, String> (values[0].trim (), values[1].trim ());
|
||||
|
||||
|
|
@ -681,6 +692,11 @@ void BotConfig::loadCustomConfig () {
|
|||
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
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
return BotCommandResult::Handled;
|
||||
|
|
@ -1642,10 +1642,10 @@ int BotControl::menuCampDirections (int item) {
|
|||
int BotControl::menuAutoPathDistance (int item) {
|
||||
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) {
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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_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_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);
|
||||
|
||||
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?
|
||||
if (height < lastHeight - maxHeight) {
|
||||
|
|
@ -2515,8 +2515,8 @@ void BotGraph::addBasic () {
|
|||
return EntitySearchResult::Continue;
|
||||
});
|
||||
|
||||
auto autoCreateForEntity = [] (int type, const char *entity) {
|
||||
game.searchEntities ("classname", entity, [&] (edict_t *ent) {
|
||||
auto autoCreateForEntity = [] (int type, StringRef classname) {
|
||||
game.searchEntities ("classname", classname, [&] (edict_t *ent) {
|
||||
Vector pos = game.getEntityOrigin (ent);
|
||||
|
||||
TraceResult tr;
|
||||
|
|
|
|||
|
|
@ -333,9 +333,6 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int interfaceVersion) {
|
|||
RETURN_META (MRES_IGNORED);
|
||||
}
|
||||
dllapi.pfnServerDeactivate ();
|
||||
|
||||
// refill export table
|
||||
entlink.flush ();
|
||||
};
|
||||
|
||||
table->pfnStartFrame = [] () {
|
||||
|
|
|
|||
|
|
@ -373,6 +373,11 @@ void BotManager::maintainQuota () {
|
|||
return;
|
||||
}
|
||||
|
||||
if (analyzer.isAnalyzing ()) {
|
||||
ctrl.msg ("Can't create bot during map analysis process.");
|
||||
return;
|
||||
}
|
||||
|
||||
// bot's creation update
|
||||
if (!m_addRequests.empty () && m_maintainTime < game.time ()) {
|
||||
const BotRequest &request = m_addRequests.popFront ();
|
||||
|
|
|
|||
|
|
@ -2820,7 +2820,7 @@ bool Bot::isBlockedRight () {
|
|||
|
||||
bool Bot::checkWallOnLeft () {
|
||||
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...
|
||||
if (tr.flFraction < 1.0f) {
|
||||
|
|
@ -2833,7 +2833,7 @@ bool Bot::checkWallOnRight () {
|
|||
TraceResult tr {};
|
||||
|
||||
// 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...
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -3183,7 +3183,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) {
|
|||
destIndex = graph.random ();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -3191,7 +3191,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) {
|
|||
|
||||
// do not process if src points to dst
|
||||
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;
|
||||
}
|
||||
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
|
||||
|
||||
// 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;
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,11 +393,19 @@ void BotStorage::unlinkFromDisk () {
|
|||
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)
|
||||
|
||||
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
|
||||
if (path.empty ()) {
|
||||
path = SharedLibrary::path (&bstor);
|
||||
|
|
@ -415,9 +423,17 @@ String BotStorage::getRunningPath () {
|
|||
return path;
|
||||
}
|
||||
|
||||
String BotStorage::getRunningPathVFS () {
|
||||
StringRef BotStorage::getRunningPathVFS () {
|
||||
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 ()) {
|
||||
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
|
||||
}
|
||||
|
||||
// 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 (!game.is (GameFlags::Mobility | GameFlags::Xash3D)) {
|
||||
game.serverCommand ("speak \"%s\"", m_sentences.random ());
|
||||
|
|
@ -287,6 +279,14 @@ void BotSupport::checkWelcome () {
|
|||
auto graphAuthor = graph.getAuthor ();
|
||||
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)) {
|
||||
authorStr.assignf ("Navigation Graph by: %s", graphAuthor);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue