networking i guess

This commit is contained in:
2026-02-28 21:07:44 +02:00
parent e83f7cd448
commit 03c560c2b7
68 changed files with 1348 additions and 121 deletions

View File

@@ -25,6 +25,7 @@ public:
FunnyModel_t *LoadModelFromParams( const char *szMesh, const char *szMaterial );
uint32_t LoadShader( const char *szName );
FunnyShader_t *GetShaderByIndex( uint32_t uIndex );
void UnrefShader( uint32_t uIndex );
FunnyModel_t *m_models[MAX_MODEL_COUNT] = {};
@@ -46,6 +47,10 @@ FunnyMaterial_t *CAssetManager::GetMaterialByIndex( uint32_t uIndex )
{
return m_materials[uIndex];
}
FunnyShader_t *CAssetManager::GetShaderByIndex( uint32_t uIndex )
{
return m_shaders[uIndex];
}
uint32_t CAssetManager::LoadModel( const char *szName )
@@ -116,7 +121,7 @@ uint32_t CAssetManager::LoadMaterial( const char *szName )
{
uint32_t u = 0;
uint32_t uFoundIndex = 1;
for ( auto &m: m_models)
for ( auto &m: m_materials)
{
if (m == NULL)
{
@@ -125,17 +130,51 @@ uint32_t CAssetManager::LoadMaterial( const char *szName )
}
if (m->m_szName == szName)
{
m_modelUsages[uFoundIndex]++;
m_materialsUsages[uFoundIndex]++;
return u;
}
u++;
}
for ( auto &m: m_models)
for ( auto &m: m_materials)
{
if (m == NULL)
break;
uFoundIndex++;
}
IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ);
CUtlString szProperties = filesystem->ReadString(pHandle);
IJSONValue *pRoot = JSONManager()->ReadString(szProperties);
IJSONObject *pMainObject;
switch (pRoot->GetType())
{
case JSON_PARAMETER_OBJECT:
{
pMainObject = pRoot->GetObject();
if (!pMainObject)
{
V_printf("Failed to load properties\n");
return 0;
}
IJSONValue *pShaderValue = pMainObject->GetValue("shader");
CUtlString szShader = pShaderValue->GetStringValue();
CBaseMaterial *pMaterial = CreateMaterial(szShader);
uint32_t uShaderId = LoadShader(pMaterial->GetShaderPath());
FunnyShader_t *pShader = GetShaderByIndex(uShaderId);
m_materials[uFoundIndex] = new FunnyMaterial_t;
m_materials[uFoundIndex]->m_pShaders = pShader->m_pShader;
m_materials[uFoundIndex]->m_pMaterial = g_pRenderContext->CreateMaterial(pShader->m_pShader);
m_materials[uFoundIndex]->m_pLayout = pMaterial;
m_materialsUsages[uFoundIndex]++;
return uFoundIndex;
}
break;
default:
return 0;
}
return uFoundIndex;
}
void CAssetManager::UnrefMaterial( uint32_t uIndex )
@@ -163,6 +202,8 @@ FunnyModel_t *CAssetManager::LoadModelFromParams( const char *szMesh, const char
pModel->m_szName = szMesh;
pModel->m_pMesh = g_pWorldRenderer->CreateMesh(szMesh);
pModel->m_pMesh->SetVertices(pVertexBuffer);
uint32_t uMaterial = LoadMaterial(szMaterial);
pModel->m_pFunnyMaterial = GetMaterialByIndex(uMaterial);
return pModel;
}
@@ -200,6 +241,7 @@ uint32_t CAssetManager::LoadShader( const char *szName )
FunnyShader_t *pFunnyShader = new FunnyShader_t;
pFunnyShader->m_szName = szName;
pFunnyShader->m_pShader = pShader;
m_shaders[uFoundIndex] = pFunnyShader;
return uFoundIndex;
}

View File

@@ -7,6 +7,7 @@
#include "baseentity.h"
#include "datamap.h"
#include "tier0/lib.h"
#include "cglm/cglm.h"
C_BaseEntity::~C_BaseEntity()
{
@@ -19,11 +20,20 @@ void C_BaseEntity::Precache()
void C_BaseEntity::Spawn()
{
Precache();
SetAbsOrigin({0, 0, 0});
SetAbsAngles(0, 0, 0);
SetScale(1);
}
void C_BaseEntity::SetAbsAngles( float fPitch, float fYaw, float fRoll )
{
versor q;
glm_euler_yzx_quat((vec3){fPitch, fYaw, fRoll}, q);
m_vRotation.x = q[0];
m_vRotation.y = q[1];
m_vRotation.z = q[2];
m_vRotation.w = q[3];
}
void C_BaseEntity::SetAbsOrigin( Vector origin )
@@ -39,19 +49,24 @@ void C_BaseEntity::SetScale( float fScale )
}
QAngle C_BaseEntity::GetAbsAngles( void )
QAngle C_BaseEntity::GetAbsQAngles( void )
{
}
Quat C_BaseEntity::GetAbsAngles( void )
{
return m_vRotation;
}
Vector C_BaseEntity::GetAbsOrigin( void )
{
return m_vPosition;
}
float C_BaseEntity::GetScale( void )
{
return m_vScale.x;
}
void C_BaseEntity::SetThinkImpl( fnThink pfnThink )
@@ -111,3 +126,9 @@ BEGIN_DATADESC_NOBASE(C_BaseEntity)
DEFINE_KEYFIELD(m_vRotation, FIELD_QUATERNION, "angles")
DEFINE_KEYFIELD(m_vScale, FIELD_FLOAT3, "scales")
END_DATADESC()
IMPLEMENT_RECV_DT_NOBASE(C_BaseEntity)
NetPropFloat3(m_vPosition)
END_RECV_DT()
IMPLEMENT_EMPTY_SEND_DT_NOBASE(C_BaseEntity)

View File

@@ -10,6 +10,8 @@
#include "entitysystem.h"
#include "datamap.h"
#include "trig.h"
#include "netmap.h"
#include "tier1/utlstring.h"
#define DECLARE_CLASS_NOBASE( className ) \
typedef className ThisClass;
@@ -18,7 +20,7 @@
typedef className ThisClass;
#define LINK_ENTITY_TO_CLASS( mapClassName, DLLClassName) \
static CEntityFactory<DLLClassName> g_EntityFactory_##mapClassName( #mapClassName );
static CEntityFactory<DLLClassName> g_EntityFactory_##mapClassName( #mapClassName ); \
class C_BaseEntity;
@@ -50,6 +52,7 @@ class C_BaseEntity
public:
DECLARE_CLASS_NOBASE(C_BaseEntity);
DECLARE_DATADESC_NOBASE()
DECLARE_CLIENTCLASS_NOBASE()
typedescription_t *FindDataByName( const char *szName );
typedescription_t *FindDataByMapName( const char *szName );
@@ -62,7 +65,8 @@ public:
virtual void SetAbsOrigin( Vector origin );
virtual void SetScale( float fScale );
virtual QAngle GetAbsAngles( void );
virtual QAngle GetAbsQAngles( void );
virtual Quat GetAbsAngles( void );
virtual Vector GetAbsOrigin( void );
virtual float GetScale( void );
@@ -71,6 +75,7 @@ public:
virtual void SetNextThink( float fThink );
fnThink m_pfnThink = NULL;
CUtlString m_szClassName;
private:
Vector m_vPosition;
Quat m_vRotation;

View File

@@ -0,0 +1,34 @@
#include "basemodelentity.h"
void C_BaseModelEntity::Precache()
{
}
void C_BaseModelEntity::Spawn()
{
BaseClass::Spawn();
SetThink(Think);
}
void C_BaseModelEntity::Think( float fDelta )
{
m_pInstance->SetPosition(GetAbsOrigin());
m_pInstance->SetRotation(GetAbsAngles());
m_pInstance->SetScale({GetScale(),GetScale(),GetScale()});
}
void C_BaseModelEntity::SetModel( const char *szName )
{
if (m_uModelIndex)
{
g_pAssetManager->UnrefModel(m_uModelIndex);
}
m_uModelIndex = g_pAssetManager->LoadModel(szName);
m_pModel = g_pAssetManager->GetModelByIndex(m_uModelIndex);
m_pInstance = g_pWorldRenderer->CreateInstance(m_pModel->m_pMesh);
}
BEGIN_DATADESC(C_BaseModelEntity)
END_DATADESC()

View File

@@ -0,0 +1,27 @@
#ifndef BASE_MODEL_ENTITY_H
#define BASE_MODEL_ENTITY_H
#include "baseentity.h"
#include "worldrender.h"
#include "assetmgr.h"
class C_BaseModelEntity: public C_BaseEntity
{
public:
DECLARE_CLASS(C_BaseModelEntity, C_BaseEntity);
DECLARE_DATADESC();
virtual void Precache() override;
virtual void Spawn() override;
void Think( float fDelta );
void SetModel( const char *szName );
private:
uint32_t m_uModelIndex;
FunnyModel_t *m_pModel;
IMeshInstance *m_pInstance;
};
#endif

View File

@@ -18,6 +18,7 @@ DECLARE_BUILD_STAGE(Client)
"game.cpp",
"baseentity.cpp",
"basemodelentity.cpp",
"entitysystem.cpp",
"worldrender.cpp",

View File

@@ -1,12 +0,0 @@
#ifndef ENGINE_H
#define ENGINE_H
#include "tier2/ifilesystem.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/igamewindow.h"
extern IFileSystem *filesystem;
extern IRenderContext *g_pRenderContext;
extern IGameWindow *g_pMainWindow;
#endif

View File

@@ -81,10 +81,30 @@ C_BaseEntity *CEntitySystem::CreateByClassname( const char *szName )
}
pEntity = pFactory->Create();
pEntity->m_szClassName = szName;
m_pEntities[iSelectedSlot] = pEntity;
m_nEntityCount++;
return pEntity;
}
C_BaseEntity *CEntitySystem::CreateByClassnameWithIndex( const char *szName, uint32_t uIndex )
{
IEntityFactory *pFactory;
C_BaseEntity *pEntity;
// Do not create such shit
if (uIndex >= MAX_EDICTS)
return NULL;
pFactory = GetFactoryByClassname(szName);
if ( !pFactory )
return NULL;
pEntity = pFactory->Create();
pEntity->m_szClassName = szName;
m_pEntities[uIndex] = pEntity;
m_nEntityCount++;
return pEntity;
}
IEntityFactory *CEntitySystem::GetFactoryByClassname( const char *szName )
{
@@ -118,3 +138,8 @@ void CEntitySystem::Think()
(pEntity->*pEntity->m_pfnThink)(0);
}
}
C_BaseEntity **CEntitySystem::GetEntities()
{
return m_pEntities;
};

