removed double entity list in gameworld and cleaned up connected stuff

This commit is contained in:
oy 2011-01-19 18:27:50 +01:00
parent 7ca7c95bc0
commit 19a9462fe8
13 changed files with 92 additions and 109 deletions

View file

@ -40,7 +40,7 @@ MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS)
// Character, "physical" player's part // Character, "physical" player's part
CCharacter::CCharacter(CGameWorld *pWorld) CCharacter::CCharacter(CGameWorld *pWorld)
: CEntity(pWorld, NETOBJTYPE_CHARACTER) : CEntity(pWorld, CGameWorld::ENTTYPE_CHARACTER)
{ {
m_ProximityRadius = ms_PhysSize; m_ProximityRadius = ms_PhysSize;
m_Health = 0; m_Health = 0;
@ -153,11 +153,11 @@ void CCharacter::HandleNinja()
// check if we Hit anything along the way // check if we Hit anything along the way
{ {
CCharacter *aEnts[64]; CCharacter *aEnts[MAX_CLIENTS];
vec2 Dir = m_Pos - OldPos; vec2 Dir = m_Pos - OldPos;
float Radius = m_ProximityRadius * 2.0f; float Radius = m_ProximityRadius * 2.0f;
vec2 Center = OldPos + Dir * 0.5f; vec2 Center = OldPos + Dir * 0.5f;
int Num = GameServer()->m_World.FindEntities(Center, Radius, (CEntity**)aEnts, 64, NETOBJTYPE_CHARACTER); int Num = GameServer()->m_World.FindEntities(Center, Radius, (CEntity**)aEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
for (int i = 0; i < Num; ++i) for (int i = 0; i < Num; ++i)
{ {
@ -289,10 +289,10 @@ void CCharacter::FireWeapon()
m_NumObjectsHit = 0; m_NumObjectsHit = 0;
GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE); GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE);
CCharacter *apEnts[64]; CCharacter *apEnts[MAX_CLIENTS];
int Hits = 0; int Hits = 0;
int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts, int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts,
64, NETOBJTYPE_CHARACTER); MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
for (int i = 0; i < Num; ++i) for (int i = 0; i < Num; ++i)
{ {

View file

@ -4,7 +4,7 @@
#include "flag.h" #include "flag.h"
CFlag::CFlag(CGameWorld *pGameWorld, int Team) CFlag::CFlag(CGameWorld *pGameWorld, int Team)
: CEntity(pGameWorld, NETOBJTYPE_FLAG) : CEntity(pGameWorld, CGameWorld::ENTTYPE_FLAG)
{ {
m_Team = Team; m_Team = Team;
m_ProximityRadius = ms_PhysSize; m_ProximityRadius = ms_PhysSize;

View file

@ -5,7 +5,7 @@
#include "laser.h" #include "laser.h"
CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner) CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner)
: CEntity(pGameWorld, NETOBJTYPE_LASER) : CEntity(pGameWorld, CGameWorld::ENTTYPE_LASER)
{ {
m_Pos = Pos; m_Pos = Pos;
m_Owner = Owner; m_Owner = Owner;

View file

@ -5,7 +5,7 @@
#include "pickup.h" #include "pickup.h"
CPickup::CPickup(CGameWorld *pGameWorld, int Type, int SubType) CPickup::CPickup(CGameWorld *pGameWorld, int Type, int SubType)
: CEntity(pGameWorld, NETOBJTYPE_PICKUP) : CEntity(pGameWorld, CGameWorld::ENTTYPE_PICKUP)
{ {
m_Type = Type; m_Type = Type;
m_Subtype = SubType; m_Subtype = SubType;
@ -91,12 +91,9 @@ void CPickup::Tick()
RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime; RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
// loop through all players, setting their emotes // loop through all players, setting their emotes
CEntity *apEnts[64]; CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
int Num = GameServer()->m_World.FindEntities(vec2(0, 0), 1000000, apEnts, 64, NETOBJTYPE_CHARACTER); for(; pC; pC = (CCharacter *)pC->TypeNext())
for (int i = 0; i < Num; ++i)
{ {
CCharacter *pC = static_cast<CCharacter *>(apEnts[i]);
if (pC != pChr) if (pC != pChr)
pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed()); pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed());
} }

View file

@ -6,7 +6,7 @@
CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span, CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
int Damage, bool Explosive, float Force, int SoundImpact, int Weapon) int Damage, bool Explosive, float Force, int SoundImpact, int Weapon)
: CEntity(pGameWorld, NETOBJTYPE_PROJECTILE) : CEntity(pGameWorld, CGameWorld::ENTTYPE_PROJECTILE)
{ {
m_Type = Type; m_Type = Type;
m_Pos = Pos; m_Pos = Pos;

View file

@ -11,15 +11,13 @@ CEntity::CEntity(CGameWorld *pGameWorld, int ObjType)
{ {
m_pGameWorld = pGameWorld; m_pGameWorld = pGameWorld;
m_Objtype = ObjType; m_ObjType = ObjType;
m_Pos = vec2(0,0); m_Pos = vec2(0,0);
m_ProximityRadius = 0; m_ProximityRadius = 0;
m_MarkedForDestroy = false; m_MarkedForDestroy = false;
m_Id = Server()->SnapNewID(); m_Id = Server()->SnapNewID();
m_pNextEntity = 0;
m_pPrevEntity = 0;
m_pPrevTypeEntity = 0; m_pPrevTypeEntity = 0;
m_pNextTypeEntity = 0; m_pNextTypeEntity = 0;
} }

View file

@ -57,11 +57,8 @@
class CEntity class CEntity
{ {
MACRO_ALLOC_HEAP() MACRO_ALLOC_HEAP()
private:
friend class CGameWorld; // thy these?
CEntity *m_pPrevEntity;
CEntity *m_pNextEntity;
friend class CGameWorld; // entity list handling
CEntity *m_pPrevTypeEntity; CEntity *m_pPrevTypeEntity;
CEntity *m_pNextTypeEntity; CEntity *m_pNextTypeEntity;
@ -69,7 +66,7 @@ private:
protected: protected:
bool m_MarkedForDestroy; bool m_MarkedForDestroy;
int m_Id; int m_Id;
int m_Objtype; int m_ObjType;
public: public:
CEntity(CGameWorld *pGameWorld, int Objtype); CEntity(CGameWorld *pGameWorld, int Objtype);
virtual ~CEntity(); virtual ~CEntity();

View file

@ -125,10 +125,10 @@ void CGameContext::CreateExplosion(vec2 p, int Owner, int Weapon, bool NoDamage)
if (!NoDamage) if (!NoDamage)
{ {
// deal damage // deal damage
CCharacter *apEnts[64]; CCharacter *apEnts[MAX_CLIENTS];
float Radius = 135.0f; float Radius = 135.0f;
float InnerRadius = 48.0f; float InnerRadius = 48.0f;
int Num = m_World.FindEntities(p, Radius, (CEntity**)apEnts, 64, NETOBJTYPE_CHARACTER); int Num = m_World.FindEntities(p, Radius, (CEntity**)apEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
for(int i = 0; i < Num; i++) for(int i = 0; i < Num; i++)
{ {
vec2 Diff = apEnts[i]->m_Pos - p; vec2 Diff = apEnts[i]->m_Pos - p;

View file

@ -42,7 +42,7 @@ IGameController::~IGameController()
float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos) float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos)
{ {
float Score = 0.0f; float Score = 0.0f;
CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(NETOBJTYPE_CHARACTER)); CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
for(; pC; pC = (CCharacter *)pC->TypeNext()) for(; pC; pC = (CCharacter *)pC->TypeNext())
{ {
// team mates are not as dangerous as enemies // team mates are not as dangerous as enemies

View file

@ -139,7 +139,7 @@ void CGameControllerCTF::Tick()
else else
{ {
CCharacter *apCloseCCharacters[MAX_CLIENTS]; CCharacter *apCloseCCharacters[MAX_CLIENTS];
int Num = GameServer()->m_World.FindEntities(F->m_Pos, CFlag::ms_PhysSize, (CEntity**)apCloseCCharacters, MAX_CLIENTS, NETOBJTYPE_CHARACTER); int Num = GameServer()->m_World.FindEntities(F->m_Pos, CFlag::ms_PhysSize, (CEntity**)apCloseCCharacters, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
for(int i = 0; i < Num; i++) for(int i = 0; i < Num; i++)
{ {
if(!apCloseCCharacters[i]->IsAlive() || apCloseCCharacters[i]->GetPlayer()->GetTeam() == TEAM_SPECTATORS || GameServer()->Collision()->IntersectLine(F->m_Pos, apCloseCCharacters[i]->m_Pos, NULL, NULL)) if(!apCloseCCharacters[i]->IsAlive() || apCloseCCharacters[i]->GetPlayer()->GetTeam() == TEAM_SPECTATORS || GameServer()->Collision()->IntersectLine(F->m_Pos, apCloseCCharacters[i]->m_Pos, NULL, NULL))

View file

@ -15,16 +15,16 @@ CGameWorld::CGameWorld()
m_Paused = false; m_Paused = false;
m_ResetRequested = false; m_ResetRequested = false;
m_pFirstEntity = 0x0; for(int i = 0; i < NUM_ENTTYPES; i++)
for(int i = 0; i < NUM_ENT_TYPES; i++)
m_apFirstEntityTypes[i] = 0; m_apFirstEntityTypes[i] = 0;
} }
CGameWorld::~CGameWorld() CGameWorld::~CGameWorld()
{ {
// delete all entities // delete all entities
while(m_pFirstEntity) for(int i = 0; i < NUM_ENTTYPES; i++)
delete m_pFirstEntity; while(m_apFirstEntityTypes[i])
delete m_apFirstEntityTypes[i];
} }
void CGameWorld::SetGameServer(CGameContext *pGameServer) void CGameWorld::SetGameServer(CGameContext *pGameServer)
@ -35,15 +35,16 @@ void CGameWorld::SetGameServer(CGameContext *pGameServer)
CEntity *CGameWorld::FindFirst(int Type) CEntity *CGameWorld::FindFirst(int Type)
{ {
return m_apFirstEntityTypes[Type]; return Type < 0 || Type >= NUM_ENTTYPES ? 0 : m_apFirstEntityTypes[Type];
} }
int CGameWorld::FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type) int CGameWorld::FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type)
{ {
if(Type < 0 || Type >= NUM_ENTTYPES)
return 0;
int Num = 0; int Num = 0;
for(CEntity *pEnt = (Type<0) ? m_pFirstEntity : m_apFirstEntityTypes[Type]; for(CEntity *pEnt = m_apFirstEntityTypes[Type]; pEnt; pEnt = pEnt->m_pNextTypeEntity)
pEnt; pEnt = (Type<0) ? pEnt->m_pNextEntity : pEnt->m_pNextTypeEntity)
{ {
if(distance(pEnt->m_Pos, Pos) < Radius+pEnt->m_ProximityRadius) if(distance(pEnt->m_Pos, Pos) < Radius+pEnt->m_ProximityRadius)
{ {
@ -59,26 +60,17 @@ int CGameWorld::FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max,
void CGameWorld::InsertEntity(CEntity *pEnt) void CGameWorld::InsertEntity(CEntity *pEnt)
{ {
CEntity *pCur = m_pFirstEntity; #ifdef CONF_DEBUG
while(pCur) for(CEntity *pCur = m_apFirstEntityTypes[pEnt->m_Objtype]; pCur; pCur = pCur->m_pNextTypeEntity)
{
dbg_assert(pCur != pEnt, "err"); dbg_assert(pCur != pEnt, "err");
pCur = pCur->m_pNextEntity; #endif
}
// insert it // insert it
if(m_pFirstEntity) if(m_apFirstEntityTypes[pEnt->m_ObjType])
m_pFirstEntity->m_pPrevEntity = pEnt; m_apFirstEntityTypes[pEnt->m_ObjType]->m_pPrevTypeEntity = pEnt;
pEnt->m_pNextEntity = m_pFirstEntity; pEnt->m_pNextTypeEntity = m_apFirstEntityTypes[pEnt->m_ObjType];
pEnt->m_pPrevEntity = 0x0;
m_pFirstEntity = pEnt;
// into typelist aswell
if(m_apFirstEntityTypes[pEnt->m_Objtype])
m_apFirstEntityTypes[pEnt->m_Objtype]->m_pPrevTypeEntity = pEnt;
pEnt->m_pNextTypeEntity = m_apFirstEntityTypes[pEnt->m_Objtype];
pEnt->m_pPrevTypeEntity = 0x0; pEnt->m_pPrevTypeEntity = 0x0;
m_apFirstEntityTypes[pEnt->m_Objtype] = pEnt; m_apFirstEntityTypes[pEnt->m_ObjType] = pEnt;
} }
void CGameWorld::DestroyEntity(CEntity *pEnt) void CGameWorld::DestroyEntity(CEntity *pEnt)
@ -89,30 +81,21 @@ void CGameWorld::DestroyEntity(CEntity *pEnt)
void CGameWorld::RemoveEntity(CEntity *pEnt) void CGameWorld::RemoveEntity(CEntity *pEnt)
{ {
// not in the list // not in the list
if(!pEnt->m_pNextEntity && !pEnt->m_pPrevEntity && m_pFirstEntity != pEnt) if(!pEnt->m_pNextTypeEntity && !pEnt->m_pPrevTypeEntity && m_apFirstEntityTypes[pEnt->m_ObjType] != pEnt)
return; return;
// remove // remove
if(pEnt->m_pPrevEntity)
pEnt->m_pPrevEntity->m_pNextEntity = pEnt->m_pNextEntity;
else
m_pFirstEntity = pEnt->m_pNextEntity;
if(pEnt->m_pNextEntity)
pEnt->m_pNextEntity->m_pPrevEntity = pEnt->m_pPrevEntity;
if(pEnt->m_pPrevTypeEntity) if(pEnt->m_pPrevTypeEntity)
pEnt->m_pPrevTypeEntity->m_pNextTypeEntity = pEnt->m_pNextTypeEntity; pEnt->m_pPrevTypeEntity->m_pNextTypeEntity = pEnt->m_pNextTypeEntity;
else else
m_apFirstEntityTypes[pEnt->m_Objtype] = pEnt->m_pNextTypeEntity; m_apFirstEntityTypes[pEnt->m_ObjType] = pEnt->m_pNextTypeEntity;
if(pEnt->m_pNextTypeEntity) if(pEnt->m_pNextTypeEntity)
pEnt->m_pNextTypeEntity->m_pPrevTypeEntity = pEnt->m_pPrevTypeEntity; pEnt->m_pNextTypeEntity->m_pPrevTypeEntity = pEnt->m_pPrevTypeEntity;
// keep list traversing valid // keep list traversing valid
if(m_pNextTraverseEntity == pEnt) if(m_pNextTraverseEntity == pEnt)
m_pNextTraverseEntity = pEnt->m_pNextEntity; m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
pEnt->m_pNextEntity = 0;
pEnt->m_pPrevEntity = 0;
pEnt->m_pNextTypeEntity = 0; pEnt->m_pNextTypeEntity = 0;
pEnt->m_pPrevTypeEntity = 0; pEnt->m_pPrevTypeEntity = 0;
} }
@ -120,9 +103,10 @@ void CGameWorld::RemoveEntity(CEntity *pEnt)
// //
void CGameWorld::Snap(int SnappingClient) void CGameWorld::Snap(int SnappingClient)
{ {
for(CEntity *pEnt = m_pFirstEntity; pEnt; ) for(int i = 0; i < NUM_ENTTYPES; i++)
for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; )
{ {
m_pNextTraverseEntity = pEnt->m_pNextEntity; m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
pEnt->Snap(SnappingClient); pEnt->Snap(SnappingClient);
pEnt = m_pNextTraverseEntity; pEnt = m_pNextTraverseEntity;
} }
@ -131,9 +115,10 @@ void CGameWorld::Snap(int SnappingClient)
void CGameWorld::Reset() void CGameWorld::Reset()
{ {
// reset all entities // reset all entities
for(CEntity *pEnt = m_pFirstEntity; pEnt; ) for(int i = 0; i < NUM_ENTTYPES; i++)
for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; )
{ {
m_pNextTraverseEntity = pEnt->m_pNextEntity; m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
pEnt->Reset(); pEnt->Reset();
pEnt = m_pNextTraverseEntity; pEnt = m_pNextTraverseEntity;
} }
@ -148,10 +133,10 @@ void CGameWorld::Reset()
void CGameWorld::RemoveEntities() void CGameWorld::RemoveEntities()
{ {
// destroy objects marked for destruction // destroy objects marked for destruction
CEntity *pEnt = m_pFirstEntity; for(int i = 0; i < NUM_ENTTYPES; i++)
while(pEnt) for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; )
{ {
m_pNextTraverseEntity = pEnt->m_pNextEntity; m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
if(pEnt->m_MarkedForDestroy) if(pEnt->m_MarkedForDestroy)
{ {
RemoveEntity(pEnt); RemoveEntity(pEnt);
@ -171,16 +156,18 @@ void CGameWorld::Tick()
if(GameServer()->m_pController->IsForceBalanced()) if(GameServer()->m_pController->IsForceBalanced())
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced"); GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced");
// update all objects // update all objects
for(CEntity *pEnt = m_pFirstEntity; pEnt; ) for(int i = 0; i < NUM_ENTTYPES; i++)
for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; )
{ {
m_pNextTraverseEntity = pEnt->m_pNextEntity; m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
pEnt->Tick(); pEnt->Tick();
pEnt = m_pNextTraverseEntity; pEnt = m_pNextTraverseEntity;
} }
for(CEntity *pEnt = m_pFirstEntity; pEnt; ) for(int i = 0; i < NUM_ENTTYPES; i++)
for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; )
{ {
m_pNextTraverseEntity = pEnt->m_pNextEntity; m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
pEnt->TickDefered(); pEnt->TickDefered();
pEnt = m_pNextTraverseEntity; pEnt = m_pNextTraverseEntity;
} }
@ -198,7 +185,7 @@ CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, v
vec2 LineDir = normalize(Pos1-Pos0); vec2 LineDir = normalize(Pos1-Pos0);
CCharacter *pClosest = 0; CCharacter *pClosest = 0;
CCharacter *p = (CCharacter *)FindFirst(NETOBJTYPE_CHARACTER); CCharacter *p = (CCharacter *)FindFirst(ENTTYPE_CHARACTER);
for(; p; p = (CCharacter *)p->TypeNext()) for(; p; p = (CCharacter *)p->TypeNext())
{ {
if(p == pNotThis) if(p == pNotThis)
@ -228,7 +215,7 @@ CCharacter *CGameWorld::ClosestCharacter(vec2 Pos, float Radius, CEntity *pNotTh
float ClosestRange = Radius*2; float ClosestRange = Radius*2;
CCharacter *pClosest = 0; CCharacter *pClosest = 0;
CCharacter *p = (CCharacter *)GameServer()->m_World.FindFirst(NETOBJTYPE_CHARACTER); CCharacter *p = (CCharacter *)GameServer()->m_World.FindFirst(ENTTYPE_CHARACTER);
for(; p; p = (CCharacter *)p->TypeNext()) for(; p; p = (CCharacter *)p->TypeNext())
{ {
if(p == pNotThis) if(p == pNotThis)

View file

@ -15,18 +15,23 @@ class CCharacter;
*/ */
class CGameWorld class CGameWorld
{ {
public:
enum
{
ENTTYPE_PROJECTILE = 0,
ENTTYPE_LASER,
ENTTYPE_PICKUP,
ENTTYPE_FLAG,
ENTTYPE_CHARACTER,
NUM_ENTTYPES
};
private:
void Reset(); void Reset();
void RemoveEntities(); void RemoveEntities();
enum
{
NUM_ENT_TYPES=10, // TODO: are more exact value perhaps? :)
};
// TODO: two lists seams kinda not good, shouldn't be needed
CEntity *m_pNextTraverseEntity; CEntity *m_pNextTraverseEntity;
CEntity *m_pFirstEntity; CEntity *m_apFirstEntityTypes[NUM_ENTTYPES];
CEntity *m_apFirstEntityTypes[NUM_ENT_TYPES];
class CGameContext *m_pGameServer; class CGameContext *m_pGameServer;
class IServer *m_pServer; class IServer *m_pServer;
@ -44,7 +49,6 @@ public:
void SetGameServer(CGameContext *pGameServer); void SetGameServer(CGameContext *pGameServer);
CEntity *FindFirst() { return m_pFirstEntity; }
CEntity *FindFirst(int Type); CEntity *FindFirst(int Type);
/* /*
@ -57,12 +61,12 @@ public:
ents - Pointer to a list that should be filled with the pointers ents - Pointer to a list that should be filled with the pointers
to the entities. to the entities.
max - Number of entities that fits into the ents array. max - Number of entities that fits into the ents array.
type - Type of the entities to find. -1 for all types. type - Type of the entities to find.
Returns: Returns:
Number of entities found and added to the ents array. Number of entities found and added to the ents array.
*/ */
int FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type = -1); int FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type);
/* /*
Function: interserct_CCharacter Function: interserct_CCharacter

View file

@ -208,7 +208,7 @@ void CPlayer::TryRespawn()
// check if the position is occupado // check if the position is occupado
CEntity *apEnts[2] = {0}; CEntity *apEnts[2] = {0};
int NumEnts = GameServer()->m_World.FindEntities(SpawnPos, 64, apEnts, 2, NETOBJTYPE_CHARACTER); int NumEnts = GameServer()->m_World.FindEntities(SpawnPos, 64, apEnts, 2, CGameWorld::ENTTYPE_CHARACTER);
if(NumEnts == 0) if(NumEnts == 0)
{ {