graph: reworked buckets so they can handle very large number of nodes
graph: reworked buckets so they can handle very large number of nodes aim: bots should more respect headshot allow option (needs testing) aim: incorporated never-finished changes from pr #204 nav: increased reachability timers a bit nav: ensure buckets has enough nodes before use they conf: introduced max recoil in difficulty config file bot: overall fixes to jason mode, treat knife in hands and no weapons as jason mode too bot: changed default difficulty level for bots to level 3 fix: knife attacks not working since last commit (fixes #429) fix: hostage rescue not working since last commit (fixes #427) refactor: use range loops for graph outside graph class when possible
This commit is contained in:
parent
3232c5a8b0
commit
1a650c57ce
14 changed files with 426 additions and 347 deletions
|
|
@ -451,7 +451,7 @@ int BotGraph::getFarest (const Vector &origin, float maxDistance) {
|
|||
maxDistance = cr::square (maxDistance);
|
||||
|
||||
for (const auto &path : m_paths) {
|
||||
float distance = path.origin.distanceSq (origin);
|
||||
const float distance = path.origin.distanceSq (origin);
|
||||
|
||||
if (distance > maxDistance) {
|
||||
index = path.number;
|
||||
|
|
@ -472,7 +472,7 @@ int BotGraph::getNearestNoBuckets (const Vector &origin, float minDistance, int
|
|||
if (flags != -1 && !(path.flags & flags)) {
|
||||
continue; // if flag not -1 and node has no this flag, skip node
|
||||
}
|
||||
float distance = path.origin.distanceSq (origin);
|
||||
const float distance = path.origin.distanceSq (origin);
|
||||
|
||||
if (distance < minDistance) {
|
||||
index = path.number;
|
||||
|
|
@ -492,9 +492,12 @@ int BotGraph::getEditorNearest () {
|
|||
int BotGraph::getNearest (const Vector &origin, float minDistance, int flags) {
|
||||
// find the nearest node to that origin and return the index
|
||||
|
||||
auto &bucket = getNodesInBucket (origin);
|
||||
if (minDistance > 256.0f && !cr::fequal (minDistance, kInfiniteDistance)) {
|
||||
return getNearestNoBuckets (origin, minDistance, flags);
|
||||
}
|
||||
const auto &bucket = getNodesInBucket (origin);
|
||||
|
||||
if (bucket.empty ()) {
|
||||
if (bucket.length () < kMaxNodeLinks) {
|
||||
return getNearestNoBuckets (origin, minDistance, flags);
|
||||
}
|
||||
|
||||
|
|
@ -520,17 +523,26 @@ int BotGraph::getNearest (const Vector &origin, float minDistance, int flags) {
|
|||
return index;
|
||||
}
|
||||
|
||||
IntArray BotGraph::searchRadius (float radius, const Vector &origin, int maxCount) {
|
||||
IntArray BotGraph::getNarestInRadius (float radius, const Vector &origin, int maxCount) {
|
||||
// returns all nodes within radius from position
|
||||
|
||||
radius = cr::square (radius);
|
||||
|
||||
IntArray result;
|
||||
const auto &bucket = getNodesInBucket (origin);
|
||||
|
||||
if (bucket.empty ()) {
|
||||
result.push (getNearestNoBuckets (origin, radius));
|
||||
if (bucket.length () < kMaxNodeLinks || radius > cr::square (256.0f)) {
|
||||
for (const auto &path : m_paths) {
|
||||
if (maxCount != -1 && static_cast <int> (result.length ()) > maxCount) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (origin.distanceSq (path.origin) < radius) {
|
||||
result.push (path.number);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
radius = cr::square (radius);
|
||||
|
||||
for (const auto &at : bucket) {
|
||||
if (maxCount != -1 && static_cast <int> (result.length ()) > maxCount) {
|
||||
|
|
@ -3010,24 +3022,19 @@ BotGraph::BotGraph () {
|
|||
}
|
||||
|
||||
void BotGraph::initBuckets () {
|
||||
for (int x = 0; x < kMaxBucketsInsidePos; ++x) {
|
||||
for (int y = 0; y < kMaxBucketsInsidePos; ++y) {
|
||||
for (int z = 0; z < kMaxBucketsInsidePos; ++z) {
|
||||
m_buckets[x][y][z].reserve (kMaxNodesInsideBucket);
|
||||
m_buckets[x][y][z].clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_hashTable.clear ();
|
||||
}
|
||||
|
||||
void BotGraph::addToBucket (const Vector &pos, int index) {
|
||||
const auto &bucket = locateBucket (pos);
|
||||
m_buckets[bucket.x][bucket.y][bucket.z].push (index);
|
||||
m_hashTable[locateBucket (pos)].emplace (index);
|
||||
}
|
||||
|
||||
const Array <int32_t> &BotGraph::getNodesInBucket (const Vector &pos) {
|
||||
return m_hashTable[locateBucket (pos)];
|
||||
}
|
||||
|
||||
void BotGraph::eraseFromBucket (const Vector &pos, int index) {
|
||||
const auto &bucket = locateBucket (pos);
|
||||
auto &data = m_buckets[bucket.x][bucket.y][bucket.z];
|
||||
auto &data = m_hashTable[locateBucket (pos)];
|
||||
|
||||
for (size_t i = 0; i < data.length (); ++i) {
|
||||
if (data[i] == index) {
|
||||
|
|
@ -3037,19 +3044,13 @@ void BotGraph::eraseFromBucket (const Vector &pos, int index) {
|
|||
}
|
||||
}
|
||||
|
||||
BotGraph::Bucket BotGraph::locateBucket (const Vector &pos) {
|
||||
constexpr auto size = static_cast <float> (kMaxNodes * 2);
|
||||
int BotGraph::locateBucket (const Vector &pos) {
|
||||
constexpr auto width = cr::square (kMaxNodes);
|
||||
|
||||
return {
|
||||
cr::abs (static_cast <int> ((pos.x + size) / kMaxBucketSize)),
|
||||
cr::abs (static_cast <int> ((pos.y + size) / kMaxBucketSize)),
|
||||
cr::abs (static_cast <int> ((pos.z + size) / kMaxBucketSize))
|
||||
auto hash = [&] (float axis, int32_t shift) {
|
||||
return ((static_cast <int> (axis) + width) & 0x007f80) >> shift;
|
||||
};
|
||||
}
|
||||
|
||||
const SmallArray <int32_t> &BotGraph::getNodesInBucket (const Vector &pos) {
|
||||
const auto &bucket = locateBucket (pos);
|
||||
return m_buckets[bucket.x][bucket.y][bucket.z];
|
||||
return hash (pos.x, 15) + hash (pos.y, 7);
|
||||
}
|
||||
|
||||
void BotGraph::updateGlobalPractice () {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue