fix: crash on predicted node index use after wiped

refactor: reworked prediction to calc prediction for all bots at one job, instead of firing it for every bot
This commit is contained in:
jeefo 2023-06-29 20:17:46 +03:00
commit 93d9187f6d
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
12 changed files with 205 additions and 182 deletions

View file

@ -404,17 +404,6 @@ CR_DECLARE_SCOPED_ENUM (GoalTactic,
RescueHostage
)
// frustum sides
CR_DECLARE_SCOPED_ENUM (FrustumSide,
Top = 0,
Bottom,
Left,
Right,
Near,
Far,
Num
)
// some hard-coded desire defines used to override calculated ones
namespace TaskPri {
constexpr auto Normal { 35.0f };

View file

@ -17,36 +17,6 @@ struct BotRequest {
String name;
};
// initial frustum data
struct FrustumData : public Singleton <FrustumData> {
private:
float Fov = 75.0f;
float AspectRatio = 1.33333f;
public:
float MaxView = 4096.0f;
float MinView = 2.0f;
public:
float farHeight; // height of the far frustum
float farWidth; // width of the far frustum
float nearHeight; // height of the near frustum
float nearWidth; // width of the near frustum
public:
FrustumData () {
nearHeight = 2.0f * cr::tanf (Fov * 0.0174532925f * 0.5f) * MinView;
nearWidth = nearHeight * AspectRatio;
farHeight = 2.0f * cr::tanf (Fov * 0.0174532925f * 0.5f) * MaxView;
farWidth = farHeight * AspectRatio;
}
};
// declare global frustum data
CR_EXPOSE_GLOBAL_SINGLETON (FrustumData, frustum);
// manager class
class BotManager final : public Singleton <BotManager> {
public:
@ -68,6 +38,7 @@ private:
float m_lastChatTime {}; // global chat time timestamp
float m_timeBombPlanted {}; // time the bomb were planted
float m_lastRadioTime[kGameTeamNum] {}; // global radio time
float m_predictUpdateTime {}; // time to update prediction entity
int m_lastWinner {}; // the team who won previous round
int m_lastDifficulty {}; // last bots difficulty
@ -89,7 +60,6 @@ private:
SmallArray <UniqueBot> m_bots {}; // all available bots
edict_t *m_killerEntity {}; // killer entity for bots
FrustumData m_frustumData {};
protected:
BotCreateResult create (StringRef name, int difficulty, int personality, int team, int skin);
@ -152,6 +122,8 @@ public:
void handleDeath (edict_t *killer, edict_t *victim);
void setLastWinner (int winner);
void checkBotModel (edict_t *ent, char *infobuffer);
void syncUpdateBotsPredict ();
void updateBotsPredict ();
bool isTeamStacked (int team);
bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned);
@ -318,12 +290,17 @@ public:
public:
template <typename F> void enqueue (F &&fn) {
if (m_botWorker.threadCount () == 0) {
if (!available ()) {
fn (); // no threads, no fun, just run task in current thread
return;
}
m_botWorker.enqueue (cr::move (fn));
}
public:
bool available () {
return m_botWorker.threadCount () > 0;
}
};
// expose global

View file

@ -99,9 +99,6 @@ public:
// installs the sendto function interception
void installSendTo ();
// check if object inside frustum plane
bool isObjectInsidePlane (FrustumPlane &plane, const Vector &center, float height, float radius);
// checks if same model omitting the models directory
bool isModel (const edict_t *ent, StringRef model);

65
inc/vision.h Normal file
View file

@ -0,0 +1,65 @@
//
// YaPB, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright © YaPB Project Developers <yapb@jeefo.net>.
//
// SPDX-License-Identifier: MIT
//
#pragma once
// view frustum for bots
class Frustum : public Singleton <Frustum> {
public:
struct Plane {
Vector normal {};
Vector point {};
float result {};
};
enum class PlaneSide : int {
Top = 0,
Bottom,
Left,
Right,
Near,
Far,
Num
};
public:
using Planes = Plane[static_cast <int> (PlaneSide::Num)];
private:
static constexpr float kFov = 75.0f;
static constexpr float kAspectRatio = 16.0f / 9.0f;
static constexpr float kMaxViewDistance = 4096.0f;
static constexpr float kMinViewDistance = 2.0f;
private:
float m_farHeight; // height of the far frustum
float m_farWidth; // width of the far frustum
float m_nearHeight; // height of the near frustum
float m_nearWidth; // width of the near frustum
public:
explicit Frustum () {
m_nearHeight = 2.0f * cr::tanf (kFov * deg2rad (1.0f) * 0.5f) * kMinViewDistance;
m_nearWidth = m_nearHeight * kAspectRatio;
m_farHeight = 2.0f * cr::tanf (kFov * deg2rad (1.0f) * 0.5f) * kMaxViewDistance;
m_farWidth = m_farHeight * kAspectRatio;
}
public:
// updates bot view frustum
void calculate (Planes &planes, const Vector &viewAngle, const Vector &viewOffset);
// check if object inside frustum plane
bool isObjectInsidePlane (const Plane &plane, const Vector &center, float height, float radius) const;
// check if entity origin inside view plane
bool check (const Planes &planes, edict_t *ent) const;
};
// declare global frustum data
CR_EXPOSE_GLOBAL_SINGLETON (Frustum, frustum);

View file

@ -112,13 +112,6 @@ struct ClientNoise {
float last;
};
// defines frustum data for bot
struct FrustumPlane {
Vector normal;
Vector point;
float result;
};
// array of clients struct
struct Client {
edict_t *ent; // pointer to actual edict
@ -146,6 +139,7 @@ struct ChatCollection {
// include bot graph stuff
#include <graph.h>
#include <vision.h>
// this structure links nodes returned from pathfinder
class PathWalk final : public NonCopyable {
@ -224,8 +218,6 @@ public:
private:
mutable Mutex m_pathFindLock {};
mutable Mutex m_predictLock {};
mutable Mutex m_lookAnglesLock {};
private:
uint32_t m_states {}; // sensing bitstates
@ -374,7 +366,7 @@ private:
Path *m_path {}; // pointer to the current path node
String m_chatBuffer {}; // space for strings (say text...)
FrustumPlane m_frustum[FrustumSide::Num] {};
Frustum::Planes m_viewFrustum {};
private:
int pickBestWeapon (Array <int> &vec, int moneySave);
@ -444,7 +436,6 @@ private:
bool isPenetrableObstacle2 (const Vector &dest);
bool isPenetrableObstacle3 (const Vector &dest);
bool isEnemyBehindShield (edict_t *enemy);
bool isEnemyInFrustum (edict_t *enemy);
bool checkChatKeywords (String &reply);
bool isReplyingToChat ();
bool isReachableNode (int index);
@ -472,7 +463,6 @@ private:
void checkBurstMode (float distance);
void checkSilencer ();
void updateAimDir ();
void syncUpdateLookAngles ();
void updateLookAngles ();
void updateBodyAngles ();
void updateLookAnglesNewbie (const Vector &direction, float delta);
@ -487,7 +477,6 @@ private:
void updatePracticeValue (int damage);
void updatePracticeDamage (edict_t *attacker, int damage);
void findShortestPath (int srcIndex, int destIndex);
void calculateFrustum ();
void findPath (int srcIndex, int destIndex, FindPath pathType = FindPath::Fast);
void syncFindPath (int srcIndex, int destIndex, FindPath pathType);
void debugMsgInternal (const char *str);
@ -511,8 +500,6 @@ private:
void selectSecondary ();
void selectWeaponById (int id);
void selectWeaponByIndex (int index);
void refreshEnemyPredict ();
void syncUpdatePredictedIndex ();
void updatePredictedIndex ();
void refreshModelName (char *infobuffer);
@ -523,6 +510,7 @@ private:
void translateInput ();
void moveToGoal ();
void resetMovement ();
void refreshEnemyPredict ();
void normal_ ();
void spraypaint_ ();
@ -704,7 +692,6 @@ public:
// need to wait until all threads will finish it's work before terminating bot object
~Bot () {
MutexScopedLock lock1 (m_pathFindLock);
MutexScopedLock lock2 (m_lookAnglesLock);
}
public: