From f2c8e2346e77771e5decc5824c474bbf123c760b Mon Sep 17 00:00:00 2001 From: Sam V Date: Fri, 7 Oct 2022 16:31:04 +0200 Subject: [PATCH] Access world through global, access local player through helper function, remove some obsolete utility functions ValveSoftware/halflife#3307 --- dlls/cbase.h | 41 ++++++++++++++++++++--------------- dlls/effects.cpp | 10 ++++----- dlls/gauss.cpp | 2 +- dlls/nodes.cpp | 2 +- dlls/player.cpp | 18 +++++++-------- dlls/sound.cpp | 8 +++---- dlls/talkmonster.cpp | 24 ++++++++++---------- dlls/teamplay_gamerules.cpp | 5 ++--- dlls/triggers.cpp | 23 ++++++++++---------- dlls/util.cpp | 19 ++++++++++++++-- dlls/util.h | 17 ++++++++++----- dlls/world.cpp | 28 ++++++++++++++++++++++++ game_shared/voice_gamemgr.cpp | 14 +++++------- 13 files changed, 131 insertions(+), 80 deletions(-) diff --git a/dlls/cbase.h b/dlls/cbase.h index 8c54697a9..37c3cb66e 100644 --- a/dlls/cbase.h +++ b/dlls/cbase.h @@ -279,23 +279,9 @@ class CBaseEntity bool IsDormant(); bool IsLockedByMaster() { return false; } - static CBaseEntity* Instance(edict_t* pent) - { - if (!pent) - pent = ENT(0); - CBaseEntity* pEnt = (CBaseEntity*)GET_PRIVATE(pent); - return pEnt; - } - - static CBaseEntity* Instance(entvars_t* pev) - { - if (!pev) - return Instance(ENT(0)); + static CBaseEntity* Instance(edict_t* pent); - return Instance(ENT(pev)); - } - - static CBaseEntity* Instance(int eoffset) { return Instance(ENT(eoffset)); } + static CBaseEntity* Instance(entvars_t* pev); CBaseMonster* GetMonsterPointer(entvars_t* pevMonster) { @@ -360,7 +346,6 @@ class CBaseEntity virtual bool FBecomeProne() { return false; } edict_t* edict() { return ENT(pev); } - EOFFSET eoffset() { return OFFSET(pev); } int entindex() { return ENTINDEX(edict()); } virtual Vector Center() { return (pev->absmax + pev->absmin) * 0.5; } // center point of entity @@ -756,9 +741,29 @@ push_trigger_data class CWorld : public CBaseEntity { public: + CWorld(); + ~CWorld(); + void Spawn() override; void Precache() override; bool KeyValue(KeyValueData* pkvd) override; + + static inline CWorld* Instance = nullptr; }; -inline DLL_GLOBAL edict_t* g_pBodyQueueHead = nullptr; \ No newline at end of file +inline DLL_GLOBAL edict_t* g_pBodyQueueHead = nullptr; + +inline CBaseEntity* CBaseEntity::Instance(edict_t* pent) +{ + if (!pent) + return CWorld::Instance; + return (CBaseEntity*)GET_PRIVATE(pent); +} + +inline CBaseEntity* CBaseEntity::Instance(entvars_t* pev) +{ + if (!pev) + return CWorld::Instance; + + return Instance(ENT(pev)); +} diff --git a/dlls/effects.cpp b/dlls/effects.cpp index c0c32be50..cd63aa6f2 100644 --- a/dlls/effects.cpp +++ b/dlls/effects.cpp @@ -1790,16 +1790,16 @@ Vector CBlood::BloodPosition(CBaseEntity* pActivator) { if ((pev->spawnflags & SF_BLOOD_PLAYER) != 0) { - edict_t* pPlayer; + CBaseEntity* pPlayer; if (pActivator && pActivator->IsPlayer()) { - pPlayer = pActivator->edict(); + pPlayer = pActivator; } else - pPlayer = g_engfuncs.pfnPEntityOfEntIndex(1); + pPlayer = UTIL_GetLocalPlayer(); if (pPlayer) - return (pPlayer->v.origin + pPlayer->v.view_ofs) + Vector(RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10)); + return (pPlayer->pev->origin + pPlayer->pev->view_ofs) + Vector(RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10), RANDOM_FLOAT(-10, 10)); } return pev->origin; @@ -2070,7 +2070,7 @@ void CMessage::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useTy pPlayer = pActivator; else { - pPlayer = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(1)); + pPlayer = UTIL_GetLocalPlayer(); } if (pPlayer) UTIL_ShowMessage(STRING(pev->message), pPlayer); diff --git a/dlls/gauss.cpp b/dlls/gauss.cpp index fba288f57..441d7ae40 100644 --- a/dlls/gauss.cpp +++ b/dlls/gauss.cpp @@ -263,7 +263,7 @@ void CGauss::SecondaryAttack() SendStopEvent(false); #ifndef CLIENT_DLL - m_pPlayer->TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), 50, DMG_SHOCK); + m_pPlayer->TakeDamage(CWorld::Instance->pev, CWorld::Instance->pev, 50, DMG_SHOCK); UTIL_ScreenFade(m_pPlayer, Vector(255, 128, 0), 2, 0.5, 128, FFADE_IN); #endif SendWeaponAnim(GAUSS_IDLE); diff --git a/dlls/nodes.cpp b/dlls/nodes.cpp index bc4edb0f5..cc68c544e 100644 --- a/dlls/nodes.cpp +++ b/dlls/nodes.cpp @@ -1522,7 +1522,7 @@ void CTestHull::DropDelay() { // UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding..." ); - UTIL_SetOrigin(VARS(pev), WorldGraph.m_pNodes[0].m_vecOrigin); + UTIL_SetOrigin(pev, WorldGraph.m_pNodes[0].m_vecOrigin); SetThink(&CTestHull::CallBuildNodeGraph); diff --git a/dlls/player.cpp b/dlls/player.cpp index 54b84af20..0755d3f1f 100644 --- a/dlls/player.cpp +++ b/dlls/player.cpp @@ -1096,7 +1096,7 @@ void CBasePlayer::WaterMove() pev->dmg += 1; if (pev->dmg > 5) pev->dmg = 5; - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), pev->dmg, DMG_DROWN); + TakeDamage(CWorld::Instance->pev, CWorld::Instance->pev, pev->dmg, DMG_DROWN); pev->pain_finished = gpGlobals->time + 1; // track drowning damage, give it back when @@ -1148,12 +1148,12 @@ void CBasePlayer::WaterMove() if (pev->watertype == CONTENT_LAVA) // do damage { if (pev->dmgtime < gpGlobals->time) - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), 10 * pev->waterlevel, DMG_BURN); + TakeDamage(CWorld::Instance->pev, CWorld::Instance->pev, 10 * pev->waterlevel, DMG_BURN); } else if (pev->watertype == CONTENT_SLIME) // do damage { pev->dmgtime = gpGlobals->time + 1; - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), 4 * pev->waterlevel, DMG_ACID); + TakeDamage(CWorld::Instance->pev, CWorld::Instance->pev, 4 * pev->waterlevel, DMG_ACID); } if (!FBitSet(pev->flags, FL_INWATER)) @@ -2548,7 +2548,7 @@ void CBasePlayer::PostThink() if (flFallDamage > 0) { - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), flFallDamage, DMG_FALL); + TakeDamage(CWorld::Instance->pev, CWorld::Instance->pev, flFallDamage, DMG_FALL); pev->punchangle.x = 0; } } @@ -2740,7 +2740,7 @@ edict_t* EntSelectSpawnPoint(CBaseEntity* pPlayer) { // if ent is a client, kill em (unless they are ourselves) if (ent->IsPlayer() && !(ent->edict() == player)) - ent->TakeDamage(VARS(INDEXENT(0)), VARS(INDEXENT(0)), 300, DMG_GENERIC); + ent->TakeDamage(CWorld::Instance->pev, CWorld::Instance->pev, 300, DMG_GENERIC); } goto ReturnSpot; } @@ -2764,7 +2764,7 @@ edict_t* EntSelectSpawnPoint(CBaseEntity* pPlayer) if (FNullEnt(pSpot)) { ALERT(at_error, "PutClientInServer: no info_player_start on level"); - return INDEXENT(0); + return CWorld::Instance->edict(); } g_pLastSpawn = pSpot; @@ -3554,7 +3554,7 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse) { TraceResult tr; - edict_t* pWorld = g_engfuncs.pfnPEntityOfEntIndex(0); + edict_t* pWorld = CWorld::Instance->edict(); Vector start = pev->origin + pev->view_ofs; Vector end = start + gpGlobals->v_forward * 1024; @@ -4374,7 +4374,7 @@ Vector CBasePlayer::GetAutoaimVector(float flDelta) Vector CBasePlayer::AutoaimDeflection(Vector& vecSrc, float flDist, float flDelta) { - edict_t* pEdict = g_engfuncs.pfnPEntityOfEntIndex(1); + edict_t* pEdict = UTIL_GetEntityList() + 1; CBaseEntity* pEntity; float bestdot; Vector bestdir; @@ -4817,7 +4817,7 @@ void CStripWeapons::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE } else if (!g_pGameRules->IsDeathmatch()) { - pPlayer = (CBasePlayer*)CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(1)); + pPlayer = (CBasePlayer*)UTIL_GetLocalPlayer(); } if (pPlayer) diff --git a/dlls/sound.cpp b/dlls/sound.cpp index b8bbc8676..3bfc6807b 100644 --- a/dlls/sound.cpp +++ b/dlls/sound.cpp @@ -1677,7 +1677,7 @@ float TEXTURETYPE_PlaySound(TraceResult* ptr, Vector vecSrc, Vector vecEnd, int if (pEntity) pTextureName = TRACE_TEXTURE(ENT(pEntity->pev), rgfl1, rgfl2); else - pTextureName = TRACE_TEXTURE(ENT(0), rgfl1, rgfl2); + pTextureName = TRACE_TEXTURE(CWorld::Instance->edict(), rgfl1, rgfl2); if (pTextureName) { @@ -1804,10 +1804,10 @@ float TEXTURETYPE_PlaySound(TraceResult* ptr, Vector vecSrc, Vector vecEnd, int switch (RANDOM_LONG(0, 1)) { case 0: - UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "buttons/spark5.wav", flVolume, ATTN_NORM, 0, 100); + UTIL_EmitAmbientSound(CWorld::Instance->edict(), ptr->vecEndPos, "buttons/spark5.wav", flVolume, ATTN_NORM, 0, 100); break; case 1: - UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "buttons/spark6.wav", flVolume, ATTN_NORM, 0, 100); + UTIL_EmitAmbientSound(CWorld::Instance->edict(), ptr->vecEndPos, "buttons/spark6.wav", flVolume, ATTN_NORM, 0, 100); break; // case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break; // case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break; @@ -1816,7 +1816,7 @@ float TEXTURETYPE_PlaySound(TraceResult* ptr, Vector vecSrc, Vector vecEnd, int } // play material hit sound - UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, rgsz[RANDOM_LONG(0, cnt - 1)], fvol, fattn, 0, 96 + RANDOM_LONG(0, 0xf)); + UTIL_EmitAmbientSound(CWorld::Instance->edict(), ptr->vecEndPos, rgsz[RANDOM_LONG(0, cnt - 1)], fvol, fattn, 0, 96 + RANDOM_LONG(0, 0xf)); //EMIT_SOUND_DYN( ENT(m_pPlayer->pev), CHAN_WEAPON, rgsz[RANDOM_LONG(0,cnt-1)], fvol, ATTN_NORM, 0, 96 + RANDOM_LONG(0,0xf)); return fvolbar; diff --git a/dlls/talkmonster.cpp b/dlls/talkmonster.cpp index e232b8ad4..9fbe9f35a 100644 --- a/dlls/talkmonster.cpp +++ b/dlls/talkmonster.cpp @@ -480,7 +480,7 @@ void CTalkMonster::RunTask(Task_t* pTask) case TASK_TLK_LOOK_AT_CLIENT: { // Get edict for one player - edict_t* pPlayer = g_engfuncs.pfnPEntityOfEntIndex(1); + CBaseEntity* pPlayer = UTIL_GetLocalPlayer(); // track head to the client for a while. if (pPlayer && @@ -488,7 +488,7 @@ void CTalkMonster::RunTask(Task_t* pTask) !IsMoving() && !IsTalking()) { - IdleHeadTurn(pPlayer->v.origin); + IdleHeadTurn(pPlayer->pev->origin); } else { @@ -500,14 +500,14 @@ void CTalkMonster::RunTask(Task_t* pTask) if (pTask->iTask == TASK_TLK_CLIENT_STARE) { // fail out if the player looks away or moves away. - if ((pPlayer->v.origin - pev->origin).Length2D() > TLK_STARE_DIST) + if ((pPlayer->pev->origin - pev->origin).Length2D() > TLK_STARE_DIST) { // player moved away. TaskFail(); } - UTIL_MakeVectors(pPlayer->v.angles); - if (UTIL_DotPoints(pPlayer->v.origin, pev->origin, gpGlobals->v_forward) < m_flFieldOfView) + UTIL_MakeVectors(pPlayer->pev->angles); + if (UTIL_DotPoints(pPlayer->pev->origin, pev->origin, gpGlobals->v_forward) < m_flFieldOfView) { // player looked away TaskFail(); @@ -524,13 +524,13 @@ void CTalkMonster::RunTask(Task_t* pTask) case TASK_FACE_PLAYER: { // Get edict for one player - edict_t* pPlayer = g_engfuncs.pfnPEntityOfEntIndex(1); + CBaseEntity* pPlayer = UTIL_GetLocalPlayer(); if (pPlayer) { - MakeIdealYaw(pPlayer->v.origin); + MakeIdealYaw(pPlayer->pev->origin); ChangeYaw(pev->yaw_speed); - IdleHeadTurn(pPlayer->v.origin); + IdleHeadTurn(pPlayer->pev->origin); if (gpGlobals->time > m_flWaitFinished && FlYawDiff() < 10) { TaskComplete(); @@ -1243,14 +1243,14 @@ Schedule_t* CTalkMonster::GetScheduleOfType(int Type) if (!IsTalking() && HasConditions(bits_COND_SEE_CLIENT) && RANDOM_LONG(0, 6) == 0) { - edict_t* pPlayer = g_engfuncs.pfnPEntityOfEntIndex(1); + CBaseEntity* pPlayer = UTIL_GetLocalPlayer(); if (pPlayer) { // watch the client. - UTIL_MakeVectors(pPlayer->v.angles); - if ((pPlayer->v.origin - pev->origin).Length2D() < TLK_STARE_DIST && - UTIL_DotPoints(pPlayer->v.origin, pev->origin, gpGlobals->v_forward) >= m_flFieldOfView) + UTIL_MakeVectors(pPlayer->pev->angles); + if ((pPlayer->pev->origin - pev->origin).Length2D() < TLK_STARE_DIST && + UTIL_DotPoints(pPlayer->pev->origin, pev->origin, gpGlobals->v_forward) >= m_flFieldOfView) { // go into the special STARE schedule if the player is close, and looking at me too. return &slTlkIdleWatchClient[1]; diff --git a/dlls/teamplay_gamerules.cpp b/dlls/teamplay_gamerules.cpp index 56238b0fc..484c85b41 100644 --- a/dlls/teamplay_gamerules.cpp +++ b/dlls/teamplay_gamerules.cpp @@ -45,7 +45,7 @@ CHalfLifeTeamplay::CHalfLifeTeamplay() // Cache this because the team code doesn't want to deal with changing this in the middle of a game strncpy(m_szTeamList, teamlist.string, TEAMPLAY_TEAMLISTLENGTH); - edict_t* pWorld = INDEXENT(0); + edict_t* pWorld = CWorld::Instance->edict(); if (pWorld && !FStringNull(pWorld->v.team)) { if (0 != teamoverride.value) @@ -270,8 +270,7 @@ void CHalfLifeTeamplay::ChangePlayerTeam(CBasePlayer* pPlayer, const char* pTeam m_DisableDeathMessages = true; m_DisableDeathPenalty = true; - entvars_t* pevWorld = VARS(INDEXENT(0)); - pPlayer->TakeDamage(pevWorld, pevWorld, 900, damageFlags); + pPlayer->TakeDamage(CWorld::Instance->pev, CWorld::Instance->pev, 900, damageFlags); m_DisableDeathMessages = false; m_DisableDeathPenalty = false; diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index a8f1e078d..63cf8e32d 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -695,10 +695,8 @@ void CTriggerCDAudio::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYP void PlayCDTrack(int iTrack) { - edict_t* pClient; - // manually find the single player. - pClient = g_engfuncs.pfnPEntityOfEntIndex(1); + CBaseEntity* pClient = UTIL_GetLocalPlayer(); // Can't play if the client is not connected! if (!pClient) @@ -712,14 +710,14 @@ void PlayCDTrack(int iTrack) if (iTrack == -1) { - CLIENT_COMMAND(pClient, "cd stop\n"); + CLIENT_COMMAND(pClient->edict(), "cd stop\n"); } else { char string[64]; sprintf(string, "cd play %3d\n", iTrack); - CLIENT_COMMAND(pClient, string); + CLIENT_COMMAND(pClient->edict(), string); } } @@ -776,10 +774,8 @@ void CTargetCDAudio::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE // only plays for ONE client, so only use in single play! void CTargetCDAudio::Think() { - edict_t* pClient; - // manually find the single player. - pClient = g_engfuncs.pfnPEntityOfEntIndex(1); + CBaseEntity* pClient = UTIL_GetLocalPlayer(); // Can't play if the client is not connected! if (!pClient) @@ -787,7 +783,7 @@ void CTargetCDAudio::Think() pev->nextthink = gpGlobals->time + 0.5; - if ((pClient->v.origin - pev->origin).Length() <= pev->scale) + if ((pClient->pev->origin - pev->origin).Length() <= pev->scale) Play(); } @@ -1495,7 +1491,7 @@ void CChangeLevel::ChangeLevelNow(CBaseEntity* pActivator) pev->dmgtime = gpGlobals->time; - CBaseEntity* pPlayer = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(1)); + CBaseEntity* pPlayer = UTIL_GetLocalPlayer(); if (!InTransitionVolume(pPlayer, m_szLandmarkName)) { ALERT(at_aiconsole, "Player isn't in the transition volume %s, aborting\n", m_szLandmarkName); @@ -2248,7 +2244,12 @@ void CTriggerCamera::Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE } if (!pActivator || !pActivator->IsPlayer()) { - pActivator = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex(1)); + pActivator = UTIL_GetLocalPlayer(); + + if (!pActivator) + { + return; + } } auto player = static_cast(pActivator); diff --git a/dlls/util.cpp b/dlls/util.cpp index 273634fea..49e9865db 100644 --- a/dlls/util.cpp +++ b/dlls/util.cpp @@ -321,6 +321,15 @@ TYPEDESCRIPTION gEntvarsDescription[] = #define ENTVARS_COUNT (sizeof(gEntvarsDescription) / sizeof(gEntvarsDescription[0])) +edict_t* UTIL_GetEntityList() +{ + return g_engfuncs.pfnPEntityOfEntOffset(0); +} + +CBaseEntity* UTIL_GetLocalPlayer() +{ + return UTIL_PlayerByIndex(1); +} #ifdef DEBUG edict_t* DBG_EntOfVars(const entvars_t* pev) @@ -408,7 +417,7 @@ void UTIL_MoveToOrigin(edict_t* pent, const Vector& vecGoal, float flDist, int i int UTIL_EntitiesInBox(CBaseEntity** pList, int listMax, const Vector& mins, const Vector& maxs, int flagMask) { - edict_t* pEdict = g_engfuncs.pfnPEntityOfEntIndex(1); + edict_t* pEdict = UTIL_GetEntityList(); CBaseEntity* pEntity; int count; @@ -417,6 +426,9 @@ int UTIL_EntitiesInBox(CBaseEntity** pList, int listMax, const Vector& mins, con if (!pEdict) return count; + // Ignore world. + ++pEdict; + for (int i = 1; i < gpGlobals->maxEntities; i++, pEdict++) { if (0 != pEdict->free) // Not in use @@ -450,7 +462,7 @@ int UTIL_EntitiesInBox(CBaseEntity** pList, int listMax, const Vector& mins, con int UTIL_MonstersInSphere(CBaseEntity** pList, int listMax, const Vector& center, float radius) { - edict_t* pEdict = g_engfuncs.pfnPEntityOfEntIndex(1); + edict_t* pEdict = UTIL_GetEntityList(); CBaseEntity* pEntity; int count; float distance, delta; @@ -461,6 +473,9 @@ int UTIL_MonstersInSphere(CBaseEntity** pList, int listMax, const Vector& center if (!pEdict) return count; + // Ignore world. + ++pEdict; + for (int i = 1; i < gpGlobals->maxEntities; i++, pEdict++) { if (0 != pEdict->free) // Not in use diff --git a/dlls/util.h b/dlls/util.h index 2e79b63e7..0e72a5322 100644 --- a/dlls/util.h +++ b/dlls/util.h @@ -23,6 +23,8 @@ #include "activity.h" #include "enginecallback.h" +class CBaseEntity; + inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float* pOrigin, entvars_t* ent); // implementation later in this file inline globalvars_t* gpGlobals = nullptr; @@ -86,6 +88,16 @@ typedef int EOFFSET; extern "C" DLLEXPORT void mapClassName(entvars_t* pev); \ void mapClassName(entvars_t* pev) { GetClassPtr((DLLClassName*)pev); } +/** +* @brief Gets the list of entities. +* Will return @c nullptr if there is no map loaded. +*/ +edict_t* UTIL_GetEntityList(); + +/** +* @brief Gets the local player in singleplayer, or @c nullptr in multiplayer. +*/ +CBaseEntity* UTIL_GetLocalPlayer(); // // Conversion among the three types of "entity", including identity-conversions. @@ -104,7 +116,6 @@ inline edict_t* ENT(edict_t* pent) return pent; } inline edict_t* ENT(EOFFSET eoffset) { return (*g_engfuncs.pfnPEntityOfEntOffset)(eoffset); } -inline EOFFSET OFFSET(EOFFSET eoffset) { return eoffset; } inline EOFFSET OFFSET(const edict_t* pent) { #if _DEBUG @@ -121,7 +132,6 @@ inline EOFFSET OFFSET(entvars_t* pev) #endif return OFFSET(ENT(pev)); } -inline entvars_t* VARS(entvars_t* pev) { return pev; } inline entvars_t* VARS(edict_t* pent) { @@ -131,7 +141,6 @@ inline entvars_t* VARS(edict_t* pent) return &pent->v; } -inline entvars_t* VARS(EOFFSET eoffset) { return VARS(ENT(eoffset)); } inline int ENTINDEX(edict_t* pEdict) { return (*g_engfuncs.pfnIndexOfEdict)(pEdict); } inline edict_t* INDEXENT(int iEdictNum) { return (*g_engfuncs.pfnPEntityOfEntIndex)(iEdictNum); } inline void MESSAGE_BEGIN(int msg_dest, int msg_type, const float* pOrigin, entvars_t* ent) @@ -209,8 +218,6 @@ inline bool FClassnameIs(entvars_t* pev, const char* szClassname) return FStrEq(STRING(pev->classname), szClassname); } -class CBaseEntity; - // Misc. Prototypes extern void UTIL_SetSize(entvars_t* pev, const Vector& vecMin, const Vector& vecMax); extern float UTIL_VecToYaw(const Vector& vec); diff --git a/dlls/world.cpp b/dlls/world.cpp index 9e2b131d7..92cf7217a 100644 --- a/dlls/world.cpp +++ b/dlls/world.cpp @@ -472,6 +472,27 @@ LINK_ENTITY_TO_CLASS(worldspawn, CWorld); #define SF_WORLD_TITLE 0x0002 // Display game title at startup #define SF_WORLD_FORCETEAM 0x0004 // Force teams +CWorld::CWorld() +{ + if (Instance) + { + ALERT(at_error, "Do not create multiple instances of worldspawn\n"); + return; + } + + Instance = this; +} + +CWorld::~CWorld() +{ + if (Instance != this) + { + return; + } + + Instance = nullptr; +} + void CWorld::Spawn() { g_fGameOver = false; @@ -480,6 +501,13 @@ void CWorld::Spawn() void CWorld::Precache() { + // Flag this entity for removal if it's not the actual world entity. + if (Instance != this) + { + UTIL_Remove(this); + return; + } + g_pLastSpawn = NULL; #if 1 diff --git a/game_shared/voice_gamemgr.cpp b/game_shared/voice_gamemgr.cpp index d6f4c7b28..2d00ec3b4 100644 --- a/game_shared/voice_gamemgr.cpp +++ b/game_shared/voice_gamemgr.cpp @@ -46,17 +46,13 @@ static CBasePlayer* FindPlayerByName(const char* pTestName) { for (int i = 1; i <= gpGlobals->maxClients; i++) { - edict_t* pEdict = g_engfuncs.pfnPEntityOfEntIndex(i); - if (pEdict) + CBaseEntity* pEnt = UTIL_PlayerByIndex(i); + if (pEnt) { - CBaseEntity* pEnt = CBaseEntity::Instance(pEdict); - if (pEnt && pEnt->IsPlayer()) + const char* pNetName = STRING(pEnt->pev->netname); + if (stricmp(pNetName, pTestName) == 0) { - const char* pNetName = STRING(pEnt->pev->netname); - if (stricmp(pNetName, pTestName) == 0) - { - return (CBasePlayer*)pEnt; - } + return (CBasePlayer*)pEnt; } } }