View File

@@ -7,6 +7,8 @@
#ifndef ENTITIES_H
#define ENTITIES_H
#include "stdint.h"
class IEntityFactory;
class C_BaseEntity;
@@ -19,10 +21,12 @@ public:
virtual void RegisterEntityClass( IEntityFactory *pEntityFactory, const char *szClassName );
virtual C_BaseEntity *CreateByClassname( const char *szName );
virtual C_BaseEntity *CreateByClassnameWithIndex( const char *szName, uint32_t uIndex );
virtual IEntityFactory *GetFactoryByClassname( const char *szName );
virtual void Think();
virtual C_BaseEntity **GetEntities();
private:
C_BaseEntity *m_pEntities[MAX_EDICTS];
int m_nEntityCount;

View File

@@ -7,12 +7,16 @@
#include "game.h"
#include "cglm/mat4.h"
#include "cglm/cglm.h"
#include "inetworkclient.h"
#include "netprotocol.h"
IFileSystem *filesystem;
IRenderContext *g_pRenderContext;
IGameWindow *g_pMainWindow;
static CEngineVars s_vars;
CEngineVars *g_pEngineVars = &s_vars;
EngineConsts_t *g_pEngineConstants;
INetworkBase *g_pServerBridge;
class CFunnyGameBridge: public IEngineBridge
{
@@ -34,18 +38,90 @@ EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION
void CFunnyGameBridge::Init()
{
g_pWorldRenderer->Init();
C_BaseEntity *pEntity = EntitySystem()->CreateByClassname("player");
pEntity->Spawn();
g_pServerBridge = g_pEngineConstants->ConnectLocalBridge(0);
PlayerJoined_t join = {
MESSAGE_PLAYER_JOINED,
"LocalPlayer"
};
g_pServerBridge->SendPacket({&join, sizeof(join)});
}
void CFunnyGameBridge::Tick( float fDelta )
{
}
void *ENT_GetNetMapData(C_BaseEntity *pEntity, netmap_t *pMap, uint32_t uIndex )
{
netmap_t *pCurrentMap = pMap;
uint32_t uCurrentIndex = uIndex;
searchIndex:
if (uCurrentIndex >= pCurrentMap->m_uFieldCount)
{
if (!pCurrentMap->m_uFieldCount)
return NULL;
uCurrentIndex -= pCurrentMap->m_uFieldCount;
pCurrentMap = pCurrentMap->m_pBase;
if (!pCurrentMap)
return NULL;
goto searchIndex;
}
return (char*)pEntity+pCurrentMap->m_pFields[uCurrentIndex].m_uOffset;
}
void CFunnyGameBridge::Frame( float fDelta )
{
g_pEngineVars->m_fTime += fDelta;
g_pEngineVars->m_fDeltaTime = fDelta;
g_pServerBridge->NetThink();
while ( g_pServerBridge->BHasUpdates() )
{
NetPacket_t packet = g_pServerBridge->PeekPacket();
// discard it
if (packet.uSize < sizeof (EMessageType))
continue;
PlayerPacket_t *pPacket = (PlayerPacket_t*)packet.pData;
C_BaseEntity *pEntity;
switch (pPacket->m_eType)
{
case MESSAGE_ENTITY_CLASS_SYNC:
pEntity = EntitySystem()->CreateByClassnameWithIndex(
(char*)pPacket->m_entityClass.m_szEntityName, pPacket->m_entityClass.m_uIndex
);
pEntity->Spawn();
g_pServerBridge->RecievePacket();
break;
case MESSAGE_ENTITY_DATA_SYNC:
pEntity = EntitySystem()->GetEntities()[pPacket->m_entityData.m_uIndex];
union {
void *pData;
char *pcCurrentData;
EntityDataSyncValue_t *pcSyncValue;
};
pData = pPacket;
pcCurrentData += sizeof(EntityDataSync_t);
for ( uint32_t u = 0; u < pPacket->m_entityData.m_uCount; u++ )
{
uint32_t uVariableSize = pcSyncValue->m_uVariableSize;
void *pValueData = (float*)ENT_GetNetMapData(
pEntity,
pEntity->GetRecvMap(),
pcSyncValue->m_uVariableIndex);
pcCurrentData += sizeof(EntityDataSyncValue_t);
if (pValueData)
V_memcpy(pValueData, pcCurrentData, uVariableSize);
pcCurrentData += (uVariableSize+7) & ~7;
}
g_pServerBridge->RecievePacket();
break;
default:
continue;
}
}
EntitySystem()->Think();
g_pWorldRenderer->Frame(fDelta);
}
@@ -61,5 +137,6 @@ void CFunnyGameBridge::ConnectInterface( const char *psz, void *pInterface )
CONNECT_INTERFACE(RENDER_CONTEXT_INTERFACE_VERSION, g_pRenderContext);
CONNECT_INTERFACE(FILESYSTEM_INTERFACE_VERSION, filesystem);
CONNECT_INTERFACE("MainWindow", g_pMainWindow);
CONNECT_INTERFACE("EngineConstants", g_pEngineConstants);
}

0
game/client/mapmgr.cpp Normal file
View File

0
game/client/mapmgr.h Normal file
View File

View File

View File

View File

View File

View File

@@ -4,21 +4,29 @@
void C_MOBAPlayer::Precache()
{
uint32_t uIndex = g_pAssetManager->LoadModel("game/core/models/cube.fmdl");
V_printf("%u\n", uIndex);
pModel = g_pAssetManager->GetModelByIndex(uIndex);
SetModel("game/core/models/cube.fmdl");
}
void C_MOBAPlayer::Spawn()
{
Precache();
BaseClass::Spawn();
SetThink(Think);
g_pWorldRenderer->SetCameraPosition({0, 0, -20});
};
void C_MOBAPlayer::Think( float fDelta )
{
BaseClass::Think(fDelta);
};
LINK_ENTITY_TO_CLASS(player, C_MOBAPlayer)
BEGIN_DATADESC(C_MOBAPlayer)
END_DATADESC()
IMPLEMENT_RECV_DT(C_MOBAPlayer)
NetPropFloat(m_fTimer),
END_RECV_DT()
IMPLEMENT_EMPTY_SEND_DT(C_MOBAPlayer)

View File

@@ -1,17 +1,21 @@
#include "baseentity.h"
#include "worldrender.h"
#include "game.h"
#include "assetmgr.h"
#ifndef MILMOBA_PLAYER_H
#define MILMOBA_PLAYER_H
#include "basemodelentity.h"
class C_MOBAPlayer: public C_BaseEntity
class C_MOBAPlayer: public C_BaseModelEntity
{
public:
DECLARE_CLASS(C_MOBAPlayer, C_BaseEntity)
DECLARE_CLASS(C_MOBAPlayer, C_BaseModelEntity);
DECLARE_DATADESC();
DECLARE_CLIENTCLASS()
virtual void Precache ( void ) override;
virtual void Spawn( void ) override;
virtual void Think( float fDelta );
void Think( float fDelta );
FunnyModel_t *pModel;
float m_fTimer;
};
#endif

View File

@@ -134,6 +134,8 @@ private:
ViewBuffer_t *m_pViewBufferData;
ITextureArray *m_pTextures;
IShader *m_pRasterShader;
IMaterial *m_pRasterMaterial;
vec3 m_vPos;
versor m_vRot;
@@ -192,6 +194,10 @@ void CFunnyWorldRenderer::Init()
IMAGE_FORMAT_D32_SFLOAT,
MULTISAMPLE_TYPE_4_SAMPLES
);
m_pRasterShader = g_pRenderContext->CreateShader("game/core/shaders/mesh_raster.shader_c");
ConfigureShader(m_pRasterShader);
m_pRasterShader->Build();
m_pRasterMaterial = g_pRenderContext->CreateMaterial(m_pRasterShader);
g_pMainWindow->SetOutputImage(m_pResolvedOutputImage);
@@ -291,16 +297,16 @@ void CFunnyWorldRenderer::Frame( float fDelta )
}
pDataBuffer->Unmap();
pDataBuffer->Unlock();
mesh->m_pMaterial->VSSetConstantsBuffer(0, m_pViewBuffer);
mesh->m_pMaterial->VSSetConstantsBuffer(1, pDataBuffer);
mesh->m_pMaterial->PSSetTextureArray(1, m_pTextures);
m_pRasterMaterial->VSSetConstantsBuffer(0, m_pViewBuffer);
m_pRasterMaterial->VSSetConstantsBuffer(1, pDataBuffer);
m_pRasterMaterial->PSSetTextureArray(1, m_pTextures);
g_pRenderContext->DestroyBuffer(pDataBuffer);
}
for ( auto mesh: m_pMeshes)
{
if (mesh->m_instances.GetSize()==0)
continue;
m_pRasterCommandList->SetMaterial(mesh->m_pMaterial);
m_pRasterCommandList->SetMaterial(m_pRasterMaterial);
m_pRasterCommandList->SetVertexBuffer(0, mesh->m_pVertexBuffer);
m_pRasterCommandList->DrawPrimitives(mesh->m_pVertexBuffer->GetSize()/32, 0, mesh->m_instances.GetSize(), 0);
}

View File

