backport: nodes flooder (analyzer) from cs-ebot
analyze: allow to disable goal marking analyze: add cvars descriptions and bounds nav: added optional post path smoothing for astar algorithm nav: now bots will use Dijkstra algo instead of floyd-warshall if memory usage too high (controlled via yb_path_floyd_memory_limit cvar) (fixes #434) nav: vistable are now calculated every frame to prevent game-freeze during loading the game (fixes #434) graph: pracrice reworked to hash table so memory footprint is as low as possible (at cost 5-10% performance loss on practice) (fixes #434) control: bots commands now is case-insensitive bot: major refactoring of bot's code nav: issue warnings about path fail only with debug practice: check for visibility when updating danger index analyzer: suspend any analyzing on change level control: add kickall_ct/kickall_t nav: increase blocked distance in stuck check
This commit is contained in:
parent
bb2e93a539
commit
e7712a551a
31 changed files with 3114 additions and 1722 deletions
236
inc/graph.h
236
inc/graph.h
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
constexpr int kMaxNodes = 4096; // max nodes per graph
|
||||
constexpr int kMaxNodeLinks = 8; // max links for single node
|
||||
|
||||
// defines for nodes flags field (32 bits are available)
|
||||
CR_DECLARE_SCOPED_ENUM (NodeFlag,
|
||||
Lift = cr::bit (1), // wait for lift to be down before approaching this node
|
||||
|
|
@ -43,13 +46,6 @@ CR_DECLARE_SCOPED_ENUM (PathConnection,
|
|||
Bidirectional
|
||||
)
|
||||
|
||||
// a* route state
|
||||
CR_DECLARE_SCOPED_ENUM (RouteState,
|
||||
Open = 0,
|
||||
Closed,
|
||||
New
|
||||
)
|
||||
|
||||
// node edit states
|
||||
CR_DECLARE_SCOPED_ENUM (GraphEdit,
|
||||
On = cr::bit (1),
|
||||
|
|
@ -57,26 +53,6 @@ CR_DECLARE_SCOPED_ENUM (GraphEdit,
|
|||
Auto = cr::bit (3)
|
||||
)
|
||||
|
||||
// storage header options
|
||||
CR_DECLARE_SCOPED_ENUM (StorageOption,
|
||||
Practice = cr::bit (0), // this is practice (experience) file
|
||||
Matrix = cr::bit (1), // this is floyd warshal path & distance matrix
|
||||
Vistable = cr::bit (2), // this is vistable data
|
||||
Graph = cr::bit (3), // this is a node graph data
|
||||
Official = cr::bit (4), // this is additional flag for graph indicates graph are official
|
||||
Recovered = cr::bit (5), // this is additional flag indicates graph converted from podbot and was bad
|
||||
Exten = cr::bit (6) // this is additional flag indicates that there's extension info
|
||||
)
|
||||
|
||||
// storage header versions
|
||||
CR_DECLARE_SCOPED_ENUM (StorageVersion,
|
||||
Graph = 2,
|
||||
Practice = 1,
|
||||
Vistable = 2,
|
||||
Matrix = 1,
|
||||
Podbot = 7
|
||||
)
|
||||
|
||||
// lift usage states
|
||||
CR_DECLARE_SCOPED_ENUM (LiftState,
|
||||
None = 0,
|
||||
|
|
@ -103,29 +79,13 @@ CR_DECLARE_SCOPED_ENUM (NodeAddFlag,
|
|||
Goal = 100
|
||||
)
|
||||
|
||||
// a* route
|
||||
struct Route {
|
||||
float g, f;
|
||||
int parent;
|
||||
RouteState state;
|
||||
};
|
||||
CR_DECLARE_SCOPED_ENUM (NotifySound,
|
||||
Done = 0,
|
||||
Change = 1,
|
||||
Added = 2
|
||||
)
|
||||
|
||||
// general stprage header information structure
|
||||
struct StorageHeader {
|
||||
int32_t magic;
|
||||
int32_t version;
|
||||
int32_t options;
|
||||
int32_t length;
|
||||
int32_t compressed;
|
||||
int32_t uncompressed;
|
||||
};
|
||||
|
||||
// extension header for graph information
|
||||
struct ExtenHeader {
|
||||
char author[32]; // original author of graph
|
||||
int32_t mapSize; // bsp size for checksumming map consistency
|
||||
char modified[32]; // by whom modified
|
||||
};
|
||||
#include <vistable.h>
|
||||
|
||||
// general waypoint header information structure
|
||||
struct PODGraphHeader {
|
||||
|
|
@ -136,19 +96,6 @@ struct PODGraphHeader {
|
|||
char author[32];
|
||||
};
|
||||
|
||||
// floyd-warshall matrices
|
||||
struct Matrix {
|
||||
int16_t dist;
|
||||
int16_t index;
|
||||
};
|
||||
|
||||
// experience data hold in memory while playing
|
||||
struct Practice {
|
||||
int16_t damage[kGameTeamNum];
|
||||
int16_t index[kGameTeamNum];
|
||||
int16_t value[kGameTeamNum];
|
||||
};
|
||||
|
||||
// defines linked waypoints
|
||||
struct PathLink {
|
||||
Vector velocity;
|
||||
|
|
@ -157,11 +104,6 @@ struct PathLink {
|
|||
int16_t index;
|
||||
};
|
||||
|
||||
// defines visibility count
|
||||
struct PathVis {
|
||||
uint16_t stand, crouch;
|
||||
};
|
||||
|
||||
// define graph path structure for yapb
|
||||
struct Path {
|
||||
int32_t number, flags;
|
||||
|
|
@ -183,74 +125,21 @@ struct PODPath {
|
|||
PathVis vis;
|
||||
};
|
||||
|
||||
// this structure links nodes returned from pathfinder
|
||||
class PathWalk final : public DenyCopying {
|
||||
private:
|
||||
size_t m_cursor {};
|
||||
size_t m_length {};
|
||||
// general stprage header information structure
|
||||
struct StorageHeader {
|
||||
int32_t magic;
|
||||
int32_t version;
|
||||
int32_t options;
|
||||
int32_t length;
|
||||
int32_t compressed;
|
||||
int32_t uncompressed;
|
||||
};
|
||||
|
||||
UniquePtr <int32_t[]> m_path {};
|
||||
|
||||
public:
|
||||
explicit PathWalk () = default;
|
||||
~PathWalk () = default;
|
||||
|
||||
public:
|
||||
int32_t &next () {
|
||||
return at (1);
|
||||
}
|
||||
|
||||
int32_t &first () {
|
||||
return at (0);
|
||||
}
|
||||
|
||||
int32_t &last () {
|
||||
return at (length () - 1);
|
||||
}
|
||||
|
||||
int32_t &at (size_t index) {
|
||||
return m_path[m_cursor + index];
|
||||
}
|
||||
|
||||
void shift () {
|
||||
++m_cursor;
|
||||
}
|
||||
|
||||
void reverse () {
|
||||
for (size_t i = 0; i < m_length / 2; ++i) {
|
||||
cr::swap (m_path[i], m_path[m_length - 1 - i]);
|
||||
}
|
||||
}
|
||||
|
||||
size_t length () const {
|
||||
if (m_cursor >= m_length) {
|
||||
return 0;
|
||||
}
|
||||
return m_length - m_cursor;
|
||||
}
|
||||
|
||||
bool hasNext () const {
|
||||
return length () > m_cursor;
|
||||
}
|
||||
|
||||
bool empty () const {
|
||||
return !length ();
|
||||
}
|
||||
|
||||
void add (int32_t node) {
|
||||
m_path[m_length++] = node;
|
||||
}
|
||||
|
||||
void clear () {
|
||||
m_cursor = 0;
|
||||
m_length = 0;
|
||||
|
||||
m_path[0] = 0;
|
||||
}
|
||||
|
||||
void init (size_t length) {
|
||||
m_path = cr::makeUnique <int32_t []> (length);
|
||||
}
|
||||
// extension header for graph information
|
||||
struct ExtenHeader {
|
||||
char author[32]; // original author of graph
|
||||
int32_t mapSize; // bsp size for checksumming map consistency
|
||||
char modified[32]; // by whom modified
|
||||
};
|
||||
|
||||
// graph operation class
|
||||
|
|
@ -260,7 +149,6 @@ public:
|
|||
|
||||
private:
|
||||
int m_editFlags {};
|
||||
int m_loadAttempts {};
|
||||
int m_cacheNodeIndex {};
|
||||
int m_lastJumpNode {};
|
||||
int m_findWPIndex {};
|
||||
|
|
@ -277,8 +165,8 @@ private:
|
|||
bool m_endJumpPoint {};
|
||||
bool m_jumpLearnNode {};
|
||||
bool m_hasChanged {};
|
||||
bool m_needsVisRebuild {};
|
||||
bool m_narrowChecked {};
|
||||
bool m_silenceMessages {};
|
||||
|
||||
Vector m_learnVelocity {};
|
||||
Vector m_learnPosition {};
|
||||
|
|
@ -293,11 +181,8 @@ private:
|
|||
IntArray m_rescuePoints {};
|
||||
IntArray m_visitedGoals {};
|
||||
|
||||
SmallArray <Matrix> m_matrix {};
|
||||
SmallArray <Practice> m_practice {};
|
||||
public:
|
||||
SmallArray <Path> m_paths {};
|
||||
SmallArray <uint8_t> m_vistable {};
|
||||
|
||||
HashMap <int32_t, Array <int32_t>, EmptyHash <int32_t>> m_hashTable;
|
||||
|
||||
String m_graphAuthor {};
|
||||
|
|
@ -315,13 +200,10 @@ public:
|
|||
public:
|
||||
int getFacingIndex ();
|
||||
int getFarest (const Vector &origin, float maxDistance = 32.0);
|
||||
int getForAnalyzer (const Vector &origin, float maxDistance);
|
||||
int getNearest (const Vector &origin, float minDistance = kInfiniteDistance, int flags = -1);
|
||||
int getNearestNoBuckets (const Vector &origin, float minDistance = kInfiniteDistance, int flags = -1);
|
||||
int getEditorNearest ();
|
||||
int getDangerIndex (int team, int start, int goal);
|
||||
int getDangerValue (int team, int start, int goal);
|
||||
int getDangerDamage (int team, int start, int goal);
|
||||
int getPathDist (int srcIndex, int destIndex);
|
||||
int clearConnections (int index);
|
||||
int getBspSize ();
|
||||
int locateBucket (const Vector &pos);
|
||||
|
|
@ -329,30 +211,23 @@ public:
|
|||
float calculateTravelTime (float maxSpeed, const Vector &src, const Vector &origin);
|
||||
|
||||
bool convertOldFormat ();
|
||||
bool isVisible (int srcIndex, int destIndex);
|
||||
bool isStandVisible (int srcIndex, int destIndex);
|
||||
bool isDuckVisible (int srcIndex, int destIndex);
|
||||
bool isConnected (int a, int b);
|
||||
bool isConnected (int index);
|
||||
bool isNodeReacheableEx (const Vector &src, const Vector &destination, const float maxHeight);
|
||||
bool isNodeReacheable (const Vector &src, const Vector &destination);
|
||||
bool isNodeReacheableWithJump (const Vector &src, const Vector &destination);
|
||||
bool checkNodes (bool teleportPlayer);
|
||||
bool loadPathMatrix ();
|
||||
bool isVisited (int index);
|
||||
bool isAnalyzed () const;
|
||||
|
||||
bool saveGraphData ();
|
||||
bool loadGraphData ();
|
||||
bool canDownload ();
|
||||
|
||||
template <typename U> bool saveStorage (StringRef name, StorageOption options, StorageVersion version, const SmallArray <U> &data, ExtenHeader *exten);
|
||||
template <typename U> bool loadStorage (StringRef name, StorageOption options, StorageVersion version, SmallArray <U> &data, ExtenHeader *exten, int32_t *outOptions);
|
||||
template <typename ...Args> bool raiseLoadingError (bool isGraph, bool isDebug, MemFile &file, const char *fmt, Args &&...args);
|
||||
|
||||
void saveOldFormat ();
|
||||
void reset ();
|
||||
void frame ();
|
||||
void loadPractice ();
|
||||
void loadVisibility ();
|
||||
void initNodesTypes ();
|
||||
void populateNodes ();
|
||||
void initLightLevels ();
|
||||
void initNarrowPlaces ();
|
||||
void addPath (int addIndex, int pathIndex, float distance);
|
||||
|
|
@ -360,16 +235,11 @@ public:
|
|||
void erase (int target);
|
||||
void toggleFlags (int toggleFlag);
|
||||
void setRadius (int index, float radius);
|
||||
void rebuildVisibility ();
|
||||
void pathCreate (char dir);
|
||||
void erasePath ();
|
||||
void cachePoint (int index);
|
||||
void calculatePathRadius (int index);
|
||||
void savePractice ();
|
||||
void saveVisibility ();
|
||||
void addBasic ();
|
||||
void eraseFromDisk ();
|
||||
void savePathMatrix ();
|
||||
void setSearchIndex (int index);
|
||||
void startLearnJump ();
|
||||
void setVisited (int index);
|
||||
|
|
@ -378,16 +248,14 @@ public:
|
|||
void addToBucket (const Vector &pos, int index);
|
||||
void eraseFromBucket (const Vector &pos, int index);
|
||||
void setBombOrigin (bool reset = false, const Vector &pos = nullptr);
|
||||
void updateGlobalPractice ();
|
||||
void unassignPath (int from, int to);
|
||||
void setDangerValue (int team, int start, int goal, int value);
|
||||
void setDangerDamage (int team, int start, int goal, int value);
|
||||
void convertFromPOD (Path &path, const PODPath &pod);
|
||||
void convertToPOD (const Path &path, PODPath &pod);
|
||||
void convertCampDirection (Path &path);
|
||||
void setAutoPathDistance (const float distance);
|
||||
void showStats ();
|
||||
void showFileInfo ();
|
||||
void emitNotify (int32_t sound);
|
||||
|
||||
IntArray getNarestInRadius (float radius, const Vector &origin, int maxCount = -1);
|
||||
const IntArray &getNodesInBucket (const Vector &pos);
|
||||
|
|
@ -463,6 +331,25 @@ public:
|
|||
return m_editor;
|
||||
}
|
||||
|
||||
// slicence all graph messages or not
|
||||
void setMessageSilence (bool enable) {
|
||||
m_silenceMessages = enable;
|
||||
}
|
||||
|
||||
// set exten header from binary storage
|
||||
void setExtenHeader (ExtenHeader *hdr) {
|
||||
memcpy (&m_extenHeader, hdr, sizeof (ExtenHeader));
|
||||
}
|
||||
|
||||
// set graph header from binary storage
|
||||
void setGraphHeader (StorageHeader *hdr) {
|
||||
memcpy (&m_graphHeader, hdr, sizeof (StorageHeader));
|
||||
}
|
||||
|
||||
public:
|
||||
// graph heloer for sending message to correct channel
|
||||
template <typename ...Args> void msg (const char *fmt, Args &&...args);
|
||||
|
||||
public:
|
||||
Path *begin () {
|
||||
return m_paths.begin ();
|
||||
|
|
@ -481,29 +368,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// we're need `bots`
|
||||
#include <manager.h>
|
||||
|
||||
// helper for reporting load errors
|
||||
template <typename ...Args> bool BotGraph::raiseLoadingError (bool isGraph, bool isDebug, MemFile &file, const char *fmt, Args &&...args) {
|
||||
auto result = strings.format (fmt, cr::forward <Args> (args)...);
|
||||
|
||||
// display error only for graph file
|
||||
if (isGraph || isDebug) {
|
||||
logger.error (result);
|
||||
}
|
||||
|
||||
// if graph reset paths
|
||||
if (isGraph) {
|
||||
bots.kickEveryone (true);
|
||||
|
||||
m_graphAuthor = result;
|
||||
m_paths.clear ();
|
||||
}
|
||||
file.close ();
|
||||
|
||||
return false;
|
||||
}
|
||||
#include <practice.h>
|
||||
|
||||
// explose global
|
||||
CR_EXPOSE_GLOBAL_SINGLETON (BotGraph, graph);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue