@@ -937,6 +937,8 @@ struct EntityTransmitCache // Well.... Still kinda acts as a tick-based cache, t
937937 // Updates the cache for the current tick
938938 void UpdateEntities (const unsigned short *pEdictIndices, int nEdicts)
939939 {
940+ m_bIsActivelyNetworking = true ;
941+
940942 Plat_FastMemset (&pAlwaysTransmitBits, 0 , sizeof (pAlwaysTransmitBits) * 4 ); // Again, very "safe"
941943 // pAlwaysTransmitBits.ClearAll();
942944 // pNeverTransmitBits.ClearAll();
@@ -1076,8 +1078,14 @@ struct EntityTransmitCache // Well.... Still kinda acts as a tick-based cache, t
10761078 }
10771079 }
10781080
1079- void EntityRemoved (edict_t * pEdict)
1081+ void EntityRemoved (CBaseEntity* pEntity, edict_t * pEdict)
10801082 {
1083+ // Not networking? Then we can easily skip all this since everything is cleared on the next transmit anyways
1084+ if (!m_bIsActivelyNetworking)
1085+ return ;
1086+
1087+ // Deleted during networking? Now you fked up.
1088+
10811089 int nIndex = pEdict->m_EdictIndex ;
10821090 pAlwaysTransmitBits.Clear (nIndex);
10831091 pNeverTransmitBits.Clear (nIndex);
@@ -1086,6 +1094,56 @@ struct EntityTransmitCache // Well.... Still kinda acts as a tick-based cache, t
10861094
10871095 nEntityCluster[nIndex] = 0 ;
10881096 bDirtyEntities.Clear (nIndex);
1097+
1098+ for (int i = 0 ; i<nFullEdictCount; ++i)
1099+ {
1100+ CBaseEntity* pFullEnt = pFullEntityList[i];
1101+ if (pFullEnt != pEntity)
1102+ continue ;
1103+
1104+ if (i < nFullEdictCount - 1 )
1105+ memmove (&pFullEntityList[i], &pFullEntityList[i + 1 ], (nFullEdictCount - i - 1 ) * sizeof (CBaseEntity*));
1106+
1107+ --nFullEdictCount;
1108+ pFullEntityList[nFullEdictCount] = NULL ;
1109+ break ;
1110+ }
1111+
1112+ for (int i = 0 ; i<nPVSEdictCount; ++i)
1113+ {
1114+ CBaseEntity* pFullEnt = pFullEntityList[i];
1115+ if (pFullEnt != pEntity)
1116+ continue ;
1117+
1118+ if (i < nPVSEdictCount - 1 )
1119+ memmove (&pPVSEntityList[i], &pPVSEntityList[i + 1 ], (nPVSEdictCount - i - 1 ) * sizeof (CBaseEntity*));
1120+
1121+ --nPVSEdictCount;
1122+ pPVSEntityList[nPVSEdictCount] = NULL ;
1123+ break ;
1124+ }
1125+
1126+ for (int nArea = 0 ; nArea<MAX_MAP_AREAS-1 ; ++nArea)
1127+ {
1128+ EntityTransmitCache::AreaCache& pArea = g_nEntityTransmitCache.nAreaEntities [nArea];
1129+ if (pArea.nCount == 0 )
1130+ continue ;
1131+
1132+ for (int i=0 ; i<pArea.nCount ; ++i)
1133+ {
1134+ if (pArea.pEntities [i] != pEntity)
1135+ continue ;
1136+
1137+ if (i < pArea.nCount - 1 )
1138+ memmove (&pArea.pEntities [i], &pArea.pEntities [i + 1 ], (pArea.nCount - i - 1 ) * sizeof (CBaseEntity*));
1139+
1140+ --pArea.nCount ;
1141+ pArea.pEntities [pArea.nCount ] = NULL ;
1142+ break ;
1143+ }
1144+ }
1145+
1146+ DevMsg (PROJECT_NAME " - networking: An entity (class: %s) was deleted during networking! This is utterly expensive, stop this >:(\n " , pEntity->GetClassname ());
10891147 }
10901148
10911149 void AddPVSEntity (CBaseEntity* pEntity)
@@ -1171,6 +1229,13 @@ struct EntityTransmitCache // Well.... Still kinda acts as a tick-based cache, t
11711229 pArea.pEntities [pArea.nCount ++] = pEntity;
11721230 }
11731231
1232+ inline void FinishNetworking ()
1233+ {
1234+ m_bIsActivelyNetworking = false ;
1235+ }
1236+
1237+ bool m_bIsActivelyNetworking = false ;
1238+
11741239 CBitVec<MAX_EDICTS> pAlwaysTransmitBits;
11751240 CBitVec<MAX_EDICTS> pNeverTransmitBits;
11761241 CBitVec<MAX_EDICTS> pPVSTransmitBits;
@@ -2143,7 +2208,7 @@ void CNetworkingModule::OnEntityDeleted(CBaseEntity* pEntity)
21432208 if (!pEdict)
21442209 return ;
21452210
2146- g_nEntityTransmitCache.EntityRemoved (pEdict);
2211+ g_nEntityTransmitCache.EntityRemoved (pEntity, pEdict);
21472212 CleaupSetPreventTransmit (pEntity);
21482213 int entIndex = pEdict->m_EdictIndex ;
21492214 g_pEntityCache[entIndex] = NULL ;
0 commit comments