@@ -16,6 +16,16 @@ public:
virtual void SetMaterial( IMaterial *pMaterial ) = 0;
};
abstract_class IPointLight
{
public:
virtual void SetColor( Vector vColor ) = 0;
virtual void SetRadius( Vector vColor ) = 0;
virtual void SetPosition( Vector vPosition ) = 0;
virtual void SetRotation( Quat vRotation ) = 0;
virtual void SetScale( Vector vScale ) = 0;
};
abstract_class IMeshInstance
{
public:

View File

@@ -7,15 +7,20 @@
#include "baseentity.h"
#include "datamap.h"
#include "tier0/lib.h"
#include "tier0/mem.h"
CBaseEntity::~CBaseEntity()
{
}
void CBaseEntity::Precache()
{
}
void CBaseEntity::Spawn()
{
Precache();
}
void CBaseEntity::SetAbsAngles( float fPitch, float fYaw, float fRoll )
@@ -35,22 +40,27 @@ void CBaseEntity::SetScale( float fScale )
}
QAngle CBaseEntity::GetAbsAngles( void )
QAngle CBaseEntity::GetAbsQAngles( void )
{
}
Quat CBaseEntity::GetAbsAngles( void )
{
return m_vRotation;
}
Vector CBaseEntity::GetAbsOrigin( void )
{
return m_vPosition;
}
float CBaseEntity::GetScale( void )
{
return m_vScale.x;
}
void CBaseEntity::SetThink( fnThink pfnThink )
void CBaseEntity::SetThinkImpl( fnThink pfnThink )
{
m_pfnThink = pfnThink;
}
@@ -107,3 +117,9 @@ BEGIN_DATADESC_NOBASE(CBaseEntity)
DEFINE_KEYFIELD(m_vRotation, FIELD_QUATERNION, "angles")
DEFINE_KEYFIELD(m_vScale, FIELD_FLOAT3, "scales")
END_DATADESC()
IMPLEMENT_SEND_DT_NOBASE(CBaseEntity)
NetPropFloat3(m_vPosition)
END_SEND_DT()
IMPLEMENT_EMPTY_RECV_DT_NOBASE(CBaseEntity)

View File

@@ -11,15 +11,12 @@
#include "datamap.h"
#include "cglm/cglm.h"
#include "trig.h"
#include "netmap.h"
#define DECLARE_CLASS_NOBASE( className ) \
typedef className ThisClass;
#define DECLARE_CLASS( className, baseName ) \
typedef baseName BaseClass; \
typedef className ThisClass;
#define LINK_ENTITY_TO_CLASS( mapClassName, DLLClassName) \
static CEntityFactory<DLLClassName> g_EntityFactory_##mapClassName( #mapClassName );
static CEntityFactory<DLLClassName> g_EntityFactory_##mapClassName( #mapClassName ); \
class CBaseEntity;
@@ -45,35 +42,46 @@ public:
class CBaseEntity;
typedef void(*fnThink)( float fTime );
typedef void(CBaseEntity::*fnThink)( float fTime );
class CBaseEntity
{
public:
public:
DECLARE_CLASS_NOBASE(CBaseEntity);
DECLARE_DATADESC_NOBASE()
DECLARE_SERVERCLASS_NOBASE()
typedescription_t *FindDataByName( const char *szName );
typedescription_t *FindDataByMapName( const char *szName );
const char *GetClassName();
virtual ~CBaseEntity();
virtual void Precache();
virtual void Spawn();
virtual void SetAbsAngles( float fPitch, float fYaw, float fRoll );
virtual void SetAbsOrigin( Vector origin );
virtual void SetScale( float fScale );
virtual QAngle GetAbsAngles( void );
virtual QAngle GetAbsQAngles( void );
virtual Quat GetAbsAngles( void );
virtual Vector GetAbsOrigin( void );
virtual float GetScale( void );
virtual void SetThink( fnThink pfnThink );
#define SetThink(fn) SetThinkImpl((fnThink)&ThisClass::fn)
virtual void SetThinkImpl( fnThink pfnThink );
virtual void SetNextThink( float fThink );
fnThink m_pfnThink = NULL;
const char *m_szClassName;
private:
Vector m_vPosition;
Quat m_vRotation;
Vector m_vScale;
};
#endif

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,12 @@
#ifndef BASE_MODEL_ENTITY_H
#define BASE_MODEL_ENTITY_H
#include "baseentity.h"
class CBaseModelEntity: public CBaseEntity
{
public:
DECLARE_CLASS(CBaseModelEntity, CBaseEntity);
};
#endif

View File

