diff --git a/src/client/entities.qc b/src/client/entities.qc index c7d4d1c6..42d349f4 100644 --- a/src/client/entities.qc +++ b/src/client/entities.qc @@ -165,6 +165,11 @@ Entities_ParseLump(void) if (eEnt && eEnt.isCSQC == false) { remove(eEnt); } + + if (eEnt.identity) + if (eEnt.CanSpawn(true) == false) + eEnt.Destroy(); + return (1); } diff --git a/src/gs-entbase/client/env_cubemap.qc b/src/gs-entbase/client/env_cubemap.qc index 010baaab..05358005 100644 --- a/src/gs-entbase/client/env_cubemap.qc +++ b/src/gs-entbase/client/env_cubemap.qc @@ -39,6 +39,7 @@ env_cubemap:NSEntity public: void env_cubemap(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); private: int m_iSize; @@ -67,6 +68,12 @@ env_cubemap::SpawnKey(string strField, string strKey) } } +bool +env_cubemap::CanSpawn(bool clientSide) +{ + return true; +} + void env_cubemap::env_cubemap(void) { diff --git a/src/gs-entbase/client/env_glow.qc b/src/gs-entbase/client/env_glow.qc index 2bc9d7bc..7d4d2bcf 100644 --- a/src/gs-entbase/client/env_glow.qc +++ b/src/gs-entbase/client/env_glow.qc @@ -45,6 +45,7 @@ public: virtual void postdraw(void); virtual void SpawnKey(string,string); virtual void RendererRestarted(void); + virtual bool CanSpawn(bool); private: vector m_vecColor; @@ -58,6 +59,12 @@ private: vector m_vecOrientation; }; +bool +env_glow::CanSpawn(bool clientSide) +{ + return true; +} + void env_sun_lensflare(vector, float, vector); void env_glow::postdraw(void) diff --git a/src/gs-entbase/client/env_particle.qc b/src/gs-entbase/client/env_particle.qc index d188a1b3..76506169 100644 --- a/src/gs-entbase/client/env_particle.qc +++ b/src/gs-entbase/client/env_particle.qc @@ -37,6 +37,7 @@ public: virtual void Respawn(void); virtual void customphysics(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); private: entity m_eTarget; @@ -48,6 +49,12 @@ private: string m_strTarget; }; +bool +env_particle::CanSpawn(bool clientSide) +{ + return true; +} + void env_particle::customphysics(void) { vector vecPlayer; diff --git a/src/gs-entbase/client/env_sound.qc b/src/gs-entbase/client/env_sound.qc index 13dfbb48..afda211a 100644 --- a/src/gs-entbase/client/env_sound.qc +++ b/src/gs-entbase/client/env_sound.qc @@ -71,12 +71,19 @@ public: virtual void Respawn(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); private: int m_iRoomType; int m_iRadius; }; +bool +env_sound::CanSpawn(bool clientSide) +{ + return true; +} + void env_sound::SpawnKey(string strField, string strKey) { diff --git a/src/gs-entbase/client/env_soundscape.qc b/src/gs-entbase/client/env_soundscape.qc index d920e1c6..928705f0 100644 --- a/src/gs-entbase/client/env_soundscape.qc +++ b/src/gs-entbase/client/env_soundscape.qc @@ -36,6 +36,7 @@ public: virtual void Respawn(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); private: int m_iID; @@ -48,6 +49,12 @@ env_soundscape g_entSoundScape; env_soundscape g_entOldScape; env_soundscape g_ambientsound; +bool +env_soundscape::CanSpawn(bool clientSide) +{ + return true; +} + void env_soundscape::SpawnKey(string strField, string strKey) { diff --git a/src/gs-entbase/client/env_sun.qc b/src/gs-entbase/client/env_sun.qc index e027c9fe..e143e2a6 100644 --- a/src/gs-entbase/client/env_sun.qc +++ b/src/gs-entbase/client/env_sun.qc @@ -55,6 +55,7 @@ public: virtual float predraw(void); virtual void SpawnKey(string,string); virtual void RendererRestarted(void); + virtual bool CanSpawn(bool); private: vector m_vecLensPos; @@ -71,6 +72,12 @@ env_sun::RendererRestarted(void) precache_pic("textures/sfx/flare4"); } +bool +env_sun::CanSpawn(bool clientSide) +{ + return true; +} + float env_sun::predraw(void) { diff --git a/src/gs-entbase/client/func_dustcloud.qc b/src/gs-entbase/client/func_dustcloud.qc index a3149d95..b24f13b0 100644 --- a/src/gs-entbase/client/func_dustcloud.qc +++ b/src/gs-entbase/client/func_dustcloud.qc @@ -34,6 +34,7 @@ public: virtual void Spawned(void); virtual float predraw(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); private: int m_iCount; @@ -66,6 +67,12 @@ private: float m_flLifeTime; }; +bool +func_dustcloud::CanSpawn(bool clientSide) +{ + return true; +} + float func_dustcloud_cloud::predraw(void) { diff --git a/src/gs-entbase/client/func_dustmotes.qc b/src/gs-entbase/client/func_dustmotes.qc index a3d66d0c..40b3e76c 100644 --- a/src/gs-entbase/client/func_dustmotes.qc +++ b/src/gs-entbase/client/func_dustmotes.qc @@ -32,6 +32,7 @@ public: virtual void Spawned(void); virtual float predraw(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); private: int m_iCount; @@ -39,6 +40,12 @@ private: float m_flNexTime; }; +bool +func_dustmotes::CanSpawn(bool clientSide) +{ + return true; +} + float func_dustmotes::predraw(void) { diff --git a/src/gs-entbase/client/func_lod.qc b/src/gs-entbase/client/func_lod.qc index 06289687..f0ccbcbb 100644 --- a/src/gs-entbase/client/func_lod.qc +++ b/src/gs-entbase/client/func_lod.qc @@ -39,11 +39,18 @@ public: virtual void Spawned(void); virtual float predraw(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); private: int m_iDisappearDist; }; +bool +func_lod::CanSpawn(bool clientSide) +{ + return true; +} + float func_lod::predraw(void) { diff --git a/src/gs-entbase/client/func_smokevolume.qc b/src/gs-entbase/client/func_smokevolume.qc index 4a0997db..9b1fb54f 100644 --- a/src/gs-entbase/client/func_smokevolume.qc +++ b/src/gs-entbase/client/func_smokevolume.qc @@ -36,6 +36,7 @@ public: virtual void Spawned(void); virtual float predraw(void); virtual void SpawnKey(string, string); + virtual bool CanSpawn(bool); private: int m_iCount; @@ -177,6 +178,12 @@ func_smokevolume::Spawned(void) localcmd(sprintf(g_dustcloud_cfg, m_strParticle));*/ } +bool +func_smokevolume::CanSpawn(bool clientSide) +{ + return true; +} + void func_smokevolume::SpawnKey(string strField, string strKey) { diff --git a/src/gs-entbase/client/info_notnull.qc b/src/gs-entbase/client/info_notnull.qc index 1dd2eb0e..f9c68737 100644 --- a/src/gs-entbase/client/info_notnull.qc +++ b/src/gs-entbase/client/info_notnull.qc @@ -18,8 +18,16 @@ class info_notnull:NSEntity { public: void info_notnull(void); + virtual bool CanSpawn(bool); }; + +bool +info_notnull::CanSpawn(bool clientSide) +{ + return true; +} + void info_notnull::info_notnull(void) { diff --git a/src/gs-entbase/client/infodecal.qc b/src/gs-entbase/client/infodecal.qc index 782e2118..b08947e1 100644 --- a/src/gs-entbase/client/infodecal.qc +++ b/src/gs-entbase/client/infodecal.qc @@ -21,6 +21,7 @@ public: void infodecal(void); virtual void SpawnKey(string, string); virtual float predraw(void); + virtual bool CanSpawn(bool); private: decal m_decChild; @@ -38,6 +39,12 @@ infodecal::predraw(void) return (PREDRAW_NEXT); } +bool +infodecal::CanSpawn(bool clientSide) +{ + return true; +} + void infodecal::SpawnKey(string strField, string strKey) { diff --git a/src/gs-entbase/client/light_environment.qc b/src/gs-entbase/client/light_environment.qc index 4862b9d2..48e5396f 100644 --- a/src/gs-entbase/client/light_environment.qc +++ b/src/gs-entbase/client/light_environment.qc @@ -57,6 +57,7 @@ public: virtual void Respawn(void); virtual void SpawnKey(string,string); + virtual bool CanSpawn(bool); }; @@ -83,6 +84,12 @@ light_environment::SpawnKey(string strField, string strKey) } } +bool +light_environment::CanSpawn(bool clientSide) +{ + return true; +} + void light_environment::light_environment(void) { diff --git a/src/gs-entbase/client/point_message.qc b/src/gs-entbase/client/point_message.qc index 48fc7a2d..6d270503 100644 --- a/src/gs-entbase/client/point_message.qc +++ b/src/gs-entbase/client/point_message.qc @@ -34,6 +34,7 @@ class point_message:NSEntity public: void point_message(void); virtual void SpawnKey(string, string); + virtual bool CanSpawn(bool); private: float m_flRadius; @@ -67,6 +68,12 @@ point_message::point_message(void) isCSQC = true; } +bool +point_message::CanSpawn(bool clientSide) +{ + return true; +} + int PointMessage_Visible(vector p1, vector p2, vector ang) { diff --git a/src/gs-entbase/client/prop_static.qc b/src/gs-entbase/client/prop_static.qc index 33a240d1..c98f90dd 100644 --- a/src/gs-entbase/client/prop_static.qc +++ b/src/gs-entbase/client/prop_static.qc @@ -23,6 +23,7 @@ public: virtual void SpawnKey(string,string); virtual void Respawn(void); virtual void Spawned(void); + virtual bool CanSpawn(bool); private: int m_iBody; @@ -66,6 +67,12 @@ prop_static::Spawned(void) setsize(this, mins * scale, maxs * scale); } +bool +prop_static::CanSpawn(bool clientSide) +{ + return true; +} + void prop_static::prop_static(void) { diff --git a/src/gs-entbase/client/sky_camera.qc b/src/gs-entbase/client/sky_camera.qc index 1f6de5a9..4c94b49e 100644 --- a/src/gs-entbase/client/sky_camera.qc +++ b/src/gs-entbase/client/sky_camera.qc @@ -40,6 +40,7 @@ public: void sky_camera(void); virtual void SpawnKey(string, string); + virtual bool CanSpawn(bool); }; void @@ -59,6 +60,12 @@ sky_camera::SpawnKey(string strField, string strKey) } } +bool +sky_camera::CanSpawn(bool clientSide) +{ + return true; +} + void sky_camera::sky_camera(void) { diff --git a/src/server/NSGameRules.h b/src/server/NSGameRules.h index b25387e7..3b5f444b 100644 --- a/src/server/NSGameRules.h +++ b/src/server/NSGameRules.h @@ -34,6 +34,7 @@ public: /* overrides */ virtual void Save(float); virtual void Restore(string,string); + virtual void RestoreComplete(void); /** Overridable: Called when all map entities have initialized. */ virtual void InitPostEnts(void); diff --git a/src/server/NSGameRules.qc b/src/server/NSGameRules.qc index bdd60f47..a7517d9e 100644 --- a/src/server/NSGameRules.qc +++ b/src/server/NSGameRules.qc @@ -47,6 +47,13 @@ NSGameRules::Restore(string strKey, string strValue) } } +void +NSGameRules::RestoreComplete(void) +{ + /* mark this as our active game-rule upon restore. */ + g_grMode = this; +} + /* init */ void NSGameRules::InitPostEnts(void) diff --git a/src/server/entry.qc b/src/server/entry.qc index a69834e1..9890caca 100644 --- a/src/server/entry.qc +++ b/src/server/entry.qc @@ -751,4 +751,12 @@ CheckSpawn(void() spawnfunc) print(sprintf("^1Cannot find entity class ^7%s\n", self.classname)); remove(self); } + + /* check if this entity was meant to spawn on the client-side only */ + if (self.identity) { + NSEntity ent = (NSEntity)self; + + if (ent.CanSpawn(false) == false) + ent.Destroy(); + } } diff --git a/src/shared/NSEntity.h b/src/shared/NSEntity.h index e7070b5a..4da538e3 100644 --- a/src/shared/NSEntity.h +++ b/src/shared/NSEntity.h @@ -110,6 +110,10 @@ public: collision and maintain the appearance it had before getting removed. */ virtual void MakeStatic(void); + /** Returns if this entity can spawned from the map file. + @param clientSide If it's being spawned on the client-side. */ + virtual bool CanSpawn(bool clientSide); + #ifdef SERVER virtual void Respawn(void); virtual void Input(entity,string,string); @@ -119,9 +123,6 @@ public: /** Called when we need to re-align the entity to our parent entity. */ virtual void ParentUpdate(void); - /** Called when the entity has been successfully restored from a savegame file. */ - virtual void RestoreComplete(void); - /** Run each tic after physics are run to determine if we need to send updates over the network. */ virtual void EvaluateEntity(void); diff --git a/src/shared/NSEntity.qc b/src/shared/NSEntity.qc index cf4cc493..1c5ef141 100644 --- a/src/shared/NSEntity.qc +++ b/src/shared/NSEntity.qc @@ -717,10 +717,6 @@ void NSEntity::Restore( string strKey, string strValue ) { } } -void NSEntity::RestoreComplete( void ) { - /* this is where we can handle anything post-loading */ -} - void NSEntity::Input( entity eAct, string strInput, string strData ) { switch ( strInput ) { case "Kill": @@ -825,6 +821,16 @@ void NSEntity::MakeStatic( void ) { makestatic( this ); } +bool +NSEntity::CanSpawn(bool clientSide) +{ + /* in most cases, we don't need these to spawn on the client-side */ + if (clientSide) + return false; + else + return true; +} + bool NSEntity::WithinBounds( entity check ) { if not ( check.absmin[0] >= absmin[0] && check.absmax[0] <= absmax[0] ) return ( false ); diff --git a/src/shared/NSIO.h b/src/shared/NSIO.h index c3eef897..9fe9e390 100644 --- a/src/shared/NSIO.h +++ b/src/shared/NSIO.h @@ -66,6 +66,9 @@ public: needs to be read back in here. */ virtual void Restore(string,string); + /** Called when the entity has been successfully restored from a savegame file. */ + virtual void RestoreComplete(void); + /** Called when we are being prompted by another object/function with an input message. */ virtual void Input(entity,string,string); diff --git a/src/shared/NSIO.qc b/src/shared/NSIO.qc index 0d6245a8..e570b3af 100644 --- a/src/shared/NSIO.qc +++ b/src/shared/NSIO.qc @@ -628,6 +628,11 @@ NSIO::Restore(string strKey, string strValue) break; } } + +void +NSIO::RestoreComplete( void ) { + /* this is where we can handle anything post-loading */ +} #endif void diff --git a/src/shared/NSRenderableEntity.qc b/src/shared/NSRenderableEntity.qc index e417b7fd..37c74d86 100644 --- a/src/shared/NSRenderableEntity.qc +++ b/src/shared/NSRenderableEntity.qc @@ -139,7 +139,7 @@ NSRenderableEntity::SendEntity(entity ePEnt, float flChanged) /* no rendermode means no extra fields */ if (m_iRenderMode == RM_NORMAL) { flChanged &= ~RDENT_CHANGED_RENDERMODE; - flChanged &= ~RDENT_CHANGED_RENDERCOLOR; + //flChanged &= ~RDENT_CHANGED_RENDERCOLOR; /* glowmod needs this */ flChanged &= ~RDENT_CHANGED_RENDERAMT; }