nav: various fixes to movement code

refactor: move some things into new game state class
This commit is contained in:
jeefo 2025-10-08 20:12:46 +03:00
commit 7b378ba3fa
No known key found for this signature in database
GPG key ID: D696786B81B667C8
29 changed files with 805 additions and 745 deletions

View file

@ -447,7 +447,7 @@ constexpr auto kSprayDistanceX2 = kSprayDistance * 2;
constexpr auto kMaxChatterRepeatInterval = 99.0f;
constexpr auto kViewFrameUpdate = 1.0f / 25.0f;
constexpr auto kGrenadeDamageRadius = 385.0f;
constexpr auto kMinMovedDistance = 3.0f;
constexpr auto kMinMovedDistance = 2.5f;
constexpr auto kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
constexpr auto kMaxWeapons = 32;

View file

@ -265,7 +265,7 @@ public:
void searchEntities (const Vector &position, float radius, EntitySearch functor) const;
// check if map has entity
bool hasEntityInGame (StringRef classname);
bool hasEntityInGame (StringRef classname) const;
// print the version to server console on startup
void printBotVersion () const;
@ -282,6 +282,38 @@ public:
// is developer mode ?
bool isDeveloperMode () const;
// entity utils
public:
// check if entity is alive
bool isAliveEntity (edict_t *ent) const;
// checks if entity is fakeclient
bool isFakeClientEntity (edict_t *ent) const;
// check if entity is a player
bool isPlayerEntity (edict_t *ent) const ;
// check if entity is a monster
bool isMonsterEntity (edict_t *ent) const;
// check if entity is a item
bool isItemEntity (edict_t *ent) const;
// check if entity is a hostage entity
bool isHostageEntity (edict_t *ent) const;
// check if entity is a door entity
bool isDoorEntity (edict_t *ent) const;
// this function is checking that pointed by ent pointer obstacle, can be destroyed
bool isBreakableEntity (edict_t *ent, bool initialSeed = false) const;
// checks if same model omitting the models directory
bool isEntityModelMatches (const edict_t *ent, StringRef model) const;
// check if entity is a vip
bool isPlayerVIP (edict_t *ent) const;
// public inlines
public:
// get the current time on server
@ -343,7 +375,7 @@ public:
}
// get the wroldspawn entity
edict_t *getStartEntity () {
edict_t *getStartEntity () const {
return m_startEntity;
}
@ -353,7 +385,7 @@ public:
}
// gets the player team
int getTeam (edict_t *ent) const {
int getPlayerTeam (edict_t *ent) const {
if (isNullEntity (ent)) {
return Team::Unassigned;
}
@ -361,7 +393,7 @@ public:
}
// gets the player team (real in ffa)
int getRealTeam (edict_t *ent) const {
int getRealPlayerTeam (edict_t *ent) const {
if (isNullEntity (ent)) {
return Team::Unassigned;
}
@ -369,8 +401,8 @@ public:
}
// get real gamedll team (matches gamedll indices)
int getGameTeam (edict_t *ent) const {
return getRealTeam (ent) + 1;
int getPlayerTeamGame (edict_t *ent) const {
return getRealPlayerTeam (ent) + 1;
}
// sets the precache to uninitialized
@ -723,6 +755,98 @@ public:
}
};
// offload bot manager class from things it shouldn't do
class GameState final : public Singleton <GameState> {
private:
bool m_bombPlanted {}; // is bomb planted ?
bool m_roundOver {}; // well, round is over>
bool m_resetHud {}; // reset HUD is called for some one
float m_timeBombPlanted {}; // time the bomb were planted
float m_timeRoundStart {}; // time round has started
float m_timeRoundEnd {}; // time round ended
float m_timeRoundMid {}; // middle point timestamp of a round
Vector m_bombOrigin {}; // stored bomb origin
Array <edict_t *> m_activeGrenades {}; // holds currently active grenades on the map
Array <edict_t *> m_interestingEntities {}; // holds currently interesting entities on the map
IntervalTimer m_interestingEntitiesUpdateTime {}; // time to update interesting entities
IntervalTimer m_activeGrenadesUpdateTime {}; // time to update active grenades
public:
GameState () = default;
~GameState () = default;
public:
const Vector &getBombOrigin () const {
return m_bombOrigin;
}
bool isBombPlanted () const {
return m_bombPlanted;
}
float getTimeBombPlanted () const {
return m_timeBombPlanted;
}
float getRoundStartTime () const {
return m_timeRoundStart;
}
float getRoundMidTime () const {
return m_timeRoundMid;
}
float getRoundEndTime () const {
return m_timeRoundEnd;
}
bool isRoundOver () const {
return m_roundOver;
}
bool isResetHUD () const {
return m_resetHud;
}
void setResetHUD (bool resetHud) {
m_resetHud = resetHud;
}
void setRoundOver (bool roundOver) {
m_roundOver = roundOver;
}
const Array <edict_t *> &getActiveGrenades () {
return m_activeGrenades;
}
const Array <edict_t *> &getInterestingEntities () {
return m_interestingEntities;
}
bool hasActiveGrenades () const {
return !m_activeGrenades.empty ();
}
bool hasInterestingEntities () const {
return !m_interestingEntities.empty ();
}
public:
float getBombTimeLeft () const;
void setBombPlanted (bool isPlanted);
void setBombOrigin (bool reset = false, const Vector &pos = nullptr);
void roundStart ();
void updateActiveGrenade ();
void updateInterestingEntities ();
};
// expose globals
CR_EXPOSE_GLOBAL_SINGLETON (Game, game);
CR_EXPOSE_GLOBAL_SINGLETON (GameState, gameState);
CR_EXPOSE_GLOBAL_SINGLETON (LightMeasure, illum);

View file

@ -173,7 +173,6 @@ private:
Vector m_learnVelocity {};
Vector m_learnPosition {};
Vector m_bombOrigin {};
Vector m_lastNode {};
IntArray m_terrorPoints {};
@ -253,7 +252,6 @@ public:
void clearVisited ();
void eraseFromBucket (const Vector &pos, int index);
void setBombOrigin (bool reset = false, const Vector &pos = nullptr);
void unassignPath (int from, int to);
void convertFromPOD (Path &path, const PODPath &pod) const;
void convertToPOD (const Path &path, PODPath &pod);
@ -292,10 +290,6 @@ public:
m_editFlags &= ~flag;
}
const Vector &getBombOrigin () const {
return m_bombOrigin;
}
// access paths
Path &operator [] (int index) {
return m_paths[index];

View file

@ -24,32 +24,19 @@ public:
using UniqueBot = UniquePtr <Bot>;
private:
float m_timeRoundStart {}; // time round has started
float m_timeRoundEnd {}; // time round ended
float m_timeRoundMid {}; // middle point timestamp of a round
float m_difficultyBalanceTime {}; // time to balance difficulties ?
float m_autoKillCheckTime {}; // time to kill all the bots ?
float m_maintainTime {}; // time to maintain bot creation
float m_quotaMaintainTime {}; // time to maintain bot quota
float m_grenadeUpdateTime {}; // time to update active grenades
float m_entityUpdateTime {}; // time to update interesting entities
float m_plantSearchUpdateTime {}; // time to update for searching planted bomb
float m_lastChatTime {}; // global chat time timestamp
float m_timeBombPlanted {}; // time the bomb were planted
int m_lastWinner {}; // the team who won previous round
int m_lastDifficulty {}; // last bots difficulty
int m_bombSayStatus {}; // some bot is issued whine about bomb
int m_numPreviousPlayers {}; // number of players in game im previous player check
bool m_bombPlanted {}; // is bomb planted ?
bool m_botsCanPause {}; // bots can do a little pause ?
bool m_roundOver {}; // well, round is over>
bool m_resetHud {}; // reset HUD is called for some one
Array <edict_t *> m_activeGrenades {}; // holds currently active grenades on the map
Array <edict_t *> m_interestingEntities {}; // holds currently interesting entities on the map
Deque <String> m_saveBotNames {}; // bots names that persist upon changelevel
Deque <BotRequest> m_addRequests {}; // bot creation tab
@ -81,10 +68,9 @@ public:
int getAliveHumansCount ();
int getPlayerPriority (edict_t *ent);
float getConnectTime (StringRef name, float original);
float getConnectionTimes (StringRef name, float original);
float getAverageTeamKPD (bool calcForBots);
void setBombPlanted (bool isPlanted);
void frame ();
void createKillerEntity ();
void destroyKillerEntity ();
@ -113,8 +99,6 @@ public:
void reset ();
void initFilters ();
void resetFilters ();
void updateActiveGrenade ();
void updateInterestingEntities ();
void captureChatRadio (StringRef cmd, StringRef arg, edict_t *ent);
void notifyBombDefuse ();
void execGameEntity (edict_t *ent);
@ -130,27 +114,10 @@ public:
bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned);
bool balancedKickRandom (bool decQuota);
bool hasCustomCSDMSpawnEntities ();
bool isLineBlockedBySmoke (const Vector &from, const Vector &to);
bool isFrameSkipDisabled ();
public:
const Array <edict_t *> &getActiveGrenades () {
return m_activeGrenades;
}
const Array <edict_t *> &getInterestingEntities () {
return m_interestingEntities;
}
bool hasActiveGrenades () const {
return !m_activeGrenades.empty ();
}
bool hasInterestingEntities () const {
return !m_interestingEntities.empty ();
}
bool checkTeamEco (int team) const {
bool getTeamEconomics (int team) const {
return m_teamData[team].positiveEco;
}
@ -171,30 +138,6 @@ public:
addbot ("", -1, -1, -1, -1, manual);
}
bool isBombPlanted () const {
return m_bombPlanted;
}
float getTimeBombPlanted () const {
return m_timeBombPlanted;
}
float getRoundStartTime () const {
return m_timeRoundStart;
}
float getRoundMidTime () const {
return m_timeRoundMid;
}
float getRoundEndTime () const {
return m_timeRoundEnd;
}
bool isRoundOver () const {
return m_roundOver;
}
bool canPause () const {
return m_botsCanPause;
}
@ -236,10 +179,6 @@ public:
m_teamData[team].lastRadioSlot = radio;
}
void setResetHUD (bool resetHud) {
m_resetHud = resetHud;
}
int getLastRadio (const int team) const {
return m_teamData[team].lastRadioSlot;
}