@@ -18,6 +18,9 @@ DECLARE_BUILD_STAGE(Server)
"game.cpp",
"entitysystem.cpp",
"baseentity.cpp",
"basemodelentity.cpp",
"milmoba/player.cpp",
};
compileProject.includeDirectories = {
"../../public",

View File

@@ -9,6 +9,8 @@
#include "stddef.h"
#include "string.h"
#include "stdlib.h"
#include "engine.h"
#include "netprotocol.h"
CEntitySystem *EntitySystem()
@@ -81,11 +83,18 @@ CBaseEntity *CEntitySystem::CreateByClassname( const char *szName )
}
pEntity = pFactory->Create();
pEntity->m_szClassName = szName;
m_pEntities[iSelectedSlot] = pEntity;
m_nEntityCount++;
EntityClass_t stClassSync = {
MESSAGE_ENTITY_CLASS_SYNC,
iSelectedSlot,
};
V_strncpy((char*)stClassSync.m_szEntityName, szName, 256);
g_pClientBridge->SendPacket({&stClassSync, sizeof(stClassSync)});
return pEntity;
}
IEntityFactory *CEntitySystem::GetFactoryByClassname( const char *szName )
{
EntityRegistry_t *pEntity;
@@ -99,15 +108,27 @@ IEntityFactory *CEntitySystem::GetFactoryByClassname( const char *szName )
}
return NULL;
}
void CEntitySystem::Think()
{
CBaseEntity *pEntity;
int i;
uint32_t u;
uint32_t x;
uint32_t uSize;
netmap_t *pNetMap;
void *pData;
union {
void *pCurrentData;
char *pcCurrentData;
EntityDataSync_t *pSync;
EntityDataSyncValue_t *pValue;
};
for ( i = 0; i < MAX_EDICTS; i++ )
{
pEntity = m_pEntities[i];
if ( pEntity == NULL )
continue;
@@ -115,6 +136,54 @@ void CEntitySystem::Think()
if ( !pEntity->m_pfnThink )
continue;
pEntity->m_pfnThink(0);
(pEntity->*pEntity->m_pfnThink)(0);
pNetMap = pEntity->GetSendMap();
uSize = sizeof(EntityDataSyncValue_t);
x = 0;
while ( pNetMap )
{
for ( u = 0; u < pNetMap->m_uFieldCount; u++ )
{
x++;
uSize += (pNetMap->m_pFields[u].m_uSize+7) & ~7;
uSize += sizeof(EntityDataSyncValue_t);
}
pNetMap = pNetMap->m_pBase;
}
pData = V_malloc(uSize);
V_memset(pData, 0, uSize);
pCurrentData = pData;
pSync->m_eType = MESSAGE_ENTITY_DATA_SYNC;
pSync->m_uIndex = i;
pSync->m_uCount = x;
pcCurrentData += sizeof(EntityDataSync_t);
pNetMap = pEntity->GetSendMap();
x = 0;
while ( pNetMap )
{
for ( u = 0; u < pNetMap->m_uFieldCount; u++ )
{
pValue->m_uVariableSize = pNetMap->m_pFields[u].m_uSize;
pValue->m_uVariableIndex = x;
uint32_t uVariableSize;
pcCurrentData += sizeof(EntityDataSyncValue_t);
V_memcpy(pcCurrentData,
pNetMap->m_pFields[u].m_uOffset+(char*)pEntity,
pNetMap->m_pFields[u].m_uSize);
pcCurrentData += (pNetMap->m_pFields[u].m_uSize+7) & ~7;
x++;
}
pNetMap = pNetMap->m_pBase;
}
g_pClientBridge->SendPacket({pData, uSize});
V_free(pData);
}
}
CBaseEntity **CEntitySystem::GetEntities()
{
return m_pEntities;
}

View File

@@ -23,6 +23,7 @@ public:
virtual IEntityFactory *GetFactoryByClassname( const char *szName );
virtual void Think();
virtual CBaseEntity **GetEntities();
private:
CBaseEntity *m_pEntities[MAX_EDICTS];
int m_nEntityCount;

View File

