// // YaPB, based on PODBot by Markus Klinge ("CountFloyd"). // Copyright © YaPB Project Developers . // // SPDX-License-Identifier: MIT // #pragma once class BotSupport final : public Singleton { private: mutable Mutex m_cs {}; private: bool m_needToSendWelcome {}; float m_welcomeReceiveTime {}; StringArray m_sentences {}; SmallArray m_clients {}; HashMap m_weaponAliases {}; public: BotSupport (); ~BotSupport () = default; public: // need to send welcome message ? void checkWelcome (); // 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 isShootableBreakable (edict_t *ent); // 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); // tracing decals for bots spraying logos void decalTrace (entvars_t *pev, TraceResult *trace, int logotypeIndex); // update stats on clients void updateClients (); // generates ping bitmask for SVC_PINGS message int getPingBitmask (edict_t *ent, int loss, int ping); // calculate our own pings for all the players void syncCalculatePings (); // calculate our own pings for all the players void calculatePings (); // send modified pings to all the clients void emitPings (edict_t *to); // reset ping to zero values void resetPings (edict_t *to); // checks if same model omitting the models directory bool isModel (const edict_t *ent, StringRef model); // get the current date and time as string String getCurrentDateTime (); // generates fake steam id from bot name StringRef getFakeSteamId (edict_t *ent); // get's the wave length float getWaveLength (StringRef filename); public: // re-show welcome after changelevel ? void setNeedForWelcome (bool need) { m_needToSendWelcome = need; m_welcomeReceiveTime = -1.0f; } // get array of clients SmallArray &getClients () { return m_clients; } // get clients as const-reference const SmallArray &getClients () const { return m_clients; } // get single client as ref Client &getClient (const int index) { return m_clients[index]; } // gets the shooting cone deviation float getConeDeviation (edict_t *ent, const Vector &pos) const { return ent->v.v_angle.forward () | (pos - (ent->v.origin + ent->v.view_ofs)).normalize (); // he's facing it, he meant it } // check if position is inside view cone of entity bool isInViewCone (const Vector &pos, edict_t *ent) const { return getConeDeviation (ent, pos) >= cr::cosf (cr::deg2rad ((ent->v.fov > 0 ? ent->v.fov : 90.0f) * 0.5f)); } }; // expose global CR_EXPOSE_GLOBAL_SINGLETON (BotSupport, util);