diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 0a3dd87bd..53c75e3df 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -40,7 +40,7 @@ MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS) // Character, "physical" player's part CCharacter::CCharacter(CGameWorld *pWorld) -: CEntity(pWorld, NETOBJTYPE_CHARACTER) +: CEntity(pWorld, CGameWorld::ENTTYPE_CHARACTER) { m_ProximityRadius = ms_PhysSize; m_Health = 0; @@ -153,11 +153,11 @@ void CCharacter::HandleNinja() // check if we Hit anything along the way { - CCharacter *aEnts[64]; + CCharacter *aEnts[MAX_CLIENTS]; vec2 Dir = m_Pos - OldPos; float Radius = m_ProximityRadius * 2.0f; 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) { @@ -289,10 +289,10 @@ void CCharacter::FireWeapon() m_NumObjectsHit = 0; GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE); - CCharacter *apEnts[64]; + CCharacter *apEnts[MAX_CLIENTS]; int Hits = 0; 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) { diff --git a/src/game/server/entities/flag.cpp b/src/game/server/entities/flag.cpp index 4d034214d..13109b077 100644 --- a/src/game/server/entities/flag.cpp +++ b/src/game/server/entities/flag.cpp @@ -4,7 +4,7 @@ #include "flag.h" CFlag::CFlag(CGameWorld *pGameWorld, int Team) -: CEntity(pGameWorld, NETOBJTYPE_FLAG) +: CEntity(pGameWorld, CGameWorld::ENTTYPE_FLAG) { m_Team = Team; m_ProximityRadius = ms_PhysSize; diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp index 17eb43321..2f6568faf 100644 --- a/src/game/server/entities/laser.cpp +++ b/src/game/server/entities/laser.cpp @@ -5,7 +5,7 @@ #include "laser.h" 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_Owner = Owner; diff --git a/src/game/server/entities/pickup.cpp b/src/game/server/entities/pickup.cpp index a2c6f650f..136e3efe2 100644 --- a/src/game/server/entities/pickup.cpp +++ b/src/game/server/entities/pickup.cpp @@ -5,7 +5,7 @@ #include "pickup.h" CPickup::CPickup(CGameWorld *pGameWorld, int Type, int SubType) -: CEntity(pGameWorld, NETOBJTYPE_PICKUP) +: CEntity(pGameWorld, CGameWorld::ENTTYPE_PICKUP) { m_Type = Type; m_Subtype = SubType; @@ -91,12 +91,9 @@ void CPickup::Tick() RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime; // loop through all players, setting their emotes - CEntity *apEnts[64]; - int Num = GameServer()->m_World.FindEntities(vec2(0, 0), 1000000, apEnts, 64, NETOBJTYPE_CHARACTER); - - for (int i = 0; i < Num; ++i) + CCharacter *pC = static_cast(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER)); + for(; pC; pC = (CCharacter *)pC->TypeNext()) { - CCharacter *pC = static_cast(apEnts[i]); if (pC != pChr) pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed()); } diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp index f5c376a2f..6e256e955 100644 --- a/src/game/server/entities/projectile.cpp +++ b/src/game/server/entities/projectile.cpp @@ -6,7 +6,7 @@ CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span, int Damage, bool Explosive, float Force, int SoundImpact, int Weapon) -: CEntity(pGameWorld, NETOBJTYPE_PROJECTILE) +: CEntity(pGameWorld, CGameWorld::ENTTYPE_PROJECTILE) { m_Type = Type; m_Pos = Pos; diff --git a/src/game/server/entity.cpp b/src/game/server/entity.cpp index 5241c06b1..aff36943c 100644 --- a/src/game/server/entity.cpp +++ b/src/game/server/entity.cpp @@ -11,15 +11,13 @@ CEntity::CEntity(CGameWorld *pGameWorld, int ObjType) { m_pGameWorld = pGameWorld; - m_Objtype = ObjType; + m_ObjType = ObjType; m_Pos = vec2(0,0); m_ProximityRadius = 0; m_MarkedForDestroy = false; m_Id = Server()->SnapNewID(); - m_pNextEntity = 0; - m_pPrevEntity = 0; m_pPrevTypeEntity = 0; m_pNextTypeEntity = 0; } diff --git a/src/game/server/entity.h b/src/game/server/entity.h index dc50daca7..d56c60e77 100644 --- a/src/game/server/entity.h +++ b/src/game/server/entity.h @@ -57,11 +57,8 @@ class CEntity { 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_pNextTypeEntity; @@ -69,7 +66,7 @@ private: protected: bool m_MarkedForDestroy; int m_Id; - int m_Objtype; + int m_ObjType; public: CEntity(CGameWorld *pGameWorld, int Objtype); virtual ~CEntity(); diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 906b9801f..063e3a005 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -125,10 +125,10 @@ void CGameContext::CreateExplosion(vec2 p, int Owner, int Weapon, bool NoDamage) if (!NoDamage) { // deal damage - CCharacter *apEnts[64]; + CCharacter *apEnts[MAX_CLIENTS]; float Radius = 135.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++) { vec2 Diff = apEnts[i]->m_Pos - p; diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index 8ba693989..f4b6d33ce 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -42,7 +42,7 @@ IGameController::~IGameController() float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos) { float Score = 0.0f; - CCharacter *pC = static_cast(GameServer()->m_World.FindFirst(NETOBJTYPE_CHARACTER)); + CCharacter *pC = static_cast(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER)); for(; pC; pC = (CCharacter *)pC->TypeNext()) { // team mates are not as dangerous as enemies diff --git a/src/game/server/gamemodes/ctf.cpp b/src/game/server/gamemodes/ctf.cpp index f6681ff69..6cefe4359 100644 --- a/src/game/server/gamemodes/ctf.cpp +++ b/src/game/server/gamemodes/ctf.cpp @@ -139,7 +139,7 @@ void CGameControllerCTF::Tick() else { 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++) { if(!apCloseCCharacters[i]->IsAlive() || apCloseCCharacters[i]->GetPlayer()->GetTeam() == TEAM_SPECTATORS || GameServer()->Collision()->IntersectLine(F->m_Pos, apCloseCCharacters[i]->m_Pos, NULL, NULL)) diff --git a/src/game/server/gameworld.cpp b/src/game/server/gameworld.cpp index 8fc9fec87..b4ab4594b 100644 --- a/src/game/server/gameworld.cpp +++ b/src/game/server/gameworld.cpp @@ -15,16 +15,16 @@ CGameWorld::CGameWorld() m_Paused = false; m_ResetRequested = false; - m_pFirstEntity = 0x0; - for(int i = 0; i < NUM_ENT_TYPES; i++) + for(int i = 0; i < NUM_ENTTYPES; i++) m_apFirstEntityTypes[i] = 0; } CGameWorld::~CGameWorld() { // delete all entities - while(m_pFirstEntity) - delete m_pFirstEntity; + for(int i = 0; i < NUM_ENTTYPES; i++) + while(m_apFirstEntityTypes[i]) + delete m_apFirstEntityTypes[i]; } void CGameWorld::SetGameServer(CGameContext *pGameServer) @@ -35,15 +35,16 @@ void CGameWorld::SetGameServer(CGameContext *pGameServer) 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) { + if(Type < 0 || Type >= NUM_ENTTYPES) + return 0; + int Num = 0; - for(CEntity *pEnt = (Type<0) ? m_pFirstEntity : m_apFirstEntityTypes[Type]; - pEnt; pEnt = (Type<0) ? pEnt->m_pNextEntity : pEnt->m_pNextTypeEntity) + for(CEntity *pEnt = m_apFirstEntityTypes[Type]; pEnt; pEnt = pEnt->m_pNextTypeEntity) { 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) { - CEntity *pCur = m_pFirstEntity; - while(pCur) - { +#ifdef CONF_DEBUG + for(CEntity *pCur = m_apFirstEntityTypes[pEnt->m_Objtype]; pCur; pCur = pCur->m_pNextTypeEntity) dbg_assert(pCur != pEnt, "err"); - pCur = pCur->m_pNextEntity; - } +#endif // insert it - if(m_pFirstEntity) - m_pFirstEntity->m_pPrevEntity = pEnt; - pEnt->m_pNextEntity = m_pFirstEntity; - 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]; + 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; - m_apFirstEntityTypes[pEnt->m_Objtype] = pEnt; + m_apFirstEntityTypes[pEnt->m_ObjType] = pEnt; } void CGameWorld::DestroyEntity(CEntity *pEnt) @@ -89,30 +81,21 @@ void CGameWorld::DestroyEntity(CEntity *pEnt) void CGameWorld::RemoveEntity(CEntity *pEnt) { // 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; // 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) pEnt->m_pPrevTypeEntity->m_pNextTypeEntity = pEnt->m_pNextTypeEntity; else - m_apFirstEntityTypes[pEnt->m_Objtype] = pEnt->m_pNextTypeEntity; + m_apFirstEntityTypes[pEnt->m_ObjType] = pEnt->m_pNextTypeEntity; if(pEnt->m_pNextTypeEntity) pEnt->m_pNextTypeEntity->m_pPrevTypeEntity = pEnt->m_pPrevTypeEntity; // keep list traversing valid 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_pPrevTypeEntity = 0; } @@ -120,23 +103,25 @@ void CGameWorld::RemoveEntity(CEntity *pEnt) // void CGameWorld::Snap(int SnappingClient) { - for(CEntity *pEnt = m_pFirstEntity; pEnt; ) - { - m_pNextTraverseEntity = pEnt->m_pNextEntity; - pEnt->Snap(SnappingClient); - pEnt = m_pNextTraverseEntity; - } + for(int i = 0; i < NUM_ENTTYPES; i++) + for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; + pEnt->Snap(SnappingClient); + pEnt = m_pNextTraverseEntity; + } } void CGameWorld::Reset() { // reset all entities - for(CEntity *pEnt = m_pFirstEntity; pEnt; ) - { - m_pNextTraverseEntity = pEnt->m_pNextEntity; - pEnt->Reset(); - pEnt = m_pNextTraverseEntity; - } + for(int i = 0; i < NUM_ENTTYPES; i++) + for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; + pEnt->Reset(); + pEnt = m_pNextTraverseEntity; + } RemoveEntities(); GameServer()->m_pController->PostReset(); @@ -148,17 +133,17 @@ void CGameWorld::Reset() void CGameWorld::RemoveEntities() { // destroy objects marked for destruction - CEntity *pEnt = m_pFirstEntity; - while(pEnt) - { - m_pNextTraverseEntity = pEnt->m_pNextEntity; - if(pEnt->m_MarkedForDestroy) + for(int i = 0; i < NUM_ENTTYPES; i++) + for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) { - RemoveEntity(pEnt); - pEnt->Destroy(); + m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; + if(pEnt->m_MarkedForDestroy) + { + RemoveEntity(pEnt); + pEnt->Destroy(); + } + pEnt = m_pNextTraverseEntity; } - pEnt = m_pNextTraverseEntity; - } } void CGameWorld::Tick() @@ -171,19 +156,21 @@ void CGameWorld::Tick() if(GameServer()->m_pController->IsForceBalanced()) GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced"); // update all objects - for(CEntity *pEnt = m_pFirstEntity; pEnt; ) - { - m_pNextTraverseEntity = pEnt->m_pNextEntity; - pEnt->Tick(); - pEnt = m_pNextTraverseEntity; - } + for(int i = 0; i < NUM_ENTTYPES; i++) + for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; + pEnt->Tick(); + pEnt = m_pNextTraverseEntity; + } - for(CEntity *pEnt = m_pFirstEntity; pEnt; ) - { - m_pNextTraverseEntity = pEnt->m_pNextEntity; - pEnt->TickDefered(); - pEnt = m_pNextTraverseEntity; - } + for(int i = 0; i < NUM_ENTTYPES; i++) + for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; + pEnt->TickDefered(); + pEnt = m_pNextTraverseEntity; + } } RemoveEntities(); @@ -198,7 +185,7 @@ CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, v vec2 LineDir = normalize(Pos1-Pos0); CCharacter *pClosest = 0; - CCharacter *p = (CCharacter *)FindFirst(NETOBJTYPE_CHARACTER); + CCharacter *p = (CCharacter *)FindFirst(ENTTYPE_CHARACTER); for(; p; p = (CCharacter *)p->TypeNext()) { if(p == pNotThis) @@ -228,7 +215,7 @@ CCharacter *CGameWorld::ClosestCharacter(vec2 Pos, float Radius, CEntity *pNotTh float ClosestRange = Radius*2; 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()) { if(p == pNotThis) diff --git a/src/game/server/gameworld.h b/src/game/server/gameworld.h index 62d1e58c1..38002b87c 100644 --- a/src/game/server/gameworld.h +++ b/src/game/server/gameworld.h @@ -15,18 +15,23 @@ class CCharacter; */ class CGameWorld { +public: + enum + { + ENTTYPE_PROJECTILE = 0, + ENTTYPE_LASER, + ENTTYPE_PICKUP, + ENTTYPE_FLAG, + ENTTYPE_CHARACTER, + NUM_ENTTYPES + }; + +private: void Reset(); 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_pFirstEntity; - CEntity *m_apFirstEntityTypes[NUM_ENT_TYPES]; + CEntity *m_apFirstEntityTypes[NUM_ENTTYPES]; class CGameContext *m_pGameServer; class IServer *m_pServer; @@ -44,7 +49,6 @@ public: void SetGameServer(CGameContext *pGameServer); - CEntity *FindFirst() { return m_pFirstEntity; } CEntity *FindFirst(int Type); /* @@ -57,12 +61,12 @@ public: ents - Pointer to a list that should be filled with the pointers to the entities. 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: 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 diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index cf75615ee..3f32d6af1 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -208,7 +208,7 @@ void CPlayer::TryRespawn() // check if the position is occupado 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) {