@@ -1,10 +1,18 @@
#include "tier2/ifilesystem.h"
#include "materialsystem/imaterialsystem.h"
#include "entitysystem.h"
#include "baseentity.h"
#include "enginebridge.h"
#include "game.h"
#include "inetworkserver.h"
#include "netprotocol.h"
IFileSystem *filesystem;
IRenderContext *g_pRenderContext;
IGameWindow *g_pMainWindow;
static CEngineVars s_vars;
CEngineVars *g_pEngineVars = &s_vars;
EngineConsts_t *g_pEngineConstants;
INetworkBase *g_pClientBridge;
class CFunnyGameBridge: public IEngineBridge
{
@@ -13,6 +21,7 @@ class CFunnyGameBridge: public IEngineBridge
virtual void Frame( float fDelta ) override;
virtual void Shutdown() override;
virtual void ConnectInterface( const char *psz, void *pInterface ) override;
};
IEngineBridge *EngineBridge()
@@ -24,7 +33,8 @@ IEngineBridge *EngineBridge()
EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION)
void CFunnyGameBridge::Init()
{
{
g_pClientBridge = g_pEngineConstants->LaunchLocalBridge(0);
}
void CFunnyGameBridge::Tick( float fDelta )
@@ -34,6 +44,32 @@ void CFunnyGameBridge::Tick( float fDelta )
void CFunnyGameBridge::Frame( float fDelta )
{
g_pEngineVars->m_fTime += fDelta;
g_pEngineVars->m_fDeltaTime = fDelta;
g_pClientBridge->NetThink();
while (g_pClientBridge->BHasUpdates())
{
NetPacket_t packet = g_pClientBridge->PeekPacket();
// discard it
if (packet.uSize < sizeof (EMessageType))
continue;
PlayerPacket_t *pPacket = (PlayerPacket_t*)packet.pData;
CBaseEntity *pEntity;
switch (pPacket->m_eType)
{
case MESSAGE_PLAYER_JOINED:
g_pClientBridge->RecievePacket();
V_printf("Hi %s\n",pPacket->m_playerJoined.m_szPlayerName);
pEntity = EntitySystem()->CreateByClassname("player");
pEntity->Spawn();
break;
default:
continue;
}
}
EntitySystem()->Think();
}
@@ -45,5 +81,6 @@ void CFunnyGameBridge::Shutdown()
#define CONNECT_INTERFACE(szName, pGlobal) if (!V_strcmp(psz, szName)) { pGlobal = (typeof(pGlobal))pInterface; return; }
void CFunnyGameBridge::ConnectInterface( const char *psz, void *pInterface )
{
CONNECT_INTERFACE("EngineConstants", g_pEngineConstants)
}

View File

@@ -0,0 +1,26 @@
#include "player.h"
#include "game.h"
void CMOBAPlayer::Spawn()
{
SetThink(Think);
};
void CMOBAPlayer::Think( float fDelta )
{
m_fTimer = g_pEngineVars->m_fTime;
SetAbsOrigin({m_fTimer,0,0});
};
LINK_ENTITY_TO_CLASS(player, CMOBAPlayer)
BEGIN_DATADESC(CMOBAPlayer)
END_DATADESC()
IMPLEMENT_SEND_DT(CMOBAPlayer)
NetPropFloat(m_fTimer)
END_SEND_DT()
IMPLEMENT_EMPTY_RECV_DT(CMOBAPlayer)

View File

@@ -0,0 +1,19 @@
#ifndef MILMOBA_PLAYER_H
#define MILMOBA_PLAYER_H
#include "basemodelentity.h"
class CMOBAPlayer: public CBaseModelEntity
{
public:
DECLARE_CLASS(CMOBAPlayer, CBaseModelEntity);
DECLARE_DATADESC();
DECLARE_SERVERCLASS()
virtual void Spawn( void ) override;
void Think( float fDelta );
float m_fTimer;
};
#endif

View File

@@ -0,0 +1 @@
#include "pointentity.h"

10
game/server/pointentity.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef POINT_ENTITY_H
#define POINT_ENTITY_H
#include "baseentity.h"
class CPointEntity: public CBaseEntity
{
public:
};
#endif

View File

@@ -10,6 +10,7 @@
#ifndef DATAMAP_H
#define DATAMAP_H
#include "stddef.h"
#include "gameclass.h"
enum fieldtype_t {
FIELD_VOID = 0,
@@ -57,12 +58,6 @@ struct datamap_t
int m_iNumFields;
};
#define DECLARE_CLASS_NOBASE( className ) \
typedef className ThisClass;
#define DECLARE_CLASS( className, baseName ) \
typedef baseName BaseClass; \
typedef className ThisClass;
#define DECLARE_DATADESC() \
datamap_t *GetBaseMap(); \
virtual datamap_t *GetDataMap() override; \
@@ -103,6 +98,7 @@ struct datamap_t
#define _class_offsetof( class, var ) ((size_t)&(((class*)0)->var))
#define _FIELD( name, fieldtype, count, flags, mapname, tolerance) { #name, mapname, fieldtype, _class_offsetof(ThisClass, name), count, sizeof(((ThisClass*)0)->name), flags },
#define DEFINE_FIELD( name, fieldtype ) _FIELD( name, fieldtype, 1, FTYPEDESC_KEY, 0, 0)
#define DEFINE_KEYFIELD( name, fieldtype, mapname ) _FIELD( name, fieldtype, 1, FTYPEDESC_KEY, mapname, 0)
#define FTYPEDESC_KEY 0x0004

26
game/shared/engine.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef ENGINE_H
#define ENGINE_H
#include "tier2/ifilesystem.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/igamewindow.h"
#include "networkbase.h"
struct EngineConsts_t
{
bool m_bIsDedicated;
bool m_bIsSteam;
INetworkBase *(LaunchLocalBridge)(uint16_t uPort);
INetworkBase *(LaunchServer)(uint16_t uPort);
INetworkBase *(ConnectLocalBridge)(uint16_t uPort);
INetworkBase *(ConnectSteamServer)(uint64_t uServer, uint16_t uPort);
};
extern IFileSystem *filesystem;
extern IRenderContext *g_pRenderContext;
extern IGameWindow *g_pMainWindow;
extern EngineConsts_t *g_pEngineConstants;
extern INetworkBase *g_pServerBridge;
extern INetworkBase *g_pClientBridge;
#endif

9
game/shared/gameclass.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef GAMECLASS_H
#define GAMECLASS_H
#define DECLARE_CLASS_NOBASE( className ) \
typedef className ThisClass;
#define DECLARE_CLASS( className, baseName ) \
typedef baseName BaseClass; \
typedef className ThisClass;
#endif

118
game/shared/netmap.h Normal file
View File

@@ -0,0 +1,118 @@
#ifndef NETMAP_H
#define NETMAP_H
#include "stddef.h"
#include "stdint.h"
#include "datamap.h"
struct netfield_t
{
const char *m_szName;
fieldtype_t m_eType;
size_t m_uOffset;
size_t m_uSize;
};
struct netmap_t
{
struct netmap_t *m_pBase;
netfield_t *m_pFields;
uint32_t m_uFieldCount;
};
#define NetPropInt(name) { #name, FIELD_INT, _class_offsetof(ThisClass, name), sizeof(name)}
#define NetPropFloat(name) { #name, FIELD_FLOAT, _class_offsetof(ThisClass, name), sizeof(name)}
#define NetPropFloat3(name) \
NetPropFloat(name.x), \
NetPropFloat(name.y), \
NetPropFloat(name.z)
#define NetPropQuaternion(name) \
NetPropFloat(name.x), \
NetPropFloat(name.y), \
NetPropFloat(name.z), \
NetPropFloat(name.w) \
#define __DECLARE_NETCLASS_NOBASE() \
netmap_t *GetBaseSendMap(); \
virtual netmap_t *GetSendMap(); \
virtual netmap_t SendMapInit(); \
netmap_t *GetBaseRecvMap(); \
virtual netmap_t *GetRecvMap(); \
virtual netmap_t RecvMapInit(); \
#define __DECLARE_NETCLASS() \
netmap_t *GetBaseSendMap(); \
virtual netmap_t *GetSendMap() override; \
virtual netmap_t SendMapInit() override; \
netmap_t *GetBaseRecvMap(); \
virtual netmap_t *GetRecvMap() override; \
virtual netmap_t RecvMapInit() override; \
#define DECLARE_SERVERCLASS_NOBASE() \
__DECLARE_NETCLASS_NOBASE() \
#define DECLARE_CLIENTCLASS_NOBASE() \
__DECLARE_NETCLASS_NOBASE() \
#define DECLARE_SERVERCLASS() \
__DECLARE_NETCLASS() \
#define DECLARE_CLIENTCLASS() \
__DECLARE_NETCLASS() \
#define IMPLEMENT_SEND_DT_INTERNAL(className) \
netmap_t *className::GetSendMap() { static netmap_t s_DataMap = ThisClass::SendMapInit(); return &s_DataMap; } \
netmap_t className::SendMapInit() { \
netmap_t map; \
map.m_pBase = ThisClass::GetBaseSendMap(); \
static netfield_t dataDesc[] \
{\
#define IMPLEMENT_SEND_DT_NOBASE(className) \
netmap_t *className::GetBaseSendMap() { return NULL; } \
IMPLEMENT_SEND_DT_INTERNAL(className)
#define IMPLEMENT_SEND_DT(className) \
netmap_t *className::GetBaseSendMap() { return BaseClass::GetSendMap(); } \
IMPLEMENT_SEND_DT_INTERNAL(className)
#define IMPLEMENT_RECV_DT_INTERNAL(className) \
netmap_t *className::GetRecvMap() { static netmap_t s_DataMap = ThisClass::RecvMapInit(); return &s_DataMap; } \
netmap_t className::RecvMapInit() { \
netmap_t map; \
map.m_pBase = ThisClass::GetBaseRecvMap(); \
static netfield_t dataDesc[] \
{\
#define IMPLEMENT_RECV_DT_NOBASE(className) \
netmap_t *className::GetBaseRecvMap() { return NULL; } \
IMPLEMENT_RECV_DT_INTERNAL(className)
#define IMPLEMENT_RECV_DT(className) \
netmap_t *className::GetBaseRecvMap() { return BaseClass::GetRecvMap(); } \
IMPLEMENT_RECV_DT_INTERNAL(className)
#define END_NET_DT_INTERNAL() \
}; \
map.m_uFieldCount = sizeof(dataDesc)/sizeof(netfield_t); \
map.m_pFields = dataDesc; \
return map; \
}
#define END_SEND_DT() \
END_NET_DT_INTERNAL()
#define END_RECV_DT() \
END_NET_DT_INTERNAL()
#define IMPLEMENT_EMPTY_SEND_DT_NOBASE(className) \
IMPLEMENT_SEND_DT_NOBASE(className) \
END_RECV_DT()
#define IMPLEMENT_EMPTY_SEND_DT(className) \
IMPLEMENT_SEND_DT(className) \
END_RECV_DT()
#define IMPLEMENT_EMPTY_RECV_DT_NOBASE(className) \
IMPLEMENT_RECV_DT_NOBASE(className) \
END_RECV_DT()
#define IMPLEMENT_EMPTY_RECV_DT(className) \
IMPLEMENT_RECV_DT(className) \
END_RECV_DT()
#endif

76
game/shared/netprotocol.h Normal file
View File

@@ -0,0 +1,76 @@
#ifndef NET_PROTOCOL_H
#define NET_PROTOCOL_H
#include "stdint.h"
#include <arpa/inet.h>
class CNetworkUInt32
{
public:
CNetworkUInt32() : m_uValue(0) {}
CNetworkUInt32( uint32_t uValue ) : m_uValue(htonl(uValue)) {}
operator uint32_t() const {
return htonl(m_uValue);
}
uint32_t m_uValue;
};
enum EMessageType: uint32_t
{
MESSAGE_PLAYER_JOINED,
MESSAGE_PLAYER_JOINED_CALLBACK,
MESSAGE_PLAYER_LEFT,
MESSAGE_ENTITY_CLASS_SYNC,
MESSAGE_ENTITY_DATA_SYNC,
};
struct PlayerJoined_t
{
EMessageType m_eType;
int8_t m_szPlayerName[256];
};
struct PlayerJoinedCallback_t
{
EMessageType m_eType;
CNetworkUInt32 m_uPlayerIndex;
};
struct PlayerLeft_t
{
EMessageType m_eType;
CNetworkUInt32 m_uPlayerIndex;
};
struct EntityClass_t
{
EMessageType m_eType;
CNetworkUInt32 m_uIndex;
int8_t m_szEntityName[256];
};
struct EntityDataSync_t
{
EMessageType m_eType;
CNetworkUInt32 m_uIndex;
CNetworkUInt32 m_uCount;
};
struct EntityDataSyncValue_t
{
CNetworkUInt32 m_uVariableIndex;
CNetworkUInt32 m_uVariableSize;
};
union PlayerPacket_t
{
EMessageType m_eType;
PlayerJoined_t m_playerJoined;
PlayerJoinedCallback_t m_playerJoinedCallback;
PlayerLeft_t m_playerLeft;
EntityClass_t m_entityClass;
EntityDataSync_t m_entityData;
};
#endif