View file

@ -108,7 +108,7 @@ public:
void setDamage (int32_t team, int32_t start, int32_t goal, int32_t value);
// interlocked get damage
float plannerGetDamage (int32_t team, int32_t start, int32_t goal, bool addTeamHighestDamage);
float getDamageEx (int32_t team, int32_t start, int32_t goal, bool addTeamHighestDamage);
public:
void update ();

View file

@ -31,36 +31,6 @@ public:
// converts weapon id to alias name
StringRef weaponIdToAlias (int32_t id);
// check if origin is visible from the entity side
bool isVisible (const Vector &origin, edict_t *ent);
// check if entity is alive
bool isAlive (edict_t *ent);
// checks if entity is fakeclient
bool isFakeClient (edict_t *ent);
// check if entity is a player
bool isPlayer (edict_t *ent);
// check if entity is a monster
bool isMonster (edict_t *ent);
// check if entity is a item
bool isItem (edict_t *ent);
// check if entity is a vip
bool isPlayerVIP (edict_t *ent);
// check if entity is a hostage entity
bool isHostageEntity (edict_t *ent);
// check if entity is a door entity
bool isDoorEntity (edict_t *ent);
// this function is checking that pointed by ent pointer obstacle, can be destroyed
bool isBreakableEntity (edict_t *ent, bool initialSeed = false);
// nearest player search helper
bool findNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false, bool needBotWithC4 = false);
@ -70,8 +40,8 @@ public:
// update stats on clients
void updateClients ();
// checks if same model omitting the models directory
bool isModel (const edict_t *ent, StringRef model);
// check if origin is visible from the entity side
bool isVisible (const Vector &origin, edict_t *ent);
// get the current date and time as string
String getCurrentDateTime ();
@ -85,6 +55,9 @@ public:
// set custom cvar descriptions
void setCustomCvarDescriptions ();
// check if line of sight blocked by a smoke
bool isLineBlockedBySmoke (const Vector &from, const Vector &to);
public:
// re-show welcome after changelevel ?

View file

@ -39,7 +39,7 @@ public:
~GraphVistable () = default;
public:
bool visible (int srcIndex, int destIndex, VisIndex vis = VisIndex::Any);
bool visible (int srcIndex, int destIndex, VisIndex vis = VisIndex::Any) const;
void load ();
void save () const;

View file

@ -400,7 +400,7 @@ private:
int numEnemiesNear (const Vector &origin, const float radius) const;
int numFriendsNear (const Vector &origin, const float radius) const;
float getBombTimeleft () const;
float getEstimatedNodeReachTime ();
float isInFOV (const Vector &dest) const;
float getShiftSpeed ();