2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "gameworld.h"
|
2021-01-09 14:18:52 +00:00
|
|
|
#include "entities/character.h"
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "entity.h"
|
|
|
|
#include "gamecontext.h"
|
2022-06-17 17:54:10 +00:00
|
|
|
#include "gamecontroller.h"
|
|
|
|
|
2013-12-31 05:13:57 +00:00
|
|
|
#include <engine/shared/config.h>
|
2022-06-17 17:54:10 +00:00
|
|
|
|
|
|
|
#include <algorithm>
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <utility>
|
2008-08-14 18:42:47 +00:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
// game world
|
|
|
|
//////////////////////////////////////////////////
|
2010-05-29 07:25:38 +00:00
|
|
|
CGameWorld::CGameWorld()
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pGameServer = 0x0;
|
2021-01-10 12:47:07 +00:00
|
|
|
m_pConfig = 0x0;
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pServer = 0x0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Paused = false;
|
|
|
|
m_ResetRequested = false;
|
2020-10-26 14:14:07 +00:00
|
|
|
for(auto &pFirstEntityType : m_apFirstEntityTypes)
|
|
|
|
pFirstEntityType = 0;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CGameWorld::~CGameWorld()
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
|
|
|
// delete all entities
|
2020-10-26 14:14:07 +00:00
|
|
|
for(auto &pFirstEntityType : m_apFirstEntityTypes)
|
|
|
|
while(pFirstEntityType)
|
2023-01-23 10:19:19 +00:00
|
|
|
delete pFirstEntityType; // NOLINT(clang-analyzer-cplusplus.NewDelete)
|
2010-05-29 07:25:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CGameWorld::SetGameServer(CGameContext *pGameServer)
|
|
|
|
{
|
|
|
|
m_pGameServer = pGameServer;
|
2021-01-10 12:47:07 +00:00
|
|
|
m_pConfig = m_pGameServer->Config();
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pServer = m_pGameServer->Server();
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CEntity *CGameWorld::FindFirst(int Type)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2011-01-19 17:27:50 +00:00
|
|
|
return Type < 0 || Type >= NUM_ENTTYPES ? 0 : m_apFirstEntityTypes[Type];
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int CGameWorld::FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2011-01-19 17:27:50 +00:00
|
|
|
if(Type < 0 || Type >= NUM_ENTTYPES)
|
|
|
|
return 0;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int Num = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
for(CEntity *pEnt = m_apFirstEntityTypes[Type]; pEnt; pEnt = pEnt->m_pNextTypeEntity)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
if(distance(pEnt->m_Pos, Pos) < Radius + pEnt->m_ProximityRadius)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2011-02-10 11:05:55 +00:00
|
|
|
if(ppEnts)
|
|
|
|
ppEnts[Num] = pEnt;
|
2010-05-29 07:25:38 +00:00
|
|
|
Num++;
|
|
|
|
if(Num == Max)
|
2008-08-14 18:42:47 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
return Num;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CGameWorld::InsertEntity(CEntity *pEnt)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2011-01-19 17:27:50 +00:00
|
|
|
#ifdef CONF_DEBUG
|
2011-01-20 00:35:21 +00:00
|
|
|
for(CEntity *pCur = m_apFirstEntityTypes[pEnt->m_ObjType]; pCur; pCur = pCur->m_pNextTypeEntity)
|
2010-05-29 07:25:38 +00:00
|
|
|
dbg_assert(pCur != pEnt, "err");
|
2011-01-19 17:27:50 +00:00
|
|
|
#endif
|
2008-08-14 18:42:47 +00:00
|
|
|
|
|
|
|
// insert it
|
2011-01-19 17:27:50 +00:00
|
|
|
if(m_apFirstEntityTypes[pEnt->m_ObjType])
|
|
|
|
m_apFirstEntityTypes[pEnt->m_ObjType]->m_pPrevTypeEntity = pEnt;
|
|
|
|
pEnt->m_pNextTypeEntity = m_apFirstEntityTypes[pEnt->m_ObjType];
|
2010-05-29 07:25:38 +00:00
|
|
|
pEnt->m_pPrevTypeEntity = 0x0;
|
2011-01-19 17:27:50 +00:00
|
|
|
m_apFirstEntityTypes[pEnt->m_ObjType] = pEnt;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CGameWorld::RemoveEntity(CEntity *pEnt)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
|
|
|
// not in the list
|
2011-01-19 17:27:50 +00:00
|
|
|
if(!pEnt->m_pNextTypeEntity && !pEnt->m_pPrevTypeEntity && m_apFirstEntityTypes[pEnt->m_ObjType] != pEnt)
|
2008-08-14 18:42:47 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// remove
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pEnt->m_pPrevTypeEntity)
|
|
|
|
pEnt->m_pPrevTypeEntity->m_pNextTypeEntity = pEnt->m_pNextTypeEntity;
|
2008-08-14 18:42:47 +00:00
|
|
|
else
|
2011-01-19 17:27:50 +00:00
|
|
|
m_apFirstEntityTypes[pEnt->m_ObjType] = pEnt->m_pNextTypeEntity;
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pEnt->m_pNextTypeEntity)
|
|
|
|
pEnt->m_pNextTypeEntity->m_pPrevTypeEntity = pEnt->m_pPrevTypeEntity;
|
|
|
|
|
2011-01-19 14:31:42 +00:00
|
|
|
// keep list traversing valid
|
|
|
|
if(m_pNextTraverseEntity == pEnt)
|
2011-01-19 17:27:50 +00:00
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
2011-01-19 14:31:42 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
pEnt->m_pNextTypeEntity = 0;
|
|
|
|
pEnt->m_pPrevTypeEntity = 0;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2010-05-29 07:25:38 +00:00
|
|
|
void CGameWorld::Snap(int SnappingClient)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2021-11-03 17:07:25 +00:00
|
|
|
for(CEntity *pEnt = m_apFirstEntityTypes[ENTTYPE_CHARACTER]; pEnt;)
|
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
pEnt->Snap(SnappingClient);
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int i = 0; i < NUM_ENTTYPES; i++)
|
|
|
|
{
|
|
|
|
if(i == ENTTYPE_CHARACTER)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt;)
|
2011-01-19 17:27:50 +00:00
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
pEnt->Snap(SnappingClient);
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
2021-11-03 17:07:25 +00:00
|
|
|
}
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CGameWorld::Reset()
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
|
|
|
// reset all entities
|
2020-10-26 13:11:11 +00:00
|
|
|
for(auto *pEnt : m_apFirstEntityTypes)
|
|
|
|
for(; pEnt;)
|
2011-01-19 17:27:50 +00:00
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
pEnt->Reset();
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
RemoveEntities();
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2021-01-12 19:39:58 +00:00
|
|
|
GameServer()->m_pController->OnReset();
|
2010-05-29 07:25:38 +00:00
|
|
|
RemoveEntities();
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_ResetRequested = false;
|
2022-12-12 23:06:14 +00:00
|
|
|
|
|
|
|
GameServer()->CreateAllEntities(false);
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
2023-01-04 20:08:47 +00:00
|
|
|
void CGameWorld::RemoveEntitiesFromPlayer(int PlayerId)
|
|
|
|
{
|
|
|
|
RemoveEntitiesFromPlayers(&PlayerId, 1);
|
|
|
|
}
|
|
|
|
|
2023-01-03 21:57:31 +00:00
|
|
|
void CGameWorld::RemoveEntitiesFromPlayers(int PlayerIds[], int NumPlayers)
|
|
|
|
{
|
|
|
|
for(auto *pEnt : m_apFirstEntityTypes)
|
|
|
|
{
|
|
|
|
for(; pEnt;)
|
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
for(int i = 0; i < NumPlayers; i++)
|
|
|
|
{
|
|
|
|
if(pEnt->GetOwnerID() == PlayerIds[i])
|
|
|
|
{
|
|
|
|
RemoveEntity(pEnt);
|
|
|
|
pEnt->Destroy();
|
2023-01-25 17:46:00 +00:00
|
|
|
break;
|
2023-01-03 21:57:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CGameWorld::RemoveEntities()
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
|
|
|
// destroy objects marked for destruction
|
2020-10-26 13:11:11 +00:00
|
|
|
for(auto *pEnt : m_apFirstEntityTypes)
|
|
|
|
for(; pEnt;)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2011-01-19 17:27:50 +00:00
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
if(pEnt->m_MarkedForDestroy)
|
|
|
|
{
|
|
|
|
RemoveEntity(pEnt);
|
|
|
|
pEnt->Destroy();
|
|
|
|
}
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CGameWorld::Tick()
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_ResetRequested)
|
|
|
|
Reset();
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!m_Paused)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(GameServer()->m_pController->IsForceBalanced())
|
|
|
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced");
|
2022-08-24 15:52:31 +00:00
|
|
|
|
2008-08-14 18:42:47 +00:00
|
|
|
// update all objects
|
2022-08-24 15:52:31 +00:00
|
|
|
for(int i = 0; i < NUM_ENTTYPES; i++)
|
2022-07-19 16:34:49 +00:00
|
|
|
{
|
2022-08-24 15:52:31 +00:00
|
|
|
// It's important to call PreTick() and Tick() after each other.
|
|
|
|
// If we call PreTick() before, and Tick() after other entities have been processed, it causes physics changes such as a stronger shotgun or grenade.
|
2022-10-27 15:50:08 +00:00
|
|
|
if(g_Config.m_SvNoWeakHook && i == ENTTYPE_CHARACTER)
|
2022-08-24 15:52:31 +00:00
|
|
|
{
|
|
|
|
auto *pEnt = m_apFirstEntityTypes[i];
|
2022-07-19 16:34:49 +00:00
|
|
|
for(; pEnt;)
|
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
2022-08-24 15:52:31 +00:00
|
|
|
((CCharacter *)pEnt)->PreTick();
|
2022-07-19 16:34:49 +00:00
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
2022-08-24 15:52:31 +00:00
|
|
|
}
|
2022-07-19 16:34:49 +00:00
|
|
|
|
2022-08-24 15:52:31 +00:00
|
|
|
auto *pEnt = m_apFirstEntityTypes[i];
|
2020-10-26 13:11:11 +00:00
|
|
|
for(; pEnt;)
|
2011-01-19 17:27:50 +00:00
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
pEnt->Tick();
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
2022-08-24 15:52:31 +00:00
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-10-26 13:11:11 +00:00
|
|
|
for(auto *pEnt : m_apFirstEntityTypes)
|
|
|
|
for(; pEnt;)
|
2011-01-19 17:27:50 +00:00
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
2022-07-19 16:22:44 +00:00
|
|
|
pEnt->TickDeferred();
|
2011-01-19 17:27:50 +00:00
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
2012-01-09 23:49:31 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// update all objects
|
2020-10-26 13:11:11 +00:00
|
|
|
for(auto *pEnt : m_apFirstEntityTypes)
|
|
|
|
for(; pEnt;)
|
2012-01-09 23:49:31 +00:00
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
pEnt->TickPaused();
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
|
|
|
}
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
RemoveEntities();
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2019-05-01 22:34:20 +00:00
|
|
|
// find the characters' strong/weak id
|
|
|
|
int StrongWeakID = 0;
|
2020-09-26 19:41:58 +00:00
|
|
|
for(CCharacter *pChar = (CCharacter *)FindFirst(ENTTYPE_CHARACTER); pChar; pChar = (CCharacter *)pChar->TypeNext())
|
2019-05-01 22:34:20 +00:00
|
|
|
{
|
|
|
|
pChar->m_StrongWeakID = StrongWeakID;
|
|
|
|
StrongWeakID++;
|
|
|
|
}
|
2013-12-31 05:13:57 +00:00
|
|
|
}
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2021-12-14 09:35:00 +00:00
|
|
|
void CGameWorld::SwapClients(int Client1, int Client2)
|
|
|
|
{
|
|
|
|
// update all objects
|
|
|
|
for(auto *pEnt : m_apFirstEntityTypes)
|
|
|
|
for(; pEnt;)
|
|
|
|
{
|
|
|
|
m_pNextTraverseEntity = pEnt->m_pNextTypeEntity;
|
|
|
|
pEnt->SwapClients(Client1, Client2);
|
|
|
|
pEnt = m_pNextTraverseEntity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-14 18:42:47 +00:00
|
|
|
// TODO: should be more general
|
Mark parameters as `const` when possible
According to cppchecker's `constParameter` error:
```
src\engine\gfx\image_manipulation.cpp:7:58: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void Dilate(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest, unsigned char AlphaThreshold = TW_DILATE_ALPHA_THRESHOLD)
^
src\engine\gfx\image_manipulation.cpp:58:67: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void CopyColorValues(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest)
^
src\engine\shared\network_conn.cpp:241:42: style: Parameter 'Addr' can be declared as reference to const [constParameter]
void CNetConnection::DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken, SECURITY_TOKEN Token, bool Sixup)
^
src\base\system.cpp:4060:71: style: Parameter 'random' can be declared as pointer to const [constParameter]
void generate_password(char *buffer, unsigned length, unsigned short *random, unsigned random_length)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:263:38: style: Parameter 'AllocatedMemory' can be declared as reference to const [constParameter]
void Free(SMemoryHeapQueueElement &AllocatedMemory)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:1708:47: style: Parameter 'ImgExtent' can be declared as reference to const [constParameter]
static size_t ImageMipLevelCount(VkExtent3D &ImgExtent)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:2801:29: style: Parameter 'Image' can be declared as reference to const [constParameter]
void ImageBarrier(VkImage &Image, size_t MipMapBase, size_t MipMapCount, size_t LayerBase, size_t LayerCount, VkFormat Format, VkImageLayout OldLayout, VkImageLayout NewLayout)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:6495:46: style: Parameter 'ExecBuffer' can be declared as reference to const [constParameter]
void Cmd_Clear(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_Clear *pCommand)
^
src\game\client\components\skins.cpp:83:72: style: Parameter 'pImg' can be declared as pointer to const [constParameter]
static void CheckMetrics(CSkin::SSkinMetricVariable &Metrics, uint8_t *pImg, int ImgWidth, int ImgX, int ImgY, int CheckWidth, int CheckHeight)
^
src\game\client\prediction\entities\character.h:106:37: style: Parameter 'pNewInput' can be declared as pointer to const [constParameter]
void SetInput(CNetObj_PlayerInput *pNewInput)
^
src\game\client\prediction\gameworld.cpp:245:106: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
^
src\game\client\prediction\gameworld.cpp:245:151: style: Parameter 'pThisOnly' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
^
src\game\client\prediction\gameworld.cpp:283:116: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
std::list<class CCharacter *> CGameWorld::IntersectedCharacters(vec2 Pos0, vec2 Pos1, float Radius, class CEntity *pNotThis)
^
src\game\client\ui.cpp:522:180: style: Parameter 'pReadCursor' can be declared as pointer to const [constParameter]
void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, CTextCursor *pReadCursor)
^
src\game\client\ui_scrollregion.cpp:23:86: style: Parameter 'pParams' can be declared as pointer to const [constParameter]
void CScrollRegion::Begin(CUIRect *pClipRect, vec2 *pOutOffset, CScrollRegionParams *pParams)
^
src\game\server\scoreworker.h:239:29: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
void Set(float Time, float aTimeCp[NUM_CHECKPOINTS])
^
src\game\server\score.cpp:135:80: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
void CScore::SaveScore(int ClientID, float Time, const char *pTimestamp, float aTimeCp[NUM_CHECKPOINTS], bool NotEligible)
^
src\game\server\teeinfo.cpp:40:57: style: Parameter 'pUseCustomColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
^
src\game\server\teeinfo.cpp:40:80: style: Parameter 'pSkinPartColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
^
```
2022-11-13 14:32:53 +00:00
|
|
|
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, const CCharacter *pNotThis, int CollideWith, const CCharacter *pThisOnly)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
|
|
|
// Find other players
|
2019-12-09 13:58:22 +00:00
|
|
|
float ClosestLen = distance(Pos0, Pos1) * 100.0f;
|
2010-05-29 07:25:38 +00:00
|
|
|
CCharacter *pClosest = 0;
|
2008-08-14 18:42:47 +00:00
|
|
|
|
2011-01-19 17:27:50 +00:00
|
|
|
CCharacter *p = (CCharacter *)FindFirst(ENTTYPE_CHARACTER);
|
2010-05-29 07:25:38 +00:00
|
|
|
for(; p; p = (CCharacter *)p->TypeNext())
|
2015-07-09 00:08:14 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(p == pNotThis)
|
2008-08-14 18:42:47 +00:00
|
|
|
continue;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2019-10-14 14:03:28 +00:00
|
|
|
if(pThisOnly && p != pThisOnly)
|
|
|
|
continue;
|
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
if(CollideWith != -1 && !p->CanCollide(CollideWith))
|
|
|
|
continue;
|
|
|
|
|
2020-10-17 18:22:13 +00:00
|
|
|
vec2 IntersectPos;
|
|
|
|
if(closest_point_on_line(Pos0, Pos1, p->m_Pos, IntersectPos))
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2020-10-17 18:22:13 +00:00
|
|
|
float Len = distance(p->m_Pos, IntersectPos);
|
|
|
|
if(Len < p->m_ProximityRadius + Radius)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2020-10-17 18:22:13 +00:00
|
|
|
Len = distance(Pos0, IntersectPos);
|
|
|
|
if(Len < ClosestLen)
|
|
|
|
{
|
|
|
|
NewPos = IntersectPos;
|
|
|
|
ClosestLen = Len;
|
|
|
|
pClosest = p;
|
|
|
|
}
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
return pClosest;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
|
Mark parameters as `const` when possible
According to cppchecker's `constParameter` error:
```
src\engine\gfx\image_manipulation.cpp:7:58: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void Dilate(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest, unsigned char AlphaThreshold = TW_DILATE_ALPHA_THRESHOLD)
^
src\engine\gfx\image_manipulation.cpp:58:67: style: Parameter 'pSrc' can be declared as pointer to const [constParameter]
static void CopyColorValues(int w, int h, int BPP, unsigned char *pSrc, unsigned char *pDest)
^
src\engine\shared\network_conn.cpp:241:42: style: Parameter 'Addr' can be declared as reference to const [constParameter]
void CNetConnection::DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken, SECURITY_TOKEN Token, bool Sixup)
^
src\base\system.cpp:4060:71: style: Parameter 'random' can be declared as pointer to const [constParameter]
void generate_password(char *buffer, unsigned length, unsigned short *random, unsigned random_length)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:263:38: style: Parameter 'AllocatedMemory' can be declared as reference to const [constParameter]
void Free(SMemoryHeapQueueElement &AllocatedMemory)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:1708:47: style: Parameter 'ImgExtent' can be declared as reference to const [constParameter]
static size_t ImageMipLevelCount(VkExtent3D &ImgExtent)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:2801:29: style: Parameter 'Image' can be declared as reference to const [constParameter]
void ImageBarrier(VkImage &Image, size_t MipMapBase, size_t MipMapCount, size_t LayerBase, size_t LayerCount, VkFormat Format, VkImageLayout OldLayout, VkImageLayout NewLayout)
^
src\engine\client\backend\vulkan\backend_vulkan.cpp:6495:46: style: Parameter 'ExecBuffer' can be declared as reference to const [constParameter]
void Cmd_Clear(SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand_Clear *pCommand)
^
src\game\client\components\skins.cpp:83:72: style: Parameter 'pImg' can be declared as pointer to const [constParameter]
static void CheckMetrics(CSkin::SSkinMetricVariable &Metrics, uint8_t *pImg, int ImgWidth, int ImgX, int ImgY, int CheckWidth, int CheckHeight)
^
src\game\client\prediction\entities\character.h:106:37: style: Parameter 'pNewInput' can be declared as pointer to const [constParameter]
void SetInput(CNetObj_PlayerInput *pNewInput)
^
src\game\client\prediction\gameworld.cpp:245:106: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
^
src\game\client\prediction\gameworld.cpp:245:151: style: Parameter 'pThisOnly' can be declared as pointer to const [constParameter]
CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, CCharacter *pNotThis, int CollideWith, class CCharacter *pThisOnly)
^
src\game\client\prediction\gameworld.cpp:283:116: style: Parameter 'pNotThis' can be declared as pointer to const [constParameter]
std::list<class CCharacter *> CGameWorld::IntersectedCharacters(vec2 Pos0, vec2 Pos1, float Radius, class CEntity *pNotThis)
^
src\game\client\ui.cpp:522:180: style: Parameter 'pReadCursor' can be declared as pointer to const [constParameter]
void CUI::DoLabel(CUIElement::SUIElementRect &RectEl, const CUIRect *pRect, const char *pText, float Size, int Align, const SLabelProperties &LabelProps, int StrLen, CTextCursor *pReadCursor)
^
src\game\client\ui_scrollregion.cpp:23:86: style: Parameter 'pParams' can be declared as pointer to const [constParameter]
void CScrollRegion::Begin(CUIRect *pClipRect, vec2 *pOutOffset, CScrollRegionParams *pParams)
^
src\game\server\scoreworker.h:239:29: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
void Set(float Time, float aTimeCp[NUM_CHECKPOINTS])
^
src\game\server\score.cpp:135:80: style: Parameter 'aTimeCp' can be declared as const array [constParameter]
void CScore::SaveScore(int ClientID, float Time, const char *pTimestamp, float aTimeCp[NUM_CHECKPOINTS], bool NotEligible)
^
src\game\server\teeinfo.cpp:40:57: style: Parameter 'pUseCustomColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
^
src\game\server\teeinfo.cpp:40:80: style: Parameter 'pSkinPartColors' can be declared as pointer to const [constParameter]
CTeeInfo::CTeeInfo(const char *apSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors)
^
```
2022-11-13 14:32:53 +00:00
|
|
|
CCharacter *CGameWorld::ClosestCharacter(vec2 Pos, float Radius, const CEntity *pNotThis)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
|
|
|
// Find other players
|
2020-09-26 19:41:58 +00:00
|
|
|
float ClosestRange = Radius * 2;
|
2010-05-29 07:25:38 +00:00
|
|
|
CCharacter *pClosest = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-01-19 17:27:50 +00:00
|
|
|
CCharacter *p = (CCharacter *)GameServer()->m_World.FindFirst(ENTTYPE_CHARACTER);
|
2010-05-29 07:25:38 +00:00
|
|
|
for(; p; p = (CCharacter *)p->TypeNext())
|
2015-07-09 00:08:14 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(p == pNotThis)
|
2008-08-14 18:42:47 +00:00
|
|
|
continue;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
float Len = distance(Pos, p->m_Pos);
|
2020-09-26 19:41:58 +00:00
|
|
|
if(Len < p->m_ProximityRadius + Radius)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Len < ClosestRange)
|
2008-08-14 18:42:47 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
ClosestRange = Len;
|
|
|
|
pClosest = p;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
return pClosest;
|
2008-08-14 18:42:47 +00:00
|
|
|
}
|
2011-03-19 20:21:42 +00:00
|
|
|
|
2023-06-28 20:14:51 +00:00
|
|
|
std::vector<CCharacter *> CGameWorld::IntersectedCharacters(vec2 Pos0, vec2 Pos1, float Radius, const CEntity *pNotThis)
|
2010-08-31 11:01:46 +00:00
|
|
|
{
|
2023-06-28 20:14:51 +00:00
|
|
|
std::vector<CCharacter *> vpCharacters;
|
2011-01-29 00:59:50 +00:00
|
|
|
CCharacter *pChr = (CCharacter *)FindFirst(CGameWorld::ENTTYPE_CHARACTER);
|
|
|
|
for(; pChr; pChr = (CCharacter *)pChr->TypeNext())
|
2015-07-09 00:08:14 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
if(pChr == pNotThis)
|
2010-08-31 11:01:46 +00:00
|
|
|
continue;
|
|
|
|
|
2020-10-17 18:22:13 +00:00
|
|
|
vec2 IntersectPos;
|
|
|
|
if(closest_point_on_line(Pos0, Pos1, pChr->m_Pos, IntersectPos))
|
2010-08-31 11:01:46 +00:00
|
|
|
{
|
2020-10-17 18:22:13 +00:00
|
|
|
float Len = distance(pChr->m_Pos, IntersectPos);
|
|
|
|
if(Len < pChr->m_ProximityRadius + Radius)
|
|
|
|
{
|
|
|
|
pChr->m_Intersection = IntersectPos;
|
2023-06-28 20:14:51 +00:00
|
|
|
vpCharacters.push_back(pChr);
|
2020-10-17 18:22:13 +00:00
|
|
|
}
|
2010-08-31 11:01:46 +00:00
|
|
|
}
|
|
|
|
}
|
2023-06-28 20:14:51 +00:00
|
|
|
return vpCharacters;
|
2010-08-31 11:01:46 +00:00
|
|
|
}
|
2010-09-11 09:42:35 +00:00
|
|
|
|
2011-02-13 05:35:13 +00:00
|
|
|
void CGameWorld::ReleaseHooked(int ClientID)
|
2010-09-11 00:01:15 +00:00
|
|
|
{
|
2011-01-29 00:59:50 +00:00
|
|
|
CCharacter *pChr = (CCharacter *)CGameWorld::FindFirst(CGameWorld::ENTTYPE_CHARACTER);
|
2020-09-26 19:41:58 +00:00
|
|
|
for(; pChr; pChr = (CCharacter *)pChr->TypeNext())
|
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
CCharacterCore *pCore = pChr->Core();
|
2023-09-05 21:53:03 +00:00
|
|
|
if(pCore->HookedPlayer() == ClientID && !pChr->IsSuper())
|
2011-01-29 00:59:50 +00:00
|
|
|
{
|
2022-06-30 22:36:32 +00:00
|
|
|
pCore->SetHookedPlayer(-1);
|
|
|
|
pCore->m_TriggeredEvents |= COREEVENT_HOOK_RETRACT;
|
|
|
|
pCore->m_HookState = HOOK_RETRACTED;
|
2011-01-29 00:59:50 +00:00
|
|
|
}
|
2020-09-26 19:41:58 +00:00
|
|
|
}
|
2011-01-20 14:10:32 +00:00
|
|
|
}
|