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:
jeefo 2023-04-11 22:32:28 +03:00
commit 1a650c57ce
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
14 changed files with 426 additions and 347 deletions

View file

@ -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 () {