Entity debugger
authorTimePath <andrew.hardaker1995@gmail.com>
Thu, 29 Oct 2015 07:04:31 +0000 (18:04 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Thu, 29 Oct 2015 07:04:31 +0000 (18:04 +1100)
110 files changed:
qcsrc/client/announcer.qc
qcsrc/client/commands/cl_cmd.qc
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/damage.qc
qcsrc/client/generator.qc
qcsrc/client/gibs.qc
qcsrc/client/gibs.qh
qcsrc/client/hud.qh
qcsrc/client/main.qc
qcsrc/client/mapvoting.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/modeleffects.qc
qcsrc/client/rubble.qc
qcsrc/client/shownames.qc
qcsrc/client/tuba.qc
qcsrc/client/view.qc
qcsrc/common/constants.qh
qcsrc/common/deathtypes/all.qh
qcsrc/common/debug.qh [new file with mode: 0644]
qcsrc/common/effects/all.qc
qcsrc/common/effects/all.qh
qcsrc/common/effects/effect.qh
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/items/inventory.qh
qcsrc/common/minigames/cl_minigames.qh
qcsrc/common/minigames/minigame/nmm.qc
qcsrc/common/minigames/minigame/ttt.qc
qcsrc/common/minigames/sv_minigames.qc
qcsrc/common/minigames/sv_minigames.qh
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/mutator/waypoints/all.qh
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/nades/all.qc
qcsrc/common/net_notice.qc
qcsrc/common/notifications.qc
qcsrc/common/triggers/func/bobbing.qc
qcsrc/common/triggers/func/door.qc
qcsrc/common/triggers/func/fourier.qc
qcsrc/common/triggers/func/pendulum.qc
qcsrc/common/triggers/func/vectormamamam.qc
qcsrc/common/triggers/subs.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/triggers.qc
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/turrets/util.qc
qcsrc/common/util.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/blaster.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/porto.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/lib/defer.qh
qcsrc/lib/net.qh
qcsrc/lib/oo.qh
qcsrc/lib/sortlist.qc
qcsrc/lib/spawnfunc.qh
qcsrc/lib/urllib.qc
qcsrc/lib/warpzone/client.qc
qcsrc/lib/warpzone/common.qc
qcsrc/lib/warpzone/server.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/server/bot/aim.qc
qcsrc/server/bot/scripting.qc
qcsrc/server/bot/waypoints.qc
qcsrc/server/cheats.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/command/radarmap.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/constants.qh
qcsrc/server/ent_cs.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_models.qc
qcsrc/server/g_violence.qc
qcsrc/server/g_world.qc
qcsrc/server/ipban.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_keepaway.qc
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc
qcsrc/server/mutators/mutator/gamemode_onslaught.qc
qcsrc/server/mutators/mutator/mutator_nades.qc
qcsrc/server/mutators/mutator/mutator_overkill.qc
qcsrc/server/mutators/mutator/sandbox.qc
qcsrc/server/pathlib/main.qc
qcsrc/server/portals.qc
qcsrc/server/scores.qc
qcsrc/server/spawnpoints.qc
qcsrc/server/steerlib.qc
qcsrc/server/sv_main.qc
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/throwing.qc
qcsrc/server/weapons/weaponsystem.qc

index 2ad1c67..a2e13be 100644 (file)
@@ -78,19 +78,18 @@ void Announcer_Gamestart()
        {
                if(time < startTime)
                {
-                       entity e = find(world, classname, "announcer_countdown");
-                       if (!e)
+                       static entity announcer_countdown;
+                       if (!announcer_countdown)
                        {
-                               e = spawn();
-                               e.classname = "announcer_countdown";
-                               e.think = Announcer_Countdown;
+                               announcer_countdown = new(announcer_countdown);
+                               announcer_countdown.think = Announcer_Countdown;
                        }
 
                        if(time + 5.0 < startTime) // if connecting to server while restart was active don't always play prepareforbattle
-                       if(time > e.nextthink) // don't play it again if countdown was already going
+                       if(time > announcer_countdown.nextthink) // don't play it again if countdown was already going
                                Local_Notification(MSG_ANNCE, ANNCE_PREPARE);
 
-                       e.nextthink = startTime - floor(startTime - time); //synchronize nextthink to startTime
+                       announcer_countdown.nextthink = startTime - floor(startTime - time); //synchronize nextthink to startTime
                }
        }
 
index db4d59a..489e86c 100644 (file)
@@ -172,15 +172,13 @@ void LocalCommand_debugmodel(int request, int argc)
                case CMD_REQUEST_COMMAND:
                {
                        string modelname = argv(1);
-                       entity debugmodel_entity;
 
-                       debugmodel_entity = spawn();
+                       entity debugmodel_entity = new(debugmodel);
                        precache_model(modelname);
                        _setmodel(debugmodel_entity, modelname);
                        setorigin(debugmodel_entity, view_origin);
                        debugmodel_entity.angles = view_angles;
                        debugmodel_entity.draw = DrawDebugModel;
-                       debugmodel_entity.classname = "debugmodel";
 
                        return;
                }
index e2e0e93..e7a6a6b 100644 (file)
@@ -136,8 +136,7 @@ void CSQCPlayer_ModelAppearance_Apply(bool islocalplayer)
        // which one is ALWAYS good?
        if (!forceplayermodels_goodmodel)
        {
-               entity e;
-               e = spawn();
+               entity e = spawn();
                precache_model(cvar_defstring("_cl_playermodel"));
                _setmodel(e, cvar_defstring("_cl_playermodel"));
                forceplayermodels_goodmodel = e.model;
@@ -168,8 +167,7 @@ void CSQCPlayer_ModelAppearance_Apply(bool islocalplayer)
                forceplayermodels_attempted = 1;
 
                // only if this failed, find it out on our own
-               entity e;
-               e = spawn();
+               entity e = spawn();
                _setmodel(e, autocvar__cl_playermodel); // this is harmless, see below
                forceplayermodels_modelisgoodmodel = fexists(e.model);
                forceplayermodels_model = e.model;
@@ -180,8 +178,7 @@ void CSQCPlayer_ModelAppearance_Apply(bool islocalplayer)
 
        if(autocvar_cl_forcemyplayermodel != "" && autocvar_cl_forcemyplayermodel != forceplayermodels_mymodel)
        {
-               entity e;
-               e = spawn();
+               entity e = spawn();
                _setmodel(e, autocvar_cl_forcemyplayermodel); // this is harmless, see below
                forceplayermodels_myisgoodmodel = fexists(e.model);
                forceplayermodels_mymodel = e.model;
index 34890e0..2d7c4f2 100644 (file)
@@ -105,10 +105,10 @@ void DamageEffect(vector hitorg, float thedamage, int type, int specnum)
                else { return; } // objects don't bleed
        }
 
-       e = spawn();
+       e = new(damage);
+       make_pure(e);
        setmodel(e, MDL_Null); // necessary to attach and read origin
        setattachment(e, self, gettaginfo_name); // attach to the given bone
-       e.classname = "damage";
        e.owner = self;
        e.cnt = time + life;
        e.team = _particleeffectnum(effectname);
@@ -119,6 +119,7 @@ void DamageEffect(vector hitorg, float thedamage, int type, int specnum)
 
 void Ent_DamageInfo(float isNew)
 {SELFPARAM();
+       make_pure(this);
        float thedamage, rad, edge, thisdmg;
        bool hitplayer = false;
        int species, forcemul;
index d7114d1..226d13d 100644 (file)
@@ -32,9 +32,7 @@ void ons_generator_ray_draw(entity this)
 
 void ons_generator_ray_spawn(vector org)
 {
-       entity e;
-       e = spawn();
-       e.classname = "ons_ray";
+       entity e = new(ons_ray);
        setmodel(e, MDL_ONS_RAY);
        setorigin(e, org);
        e.angles = randomvec() * 360;
index 4afa5eb..5c5e69f 100644 (file)
@@ -123,7 +123,6 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
 
        // TODO remove some gibs according to cl_nogibs
        gib = RubbleNew("gib");
-       gib.classname = "gib";
        gib.move_movetype = MOVETYPE_BOUNCE;
        gib.gravity = 1;
        gib.solid = SOLID_CORPSE;
@@ -159,23 +158,19 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector
        RubbleLimit("gib", autocvar_cl_gibs_maxcount, Gib_Delete);
 }
 
-void Ent_GibSplash(bool isNew)
-{SELFPARAM();
-       int amount, type, specnum;
-       vector org, vel;
-       string specstr;
-       bool issilent;
-       string gentle_prefix = "morphed_";
+REGISTER_NET_TEMP(net_gibsplash, bool isNew)
+{
+       Net_Accept(net_gibsplash);
 
-       float randomvalue;
-       int c;
+       string gentle_prefix = "morphed_";
 
-       type = ReadByte(); // gibbage type
-       amount = ReadByte() / 16.0; // gibbage amount
+       int type = ReadByte(); // gibbage type
+       int amount = ReadByte() / 16.0; // gibbage amount
+       vector org;
        org.x = ReadShort() * 4 + 2;
        org.y = ReadShort() * 4 + 2;
        org.z = ReadShort() * 4 + 2;
-       vel = decompressShortVector(ReadShort());
+       vector vel = decompressShortVector(ReadShort());
 
        float cl_gentle_gibs = autocvar_cl_gentle_gibs;
        if(cl_gentle_gibs || autocvar_cl_gentle)
@@ -203,18 +198,18 @@ void Ent_GibSplash(bool isNew)
        if(amount <= 0 || !isNew)
                return;
 
-       setorigin(self, org); // for the sounds
+       setorigin(this, org); // for the sounds
 
-       specnum = (type & 0x78) / 8; // blood/gibmodel type: using four bits (0..7, bit indexes 3,4,5)
-       issilent = (type & 0x40);
+       int specnum = (type & 0x78) / 8; // blood/gibmodel type: using four bits (0..7, bit indexes 3,4,5)
+       bool issilent = (type & 0x40);
        type = type & 0x87; // remove the species bits: bit 7 = gentle, bit 0,1,2 = kind of gib
-       specstr = species_prefix(specnum);
+       string specstr = species_prefix(specnum);
 
        switch(type)
        {
                case 0x01:
                        if(!issilent)
-                               sound (self, CH_PAIN, SND_GIB, VOL_BASE, ATTEN_NORM);
+                               sound (this, CH_PAIN, SND_GIB, VOL_BASE, ATTEN_NORM);
 
                        if(prandom() < amount)
                                TossGib ("models/gibs/eye.md3", org, org, vel, prandomvec() * 150, specnum, 0, issilent);
@@ -222,9 +217,9 @@ void Ent_GibSplash(bool isNew)
                        if(prandom() < amount)
                                TossGib ("models/gibs/bloodyskull.md3", org, org + 16 * prandomvec(), vel, prandomvec() * 100, specnum, 0, issilent);
 
-                       for(c = 0; c < amount; ++c)
+                       for(int c = 0; c < amount; ++c)
                        {
-                               randomvalue = amount - c;
+                               int randomvalue = amount - c;
 
                                if(prandom() < randomvalue)
                                        TossGib ("models/gibs/arm.md3", org, org + 16 * prandomvec() + '0 0 8', vel, prandomvec() * (prandom() * 120 + 90), specnum,0, issilent);
@@ -267,4 +262,5 @@ void Ent_GibSplash(bool isNew)
                        // no gibs in gentle mode, sorry
                        break;
        }
+       remove(this);
 }
index eb63aa1..69058f6 100644 (file)
@@ -21,6 +21,4 @@ void Gib_Draw(entity this);
 
 void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector vrand, int specnum, bool destroyontouch, bool issilent);
 
-void Ent_GibSplash(bool isNew);
-
 #endif
index ba9cb17..cbdfb0c 100644 (file)
@@ -12,6 +12,7 @@ REGISTER_REGISTRY(Registerhud_panels)
 #define REGISTER_HUD_PANEL(id, draw_func, name, configflags, showflags) \
        void draw_func(); \
        REGISTER(Registerhud_panels, HUD_PANEL, hud_panels, id, m_id, new(hud_panel)) { \
+               make_pure(this); \
                this.panel_id = this.m_id; \
                this.panel_draw = draw_func; \
                this.panel_name = #name; \
index 9d20c40..fd5da62 100644 (file)
@@ -42,8 +42,7 @@ void clearentity(entity e)
 {
        if (!clearentity_ent)
        {
-               clearentity_ent = spawn();
-               clearentity_ent.classname = "clearentity";
+               clearentity_ent = new(clearentity);
        }
        int n = e.entnum;
        copyentity(clearentity_ent, e);
@@ -297,7 +296,10 @@ void Playerchecker_Think()
                        {
                                // player connected
                                if (!e)
-                                       playerslots[i] = e = spawn();
+                               {
+                                       playerslots[i] = e = new(playerslot);
+                                       make_pure(e);
+                               }
                                e.sv_entnum = i;
                                e.ping = 0;
                                e.ping_packetloss = 0;
@@ -316,8 +318,8 @@ void Porto_Init();
 void TrueAim_Init();
 void PostInit(void)
 {
-       entity playerchecker;
-       playerchecker = spawn();
+       entity playerchecker = new(playerchecker);
+       make_pure(playerchecker);
        playerchecker.think = Playerchecker_Think;
        playerchecker.nextthink = time + 0.2;
 
@@ -373,8 +375,9 @@ void Ent_RemoveEntCS()
 }
 void Ent_ReadEntCS()
 {SELFPARAM();
+       make_pure(this);
+       this.classname = "entcs_receiver";
        InterpolateOrigin_Undo();
-       self.classname = "entcs_receiver";
        int sf = ReadByte();
 
        if(sf & BIT(0))
@@ -418,6 +421,7 @@ void Ent_RemovePlayerScore()
 
 void Ent_ReadPlayerScore()
 {SELFPARAM();
+       make_pure(this);
        int i, n;
        bool isNew;
        entity o;
@@ -440,9 +444,13 @@ void Ent_ReadPlayerScore()
 
        self.sv_entnum = n;
 
-       if (!(playerslots[self.sv_entnum]))
-               playerslots[self.sv_entnum] = spawn();
-       o = self.owner = playerslots[self.sv_entnum];
+       o = playerslots[self.sv_entnum];
+       if (!o)
+       {
+               o = playerslots[self.sv_entnum] = new(playerslot);
+               make_pure(o);
+       }
+       self.owner = o;
        o.sv_entnum = self.sv_entnum;
        o.gotscores = 1;
 
@@ -476,6 +484,7 @@ void Ent_ReadPlayerScore()
 
 void Ent_ReadTeamScore()
 {SELFPARAM();
+       make_pure(this);
        int i;
        entity o;
 
@@ -505,6 +514,7 @@ void Ent_ReadTeamScore()
 
 void Ent_ClientData()
 {
+       make_pure(self);
        float newspectatee_status;
 
     int f = ReadByte();
@@ -554,6 +564,7 @@ void Ent_ClientData()
 
 void Ent_Nagger()
 {
+       make_pure(self);
     int i, j, b, f;
 
     int nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
@@ -609,6 +620,7 @@ void Ent_Nagger()
 
 void Ent_EliminatedPlayers()
 {
+       make_pure(self);
     int i, j, b, f;
 
     int sf = ReadByte();
@@ -630,14 +642,15 @@ void Ent_EliminatedPlayers()
 
 void Ent_RandomSeed()
 {
-       float s;
+       make_pure(self);
        prandom_debug();
-       s = ReadShort();
+       float s = ReadShort();
        psrandom(s);
 }
 
 void Ent_ReadAccuracy()
 {
+       make_pure(self);
     int sf = ReadInt24_t();
        if (sf == 0) {
                for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
@@ -768,11 +781,12 @@ void Ent_RadarLink();
 void Ent_Init();
 void Ent_ScoresInfo();
 void CSQC_Ent_Update(float bIsNewEntity)
-{SELFPARAM();
+{
+       SELFPARAM();
        int t = ReadByte();
 
        if(autocvar_developer_csqcentities)
-               LOG_INFOF("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, self, self.entnum, self.enttype, t);
+               LOG_INFOF("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, this, this.entnum, this.enttype, t);
 
        // set up the "time" global for received entities to be correct for interpolation purposes
        float savetime = time;
@@ -788,13 +802,13 @@ void CSQC_Ent_Update(float bIsNewEntity)
        }
 
 #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
-       if(self.enttype)
+       if(this.enttype)
        {
-               if(t != self.enttype || bIsNewEntity)
+               if(t != this.enttype || bIsNewEntity)
                {
-                       LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(self), self.entnum, self.enttype, t);
+                       LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(this), this.entnum, this.enttype, t);
                        Ent_Remove();
-                       clearentity(self);
+                       clearentity(this);
                        bIsNewEntity = 1;
                }
        }
@@ -802,84 +816,83 @@ void CSQC_Ent_Update(float bIsNewEntity)
        {
                if(!bIsNewEntity)
                {
-                       LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(self), self.entnum, t);
+                       LOG_INFOF("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(this), this.entnum, t);
                        bIsNewEntity = 1;
                }
        }
 #endif
-       self.enttype = t;
+       this.enttype = t;
        bool done = false;
        FOREACH(LinkedEntities, it.m_id == t, LAMBDA(
-               it.m_read(self, bIsNewEntity);
+               it.m_read(this, bIsNewEntity);
                done = true;
                break;
        ));
        if (!done)
        switch(t)
        {
-               case ENT_CLIENT_MUTATOR: {
+               #define HANDLE(t) case t: this.classname = #t; this.sourceLocFile = __FILE__; this.sourceLocLine = __LINE__;
+               HANDLE(ENT_CLIENT_MUTATOR) {
                        int mutID = ReadMutator();
                        if (!MUTATOR_CALLHOOK(CSQC_Ent_Update, mutID, bIsNewEntity))
-                       error(sprintf("Unknown mutator type in CSQC_Ent_Update (mutID: %d, edict: %d, classname: %s)\n", mutID, num_for_edict(self), self.classname));
+                       error(sprintf("Unknown mutator type in CSQC_Ent_Update (mutID: %d, edict: %d, classname: %s)\n", mutID, num_for_edict(this), this.classname));
                        break;
                }
-               case ENT_CLIENT_ENTCS: Ent_ReadEntCS(); break;
-               case ENT_CLIENT_SCORES: Ent_ReadPlayerScore(); break;
-               case ENT_CLIENT_TEAMSCORES: Ent_ReadTeamScore(); break;
-               case ENT_CLIENT_POINTPARTICLES: Ent_PointParticles(); break;
-               case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break;
-               case ENT_CLIENT_LASER: Ent_Laser(); break;
-               case ENT_CLIENT_NAGGER: Ent_Nagger(); break;
-               case ENT_CLIENT_ELIMINATEDPLAYERS: Ent_EliminatedPlayers(); break;
-               case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break;
-               case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
-               case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(bIsNewEntity); break;
-               case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(bIsNewEntity); break;
-               case ENT_CLIENT_INIT: Ent_Init(); break;
-               case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break;
-               case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break;
-               case ENT_CLIENT_CLIENTDATA: Ent_ClientData(); break;
-               case ENT_CLIENT_RANDOMSEED: Ent_RandomSeed(); break;
-               case ENT_CLIENT_WALL: Ent_Wall(); break;
-               case ENT_CLIENT_MODELEFFECT: Ent_ModelEffect(bIsNewEntity); break;
-               case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break;
-               case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break;
-               case ENT_CLIENT_WARPZONE_CAMERA: WarpZone_Camera_Read(bIsNewEntity); break;
-               case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break;
-               case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break;
-               case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break;
-               case ENT_CLIENT_INVENTORY: Inventory_Read(self); break;
-               case ENT_CLIENT_ARC_BEAM: Ent_ReadArcBeam(bIsNewEntity); break;
-               case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
-               case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
-               case ENT_CLIENT_TURRET: ent_turret(); break;
-               case ENT_CLIENT_GENERATOR: ent_generator(); break;
-               case ENT_CLIENT_CONTROLPOINT_ICON: ent_cpicon(this); break;
-               case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
-               case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break;
-               case ENT_CLIENT_BUMBLE_RAYGUN: bumble_raygun_read(bIsNewEntity); break;
-               case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(bIsNewEntity); break;
-               case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break;
-               case ENT_CLIENT_NOTIFICATION: Read_Notification(bIsNewEntity); break;
-               case ENT_CLIENT_MINIGAME: ent_read_minigame(); break;
-               case ENT_CLIENT_VIEWLOC: ent_viewloc(); break;
-               case ENT_CLIENT_VIEWLOC_TRIGGER: ent_viewloc_trigger(); break;
-               case ENT_CLIENT_LADDER: ent_func_ladder(); break;
-               case ENT_CLIENT_TRIGGER_PUSH: ent_trigger_push(); break;
-               case ENT_CLIENT_TARGET_PUSH: ent_target_push(); break;
-               case ENT_CLIENT_CONVEYOR: ent_conveyor(); break;
-               case ENT_CLIENT_DOOR: ent_door(); break;
-               case ENT_CLIENT_PLAT: ent_plat(); break;
-               case ENT_CLIENT_SWAMP: ent_swamp(); break;
-               case ENT_CLIENT_CORNER: ent_corner(); break;
-               case ENT_CLIENT_KEYLOCK: ent_keylock(); break;
-               case ENT_CLIENT_TRAIN: ent_train(); break;
-               case ENT_CLIENT_TRIGGER_IMPULSE: ent_trigger_impulse(); break;
-               case ENT_CLIENT_EFFECT: Read_Effect(bIsNewEntity); break;
-
+               HANDLE(ENT_CLIENT_ENTCS)                                        Ent_ReadEntCS();                                                                break;
+               HANDLE(ENT_CLIENT_SCORES)                                       Ent_ReadPlayerScore();                                                  break;
+               HANDLE(ENT_CLIENT_TEAMSCORES)                           Ent_ReadTeamScore();                                                    break;
+               HANDLE(ENT_CLIENT_POINTPARTICLES)                       Ent_PointParticles();                                                   break;
+               HANDLE(ENT_CLIENT_RAINSNOW)                                     Ent_RainOrSnow();                                                               break;
+               HANDLE(ENT_CLIENT_LASER)                                        Ent_Laser();                                                                    break;
+               HANDLE(ENT_CLIENT_NAGGER)                                       Ent_Nagger();                                                                   break;
+               HANDLE(ENT_CLIENT_ELIMINATEDPLAYERS)            Ent_EliminatedPlayers();                                                break;
+               HANDLE(ENT_CLIENT_RADARLINK)                            Ent_RadarLink();                                                                break;
+               HANDLE(ENT_CLIENT_PROJECTILE)                           Ent_Projectile();                                                               break;
+               HANDLE(ENT_CLIENT_DAMAGEINFO)                           Ent_DamageInfo(bIsNewEntity);                                   break;
+               HANDLE(ENT_CLIENT_INIT)                                         Ent_Init();                                                                             break;
+               HANDLE(ENT_CLIENT_SCORES_INFO)                          Ent_ScoresInfo();                                                               break;
+               HANDLE(ENT_CLIENT_MAPVOTE)                                      Ent_MapVote();                                                                  break;
+               HANDLE(ENT_CLIENT_CLIENTDATA)                           Ent_ClientData();                                                               break;
+               HANDLE(ENT_CLIENT_RANDOMSEED)                           Ent_RandomSeed();                                                               break;
+               HANDLE(ENT_CLIENT_WALL)                                         Ent_Wall();                                                                             break;
+               HANDLE(ENT_CLIENT_MODELEFFECT)                          Ent_ModelEffect(bIsNewEntity);                                  break;
+               HANDLE(ENT_CLIENT_TUBANOTE)                                     Ent_TubaNote(bIsNewEntity);                                             break;
+               HANDLE(ENT_CLIENT_WARPZONE)                                     WarpZone_Read(bIsNewEntity);                                    break;
+               HANDLE(ENT_CLIENT_WARPZONE_CAMERA)                      WarpZone_Camera_Read(bIsNewEntity);                             break;
+               HANDLE(ENT_CLIENT_WARPZONE_TELEPORTED)          WarpZone_Teleported_Read(bIsNewEntity);                 break;
+               HANDLE(ENT_CLIENT_TRIGGER_MUSIC)                        Ent_ReadTriggerMusic();                                                 break;
+               HANDLE(ENT_CLIENT_HOOK)                                         Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK);    break;
+               HANDLE(ENT_CLIENT_INVENTORY)                            Inventory_Read(this);                                                   break;
+               HANDLE(ENT_CLIENT_ARC_BEAM)                                     Ent_ReadArcBeam(bIsNewEntity);                                  break;
+               HANDLE(ENT_CLIENT_ACCURACY)                                     Ent_ReadAccuracy();                                                             break;
+               HANDLE(ENT_CLIENT_AUXILIARYXHAIR)                       Net_AuXair2(bIsNewEntity);                                              break;
+               HANDLE(ENT_CLIENT_TURRET)                                       ent_turret();                                                                   break;
+               HANDLE(ENT_CLIENT_GENERATOR)                            ent_generator();                                                                break;
+               HANDLE(ENT_CLIENT_CONTROLPOINT_ICON)            ent_cpicon(this);                                                               break;
+               HANDLE(ENT_CLIENT_MODEL)                                        CSQCModel_Read(bIsNewEntity);                                   break;
+               HANDLE(ENT_CLIENT_ITEM)                                         ItemRead(bIsNewEntity);                                                 break;
+               HANDLE(ENT_CLIENT_BUMBLE_RAYGUN)                        bumble_raygun_read(bIsNewEntity);                               break;
+               HANDLE(ENT_CLIENT_SPAWNPOINT)                           Ent_ReadSpawnPoint(bIsNewEntity);                               break;
+               HANDLE(ENT_CLIENT_SPAWNEVENT)                           Ent_ReadSpawnEvent(bIsNewEntity);                               break;
+               HANDLE(ENT_CLIENT_NOTIFICATION)                         Read_Notification(bIsNewEntity);                                break;
+               HANDLE(ENT_CLIENT_MINIGAME)                                     ent_read_minigame();                                                    break;
+               HANDLE(ENT_CLIENT_VIEWLOC)                                      ent_viewloc();                                                                  break;
+               HANDLE(ENT_CLIENT_VIEWLOC_TRIGGER)                      ent_viewloc_trigger();                                                  break;
+               HANDLE(ENT_CLIENT_LADDER)                                       ent_func_ladder();                                                              break;
+               HANDLE(ENT_CLIENT_TRIGGER_PUSH)                         ent_trigger_push();                                                             break;
+               HANDLE(ENT_CLIENT_TARGET_PUSH)                          ent_target_push();                                                              break;
+               HANDLE(ENT_CLIENT_CONVEYOR)                                     ent_conveyor();                                                                 break;
+               HANDLE(ENT_CLIENT_DOOR)                                         ent_door();                                                                             break;
+               HANDLE(ENT_CLIENT_PLAT)                                         ent_plat();                                                                             break;
+               HANDLE(ENT_CLIENT_SWAMP)                                        ent_swamp();                                                                    break;
+               HANDLE(ENT_CLIENT_CORNER)                                       ent_corner();                                                                   break;
+               HANDLE(ENT_CLIENT_KEYLOCK)                                      ent_keylock();                                                                  break;
+               HANDLE(ENT_CLIENT_TRAIN)                                        ent_train();                                                                    break;
+               HANDLE(ENT_CLIENT_TRIGGER_IMPULSE)                      ent_trigger_impulse();                                                  break;
+               #undef HANDLE
                default:
-                       //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
-                       error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", self.enttype, num_for_edict(self), self.classname));
+                       //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), this.enttype));
+                       error(sprintf("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n", this.enttype, num_for_edict(this), this.classname));
                        break;
        }
 
@@ -978,7 +991,7 @@ void Gamemode_Init();
 void Ent_ScoresInfo()
 {SELFPARAM();
     int i;
-       self.classname = "ent_client_scores_info";
+       make_pure(this);
        gametype = ReadInt24_t();
        HUD_ModIcons_SetFunc();
        for(i = 0; i < MAX_SCORE; ++i)
@@ -1001,7 +1014,7 @@ void Ent_ScoresInfo()
 
 void Ent_Init()
 {SELFPARAM();
-       self.classname = "ent_client_init";
+       make_pure(this);
 
        nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
 
index 21bb421..20ff100 100644 (file)
@@ -853,6 +853,7 @@ void MapVote_UpdateVotes()
 
 void Ent_MapVote()
 {
+       make_pure(self);
        int sf = ReadByte();
 
        if(sf & 1)
index 7983e74..036c957 100644 (file)
@@ -123,7 +123,8 @@ entity GetTeam(int Team, bool add)
                return teamslots[num];
        if (!add)
                return world;
-       entity tm = spawn();
+       entity tm = new(team);
+       make_pure(tm);
        tm.team = Team;
        teamslots[num] = tm;
        RegisterTeam(tm);
index d870d81..c17940b 100644 (file)
@@ -24,13 +24,12 @@ void ModelEffect_Draw(entity this)
 }
 
 void Ent_ModelEffect(bool isNew)
-{SELFPARAM();
-       self.classname = "modeleffect_spawner";
+{
+       make_pure(self);
 
        int f = ReadByte();
 
-       entity e = spawn();
-       e.classname = "modeleffect";
+       entity e = new(modeleffect);
        e.model = "from network";
        e.modelindex = ReadShort();
        e.skin = ReadByte();
index 5af2e23..3a0d343 100644 (file)
@@ -45,9 +45,8 @@ void RubbleLimit(string cname, float limit, void() deleteproc)
 
 entity RubbleNew(string cname)
 {
-       entity e;
        // spawn a new entity and return it
-       e = spawn();
+       entity e = spawn();
        e.classname = cname;
        e.creationtime = time;
        return e;
index 80a15ad..05493e2 100644 (file)
@@ -202,8 +202,7 @@ void Draw_ShowNames_All()
                e = shownames_ent[i];
                if(!e)
                {
-                       e = spawn();
-                       e.classname = "shownames_tag";
+                       e = new(shownames_tag);
                        e.sv_entnum = i+1;
                        shownames_ent[i] = e;
                }
index ed29649..e0613b5 100644 (file)
@@ -118,11 +118,9 @@ void Ent_TubaNote(bool isNew)
                                Ent_TubaNote_StopSound();
                        }
                } else {
-                       self.enemy = spawn();
-                       self.enemy.classname = "tuba_note";
+                       self.enemy = new(tuba_note);
                        if (Tuba_PitchStep) {
-                               self.enemy.enemy = spawn();
-                               self.enemy.enemy.classname = "tuba_note_2";
+                               self.enemy.enemy = new(tuba_note_2);
                        }
                        isNew = true;
                }
index c714437..08a281f 100644 (file)
@@ -11,6 +11,7 @@
 #include "mutators/events.qh"
 
 #include "../common/constants.qh"
+#include "../common/debug.qh"
 #include "../common/mapinfo.qh"
 #include "../common/gamemodes/all.qh"
 #include "../common/nades/all.qh"
@@ -110,8 +111,8 @@ void Porto_Draw(entity this)
 
 void Porto_Init()
 {
-       porto = spawn();
-       porto.classname = "porto";
+       porto = new(porto);
+       make_pure(porto);
        porto.draw = Porto_Draw;
        porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
 }
@@ -278,11 +279,11 @@ const float SHOTTYPE_HITENEMY = 4;
 
 void TrueAim_Init()
 {
-       trueaim = spawn();
-       trueaim.classname = "trueaim";
+       trueaim = new(trueaim);
+       make_pure(trueaim);
        trueaim.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
-       trueaim_rifle = spawn();
-       trueaim_rifle.classname = "trueaim_rifle";
+       trueaim_rifle = new(trueaim_rifle);
+       make_pure(trueaim_rifle);
        trueaim_rifle.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 }
 
@@ -1516,13 +1517,11 @@ void CSQC_UpdateView(float w, float h)
 
                if(!nightvision_noise)
                {
-                       nightvision_noise = spawn();
-                       nightvision_noise.classname = "nightvision_noise";
+                       nightvision_noise = new(nightvision_noise);
                }
                if(!nightvision_noise2)
                {
-                       nightvision_noise2 = spawn();
-                       nightvision_noise2.classname = "nightvision_noise2";
+                       nightvision_noise2 = new(nightvision_noise2);
                }
 
                // color tint in yellow
@@ -1836,6 +1835,7 @@ void CSQC_UpdateView(float w, float h)
                WITH(entity, self, e, e.draw2d(e));
        }
        Draw_ShowNames_All();
+       Debug_Draw();
 
        scoreboard_active = HUD_WouldDrawScoreboard();
 
index 47b07fc..b087877 100644 (file)
@@ -81,8 +81,9 @@ const int ENT_CLIENT_LASER = 8;
 const int ENT_CLIENT_NAGGER = 9; // flags [votecalledvote]
 const int ENT_CLIENT_RADARLINK = 11; // flags [startorigin] [endorigin] [startcolor+16*endcolor]
 const int ENT_CLIENT_PROJECTILE = 12;
-const int ENT_CLIENT_GIBSPLASH = 13;
+
 const int ENT_CLIENT_DAMAGEINFO = 14;
+
 const int ENT_CLIENT_INIT = 16;
 const int ENT_CLIENT_MAPVOTE = 17;
 const int ENT_CLIENT_CLIENTDATA = 18;
@@ -123,7 +124,7 @@ const int ENT_CLIENT_CORNER = 70;
 const int ENT_CLIENT_KEYLOCK = 71;
 const int ENT_CLIENT_GENERATOR = 72;
 const int ENT_CLIENT_CONTROLPOINT_ICON = 73;
-const int ENT_CLIENT_EFFECT = 74;
+
 const int ENT_CLIENT_MINIGAME = 75;
 const int ENT_CLIENT_VIEWLOC = 78;
 const int ENT_CLIENT_VIEWLOC_TRIGGER = 79;
index 2bf1169..05548c9 100644 (file)
@@ -12,6 +12,7 @@ REGISTER_REGISTRY(RegisterDeathtypes)
 
 #define REGISTER_DEATHTYPE(id, msg_death, msg_death_by, extra) \
     REGISTER(RegisterDeathtypes, DEATH, Deathtypes, id, m_id, new(deathtype)) { \
+        make_pure(this); \
         this.m_id += DT_FIRST; \
         this.nent_name = #id; \
         this.death_msgextra = extra; \
diff --git a/qcsrc/common/debug.qh b/qcsrc/common/debug.qh
new file mode 100644 (file)
index 0000000..0016492
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+.bool debug;
+.int sv_entnum;
+REGISTER_NET_TEMP(net_debug, bool isNew)
+#ifdef CSQC
+       {
+               Net_Accept(net_debug);
+               this.sv_entnum = ReadShort();
+               if (ReadByte()) make_pure(this);
+               this.origin_x = ReadCoord();
+               this.origin_y = ReadCoord();
+               this.origin_z = ReadCoord();
+               setorigin(this, this.origin);
+               this.debug = true;  // identify server entities by this
+               this.classname = strzone(ReadString());
+               this.sourceLocFile = strzone(ReadString());
+               this.sourceLocLine = ReadInt24_t();
+       }
+#endif
+
+#ifdef SVQC
+       bool debug_send(entity this, entity to, int sf)
+       {
+               int channel = MSG_ONE;
+               msg_entity = to;
+               WriteHeader(channel, net_debug);
+               WriteShort(channel, num_for_edict(this));
+               WriteByte(channel, is_pure(this));
+               WriteCoord(channel, this.origin.x);
+               WriteCoord(channel, this.origin.y);
+               WriteCoord(channel, this.origin.z);
+               WriteString(channel, this.classname);
+               WriteString(channel, this.sourceLocFile);
+               WriteInt24_t(channel, this.sourceLocLine);
+               return true;
+       }
+#endif
+
+bool autocvar_debugdraw;
+
+#ifdef CSQC
+       .int debugdraw_last;
+       vector project_3d_to_2d(vector vec);
+       void Debug_Draw()
+       {
+               if (!autocvar_debugdraw) return;
+               static int debugdraw_frame;
+               ++debugdraw_frame;
+               const int size = 8;
+               for (entity e1 = NULL; (e1 = nextent(e1)); )
+               {
+                       if (e1.debugdraw_last == debugdraw_frame) continue;
+                       int ofs = 0;
+                       for (entity e = findradius(e1.origin, 100); e; e = e.chain)
+                       {
+                               if (e.debugdraw_last == debugdraw_frame) continue;
+                               e.debugdraw_last = debugdraw_frame;
+                               vector rgb = (e.debug) ? '0 0 1' : '1 0 0';
+                               if (is_pure(e))
+                               {
+                                       if (autocvar_debugdraw < 2) continue;
+                                       rgb.y = 1;
+                               }
+                               vector pos = project_3d_to_2d(e.origin);
+                               if (pos.z < 0) continue;
+                               pos.z = 0;
+                               pos.y += ofs * size;
+                               drawcolorcodedstring2(pos,
+                                       sprintf("%d: '%s'@%s:%d", (e.debug ? e.sv_entnum : num_for_edict(e)),
+                                       e.classname, e.sourceLocFile, e.sourceLocLine),
+                                       size * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL);
+                               ++ofs;
+                       }
+               }
+       }
+#endif
+
+#ifdef SVQC
+       GENERIC_COMMAND(debugdraw_sv, "Dump all server entities")
+       {
+               switch (request)
+               {
+                       case CMD_REQUEST_COMMAND:
+                       {
+                               if (!autocvar_debugdraw) return;
+                               int n = 1000;
+                               int rem = n;
+                               for (entity e = NULL; (e = findfloat(e, debug, 0)) && rem > 0; )
+                               {
+                                       if (autocvar_debugdraw < 2 && is_pure(e)) continue;
+                                       debug_send(e, nextent(NULL), 0);
+                                       e.debug = true;
+                                       --rem;
+                               }
+                               LOG_INFOF("%d server entities sent\n", n - rem);
+                               return;
+                       }
+
+                       default:
+                       case CMD_REQUEST_USAGE:
+                       {
+                               LOG_INFO(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " debugdraw_sv"));
+                               return;
+                       }
+               }
+       }
+#endif
+
+#endif
index e90f3c6..7172a20 100644 (file)
@@ -1,15 +1,16 @@
 #include "all.qh"
 
+REGISTER_NET_TEMP(net_effect, bool isNew)
 #ifdef CSQC
-void Read_Effect(bool is_new)
 {
        int net_name = (Effects_COUNT >= 255) ? ReadShort() : ReadByte();
 
        entity eff = Effects[net_name];
 
-       vector v, vel = '0 0 0';
+       vector vel = '0 0 0';
        int eff_cnt = 1;
        bool eff_trail = eff.eent_eff_trail;
+       vector v;
        v_x = ReadCoord();
        v_y = ReadCoord();
        v_z = ReadCoord();
@@ -25,38 +26,37 @@ void Read_Effect(bool is_new)
        if(!eff_trail)
                eff_cnt = ReadByte();
 
-       if(is_new)
-       {
-               if(eff_trail)
-                       WarpZone_TrailParticles(world, particleeffectnum(eff), v, vel);
-               else
-                       pointparticles(particleeffectnum(eff), v, vel, eff_cnt);
-       }
+       if(eff_trail)
+               WarpZone_TrailParticles(world, particleeffectnum(eff), v, vel);
+       else
+               pointparticles(particleeffectnum(eff), v, vel, eff_cnt);
 }
 #endif
 
 #ifdef SVQC
 bool Net_Write_Effect(entity this, entity client, int sf)
 {
-       WriteByte(MSG_ENTITY, ENT_CLIENT_EFFECT);
+       int channel = MSG_ONE;
+       msg_entity = client;
+       WriteHeader(channel, net_effect);
        (Effects_COUNT >= 255)
-       ? WriteShort(MSG_ENTITY, self.m_id)
-       : WriteByte(MSG_ENTITY, self.m_id);
-       WriteCoord(MSG_ENTITY, self.eent_net_location_x);
-       WriteCoord(MSG_ENTITY, self.eent_net_location_y);
-       WriteCoord(MSG_ENTITY, self.eent_net_location_z);
+       ? WriteShort(channel, this.m_id)
+       : WriteByte(channel, this.m_id);
+       WriteCoord(channel, this.eent_net_location_x);
+       WriteCoord(channel, this.eent_net_location_y);
+       WriteCoord(channel, this.eent_net_location_z);
 
        // attempt to save a tiny bit more bandwidth by not sending velocity if it isn't set
-       if(self.eent_net_velocity)
+       if(this.eent_net_velocity)
        {
-               WriteByte(MSG_ENTITY, true);
-               WriteCoord(MSG_ENTITY, self.eent_net_velocity_x);
-               WriteCoord(MSG_ENTITY, self.eent_net_velocity_y);
-               WriteCoord(MSG_ENTITY, self.eent_net_velocity_z);
+               WriteByte(channel, true);
+               WriteCoord(channel, this.eent_net_velocity_x);
+               WriteCoord(channel, this.eent_net_velocity_y);
+               WriteCoord(channel, this.eent_net_velocity_z);
        }
-       else { WriteByte(MSG_ENTITY, false); }
+       else { WriteByte(channel, false); }
 
-       if(!self.eent_eff_trail) { WriteByte(MSG_ENTITY, self.eent_net_count); }
+       if(!this.eent_eff_trail) { WriteByte(channel, this.eent_net_count); }
        return true;
 }
 
@@ -64,9 +64,9 @@ void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
 {
        if(!eff) { return; }
        if(!eff.eent_eff_trail && !eff_cnt) { return; } // effect has no count!
-       entity net_eff = spawn();
+       entity net_eff = new(net_effect);
+       make_pure(net_eff);
        net_eff.owner = eff;
-       net_eff.classname = "net_effect";
        //net_eff.eent_broadcast = broadcast;
        net_eff.m_id = eff.m_id;
        net_eff.eent_net_velocity = eff_vel;
@@ -74,10 +74,8 @@ void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
        net_eff.eent_net_count = eff_cnt;
        net_eff.eent_eff_trail = eff.eent_eff_trail;
 
-       net_eff.think = SUB_Remove;
-       net_eff.nextthink = time + 0.2; // don't need to keep this long
-
-       Net_LinkEntity(net_eff, false, 0, Net_Write_Effect);
+       entity e; FOR_EACH_REALCLIENT(e) Net_Write_Effect(net_eff, e, 0);
+       remove(net_eff);
 }
 
 void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt)
index 7046af1..83be0aa 100644 (file)
@@ -3,9 +3,7 @@
 
 #include "effect.qh"
 
-#ifdef CSQC
-void Read_Effect(bool is_new);
-#elif defined(SVQC)
+#ifdef SVQC
 void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt);
 void Send_Effect_(string eff_name, vector eff_loc, vector eff_vel, int eff_cnt);
 #endif
index bd9cd99..bc8f848 100644 (file)
@@ -14,6 +14,7 @@
 entity Create_Effect_Entity(string eff_name, bool eff_trail)
 {
        entity this = new(effect_entity);
+       make_pure(this);
        this.eent_eff_name = eff_name;
        this.eent_eff_trail = eff_trail;
        return this;
index 72873b3..dc158a6 100644 (file)
@@ -451,9 +451,7 @@ spawnfunc(nexball_team)
 void nb_spawnteam(string teamname, float teamcolor)
 {
        LOG_TRACE("^2spawned team ", teamname, "\n");
-       entity e;
-       e = spawn();
-       e.classname = "nexball_team";
+       entity e = new(nexball_team);
        e.netname = teamname;
        e.cnt = teamcolor;
        e.team = e.cnt + 1;
@@ -804,10 +802,9 @@ void W_Nexball_Attack2(void)
                return;
 
        W_SetupShot(self, false, 2, SND(NB_SHOOT2), CH_WEAPON_A, 0);
-       entity missile = spawn();
+       entity missile = new(ballstealer);
 
        missile.owner = self;
-       missile.classname = "ballstealer";
 
        missile.movetype = MOVETYPE_FLY;
        PROJECTILE_MAKETRIGGER(missile);
index a6d266a..232a4fc 100644 (file)
@@ -14,6 +14,7 @@ class(Inventory) .int inv_items[Items_MAX];
 #ifdef CSQC
 void Inventory_Read(Inventory data)
 {
+    make_pure(self);
     const int bits = ReadInt24_t();
     FOREACH(Items, bits & BIT(it.m_id), LAMBDA(
         .int fld = inv_items[it.m_id];
@@ -53,7 +54,7 @@ bool Inventory_Send(entity this, entity to, int sf)
 void Inventory_new(entity e)
 {
     Inventory inv = new(Inventory), bak = new(Inventory);
-    inv.classname = "inventory", bak.classname = "inventory";
+    make_pure(inv); make_pure(bak);
     inv.inventory = bak;
     inv.drawonlytoclient = e;
     Net_LinkEntity((inv.owner = e).inventory = inv, false, 0, Inventory_Send);
index 016e8a3..223e2c0 100644 (file)
@@ -117,12 +117,12 @@ void HUD_MinigameMenu_CustomEntry(entity parent, string message, string event_ar
 REGISTRY(Minigames, BIT(3))
 REGISTER_REGISTRY(RegisterMinigames)
 #define REGISTER_MINIGAME(name,nicename) \
-    REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, spawn()); \
+    REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
     void name##_hud_board(vector, vector); \
     void name##_hud_status(vector, vector); \
     int name##_client_event(entity, string, ...); \
     REGISTER_INIT_POST(MINIGAME, name) { \
-        this.classname = "minigame_descriptor"; \
+        make_pure(this); \
         this.netname = strzone(strtolower(#name)); \
         this.message = nicename; \
         this.minigame_hud_board = name##_hud_board; \
index 1e4da05..93c88f6 100644 (file)
@@ -79,9 +79,8 @@ string nmm_tile_build_vmill(entity tile)
 void nmm_spawn_tile(string id, entity minig, int distance)
 {
        // TODO global variable + list_next for simpler tile loops
-       entity e = spawn();
+       entity e = new(minigame_nmm_tile);
        e.origin = minigame_tile_pos(id,7,7);
-       e.classname = "minigame_nmm_tile";
        e.netname = id;
        e.owner = minig;
        e.team = 0;
index 8c5005e..c3c7637 100644 (file)
@@ -642,8 +642,7 @@ int ttt_client_event(entity minigame, string event, ...)
 
                                        if ( spawnai )
                                        {
-                                               entity aiplayer = spawn();
-                                               aiplayer.classname = "minigame_player";
+                                               entity aiplayer = new(minigame_player);
                                                aiplayer.owner = minigame;
                                                aiplayer.team = ai;
                                                aiplayer.minigame_playerslot = 0;
index 56d0ece..403a79d 100644 (file)
@@ -131,12 +131,11 @@ int minigame_addplayer(entity minigame_session, entity player)
                        return 0;
                minigame_rmplayer(player.active_minigame,player);
        }
-       entity player_pointer = spawn();
+       entity player_pointer = new(minigame_player);
        int mgteam = minigame_session.minigame_event(minigame_session,"join",player,player_pointer);
 
        if ( mgteam )
        {
-               player_pointer.classname = "minigame_player";
                player_pointer.owner = minigame_session;
                player_pointer.minigame_players = player;
                player_pointer.team = mgteam;
@@ -171,8 +170,7 @@ entity start_minigame(entity player, string minigame )
        entity e = minigame_get_descriptor(minigame);
        if ( e )
        {
-               entity minig = spawn();
-               minig.classname = "minigame";
+               entity minig = new(minigame);
                minig.netname = strzone(strcat(e.netname,"_",ftos(num_for_edict(minig))));
                minig.descriptor = e;
                minig.minigame_event = e.minigame_event;
index e36d690..b3a6ce2 100644 (file)
@@ -49,10 +49,10 @@ bool minigame_SendEntity(entity this, entity to, int sf);
 REGISTRY(Minigames, BIT(3))
 REGISTER_REGISTRY(RegisterMinigames)
 #define REGISTER_MINIGAME(name,nicename) \
-    REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, spawn()); \
+    REGISTER(RegisterMinigames, MINIGAME, Minigames, name, m_id, new(minigame_descriptor)); \
     int name##_server_event(entity, string, ...); \
     REGISTER_INIT_POST(MINIGAME, name) { \
-        this.classname = "minigame_descriptor"; \
+        make_pure(this); \
         this.netname = strzone(strtolower(#name)); \
         this.message = nicename; \
                this.minigame_event = name##_server_event; \
index 1a1fb45..58ae391 100644 (file)
@@ -149,9 +149,8 @@ void M_Shambler_Attack_Lightning()
 
        monster_makevectors(self.enemy);
 
-       gren = spawn ();
+       gren = new(grenade);
        gren.owner = gren.realowner = self;
-       gren.classname = "grenade";
        gren.bot_dodge = true;
        gren.bot_dodgerating = (autocvar_g_monster_shambler_attack_lightning_damage);
        gren.movetype = MOVETYPE_BOUNCE;
index 8f42ca7..953ede7 100644 (file)
@@ -121,8 +121,7 @@ void M_Spider_Attack_Web()
 
        sound(self, CH_SHOTS, SND_ELECTRO_FIRE2, VOL_BASE, ATTEN_NORM);
 
-       entity proj = spawn ();
-       proj.classname = "plasma";
+       entity proj = new(plasma);
        proj.owner = proj.realowner = self;
        proj.use = M_Spider_Attack_Web_Explode;
        proj.think = adaptor_think2use_hittype_splash;
index f8294e3..7dbc9e3 100644 (file)
@@ -36,7 +36,7 @@ void monster_dropitem()
                return;
 
        vector org = self.origin + ((self.mins + self.maxs) * 0.5);
-       entity e = spawn();
+       entity e = new(droppedweapon); // use weapon handling to remove it on touch
        e.spawnfunc_checked = true;
 
        e.monster_loot = self.monster_loot;
@@ -55,7 +55,6 @@ void monster_dropitem()
                setorigin(e, org);
                e.velocity = randomvec() * 175 + '0 0 325';
                e.item_spawnshieldtime = time + 0.7;
-               e.classname = "droppedweapon"; // use weapon handling to remove it on touch
                SUB_SetFade(e, time + autocvar_g_monsters_drop_time, 1);
                setself(this);
        }
index f7fd038..6bc6729 100644 (file)
@@ -28,7 +28,7 @@ ENDCLASS(Waypoint)
 REGISTRY(RadarIcons, BITS(7))
 REGISTER_REGISTRY(RegisterRadarIcons)
 .int m_radaricon;
-#define REGISTER_RADARICON(id, num) REGISTER(RegisterRadarIcons, RADARICON, RadarIcons, id, m_id, new(RadarIcon)) { this.m_radaricon = num; this.netname = #id; }
+#define REGISTER_RADARICON(id, num) REGISTER(RegisterRadarIcons, RADARICON, RadarIcons, id, m_id, new(RadarIcon)) { make_pure(this); this.m_radaricon = num; this.netname = #id; }
 
 REGISTER_WAYPOINT(Null, "", '0 0 0', 1);
 
index f0b768c..1f4697d 100644 (file)
@@ -993,6 +993,7 @@ entity WaypointSprite_Spawn(
 )
 {
     entity wp = new(sprite_waypoint);
+    make_pure(wp);
     wp.teleport_time = time + _lifetime;
     wp.fade_time = _lifetime;
     wp.exteriormodeltoclient = ref;
index 30ad178..d56f280 100644 (file)
@@ -52,7 +52,7 @@ void healer_setup(entity e)
 REGISTER_NET_LINKED(Nade_Heal, bool isNew)
 #ifdef CSQC
 {
-       Net_Accept();
+       Net_Accept(Nade_Heal);
        int sf = ReadByte();
        if (sf & 1) {
                this.origin_x = ReadCoord();
index f748f99..317eec1 100644 (file)
@@ -49,11 +49,9 @@ void sv_notice_toall(string _notice, float _howlong, float _modal)
 #ifdef CSQC
 void cl_notice_read()
 {
-    entity _notice;
     //float _done;
     //float _modal;
-    _notice = spawn();
-    _notice.classname = "sv_notice";
+    entity _notice = new(sv_notice);
     _notice.netname = strzone(ReadString());
     _notice.alpha = ReadLong() + time;
     _notice.skin = ReadByte();
index 5a55c55..c46988d 100644 (file)
@@ -524,6 +524,7 @@ void Create_Notification_Entity(
        //  Global Entity Setup
        // =====================
        entity notif = spawn();
+       make_pure(notif);
        switch(typeId)
        {
                case MSG_ANNCE:
@@ -1842,8 +1843,8 @@ void Kill_Notification(
 
        if(killed_cpid != NO_CPID)
        {
-               net_notif = spawn();
-               net_notif.classname = "net_kill_notification";
+               net_notif = new(net_kill_notification);
+               make_pure(net_notif);
                net_notif.nent_broadcast = broadcast;
                net_notif.nent_client = client;
                net_notif.nent_net_type = MSG_CENTER_CPID;
@@ -2093,9 +2094,9 @@ void Send_Notification(
        }
        else
        {
-               entity net_notif = spawn();
+               entity net_notif = new(net_notification);
+               make_pure(net_notif);
                net_notif.owner = notif;
-               net_notif.classname = "net_notification";
                net_notif.nent_broadcast = broadcast;
                net_notif.nent_client = client;
                net_notif.nent_net_type = net_type;
index 8c7000d..909f5cd 100644 (file)
@@ -69,8 +69,7 @@ spawnfunc(func_bobbing)
                return;
 
        // wait for targets to spawn
-       controller = spawn();
-       controller.classname = "func_bobbing_controller";
+       controller = new(func_bobbing_controller);
        controller.owner = self;
        controller.nextthink = time + 1;
        controller.think = func_bobbing_controller_think;
index 74b0e54..e2d1228 100644 (file)
@@ -458,8 +458,7 @@ void door_spawnfield(vector fmins, vector fmaxs)
        entity  trigger;
        vector  t1 = fmins, t2 = fmaxs;
 
-       trigger = spawn();
-       trigger.classname = "doortriggerfield";
+       trigger = new(doortriggerfield);
        trigger.movetype = MOVETYPE_NONE;
        trigger.solid = SOLID_TRIGGER;
        trigger.owner = self;
index 2b3d07f..31e3835 100644 (file)
@@ -73,8 +73,7 @@ spawnfunc(func_fourier)
        self.active = ACTIVE_ACTIVE;
 
        // wait for targets to spawn
-       controller = spawn();
-       controller.classname = "func_fourier_controller";
+       controller = new(func_fourier_controller);
        controller.owner = self;
        controller.nextthink = time + 1;
        controller.think = func_fourier_controller_think;
index d8bab86..2d8aea3 100644 (file)
@@ -62,8 +62,7 @@ spawnfunc(func_pendulum)
        self.cnt = self.angles_z;
 
        // wait for targets to spawn
-       controller = spawn();
-       controller.classname = "func_pendulum_controller";
+       controller = new(func_pendulum_controller);
        controller.owner = self;
        controller.nextthink = time + 1;
        controller.think = func_pendulum_controller_think;
index 57d3a06..5c20864 100644 (file)
@@ -91,8 +91,7 @@ void func_vectormamamam_findtarget()
        self.destvec = self.origin - func_vectormamamam_origin(self, 0);
 
        entity controller;
-       controller = spawn();
-       controller.classname = "func_vectormamamam_controller";
+       controller = new(func_vectormamamam_controller);
        controller.owner = self;
        controller.nextthink = time + 1;
        controller.think = func_vectormamamam_controller_think;
index d9de973..850158a 100644 (file)
@@ -222,8 +222,7 @@ void SUB_CalcMove_Bezier (vector tcontrol, vector tdest, float tspeedtype, float
                return;
        }
 
-       controller = spawn();
-       controller.classname = "SUB_CalcMove_controller";
+       controller = new(SUB_CalcMove_controller);
        controller.owner = self;
        controller.platmovetype = self.platmovetype;
        controller.platmovetype_start = self.platmovetype_start;
index 8640fdf..6765903 100644 (file)
@@ -407,7 +407,7 @@ void target_push_link()
 
 spawnfunc(target_push) { target_push_link(); }
 spawnfunc(info_notnull) { target_push_link(); }
-spawnfunc(target_position) { target_push_link(); }
+spawnfunc(target_position) { make_pure(this); target_push_link(); }
 
 #endif
 
index b97d2b1..41180dd 100644 (file)
@@ -148,8 +148,7 @@ void SUB_UseTargets()
        if (self.delay)
        {
        // create a temp object to fire at a later time
-               t = spawn();
-               t.classname = "DelayedUse";
+               t = new(DelayedUse);
                t.nextthink = time + self.delay;
                t.think = DelayThink;
                t.enemy = activator;
index 582113c..6b0dbee 100644 (file)
@@ -287,7 +287,7 @@ entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, flo
        if(trace_startsolid)
                return world;
 
-       gib = spawn();
+       gib = new(turret_gib);
        setorigin(gib, _from);
        _setmodel(gib, _model);
        gib.colormod    = _cmod;
@@ -311,7 +311,6 @@ entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, flo
        gib.move_avelocity  = prandomvec() * 32;
        gib.move_time      = time;
        gib.damageforcescale = 1;
-       gib.classname = "turret_gib";
 
        return gib;
 }
index 49bd505..33e41cd 100644 (file)
@@ -1267,8 +1267,7 @@ float turret_initialize(Turret tur)
        entity e = find(world, classname, "turret_manager");
        if(!e)
        {
-               e = spawn();
-               e.classname = "turret_manager";
+               e = new(turret_manager);
                e.think = turrets_manager_think;
                e.nextthink = time + 2;
        }
@@ -1353,13 +1352,13 @@ float turret_initialize(Turret tur)
        self.nextthink                          = time + 1;
        self.nextthink                     += turret_count * sys_frametime;
 
-       self.tur_head = spawn();
+       self.tur_head = new(turret_head);
        _setmodel(self.tur_head, tur.head_model);
        setsize(self.tur_head, '0 0 0', '0 0 0');
        setorigin(self.tur_head, '0 0 0');
        setattachment(self.tur_head, self, "tag_head");
 
-       self.tur_head.netname           = self.tur_head.classname = "turret_head";
+       self.tur_head.netname           = self.tur_head.classname;
        self.tur_head.team                      = self.team;
        self.tur_head.owner                     = self;
        self.tur_head.takedamage        = DAMAGE_NO;
index 43ac006..eac40d2 100644 (file)
@@ -233,13 +233,12 @@ void walker_fire_rocket(vector org)
 
     te_explosion (org);
 
-    rocket = spawn ();
+    rocket = new(walker_rocket);
     setorigin(rocket, org);
 
     sound (self, CH_WEAPON_A, SND_HAGAR_FIRE, VOL_BASE, ATTEN_NORM);
     setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
 
-    rocket.classname             = "walker_rocket";
     rocket.owner                         = self;
     rocket.bot_dodge             = true;
     rocket.bot_dodgerating     = 50;
index 53c5fb7..b0667c8 100644 (file)
@@ -224,10 +224,7 @@ void marker_think()
 
 void mark_error(vector where,float lifetime)
 {
-       entity err;
-
-       err = spawn();
-       err.classname = "error_marker";
+       entity err = new(error_marker);
        setmodel(err, MDL_MARKER);
        setorigin(err,where);
        err.movetype = MOVETYPE_NONE;
@@ -240,10 +237,7 @@ void mark_error(vector where,float lifetime)
 
 void mark_info(vector where,float lifetime)
 {
-       entity err;
-
-       err = spawn();
-       err.classname = "info_marker";
+       entity err = spawn(info_marker);
        setmodel(err, MDL_MARKER);
        setorigin(err,where);
        err.movetype = MOVETYPE_NONE;
@@ -256,10 +250,7 @@ void mark_info(vector where,float lifetime)
 
 entity mark_misc(vector where,float lifetime)
 {
-       entity err;
-
-       err = spawn();
-       err.classname = "mark_misc";
+       entity err = spawn(mark_misc);
        setmodel(err, MDL_MARKER);
        setorigin(err,where);
        err.movetype = MOVETYPE_NONE;
index 7ac910f..a6a57c7 100644 (file)
@@ -803,8 +803,8 @@ float cvar_settemp(string tmp_cvar, string tmp_value)
        if(created_saved_value != -1)
        {
                // creating a new entity to keep track of this cvar
-               e = spawn();
-               e.classname = "saved_cvar_value";
+               e = new(saved_cvar_value);
+               make_pure(e);
                e.netname = strzone(tmp_cvar);
                e.message = strzone(cvar_string(tmp_cvar));
                created_saved_value = 1;
index a00cdcf..e1a5f1f 100644 (file)
@@ -455,10 +455,8 @@ void vehicles_reset_colors()
 
 void vehicles_clearreturn(entity veh)
 {
-       entity ret;
        // Remove "return helper", if any.
-       ret = findchain(classname, "vehicle_return");
-       while(ret)
+       for (entity ret = findchain(classname, "vehicle_return"); ret; ret = ret.chain)
        {
                if(ret.wp00 == veh)
                {
@@ -471,7 +469,6 @@ void vehicles_clearreturn(entity veh)
 
                        return;
                }
-               ret = ret.chain;
        }
 }
 
@@ -548,8 +545,7 @@ void vehicles_setreturn(entity veh)
 
        vehicles_clearreturn(veh);
 
-       ret = spawn();
-       ret.classname   = "vehicle_return";
+       ret = new(vehicle_return);
        ret.wp00           = veh;
        ret.team                = veh.team;
        ret.think          = vehicles_showwp;
@@ -1234,9 +1230,9 @@ bool vehicle_initialize(entity veh, bool nodrop)
 
        self.vehicle_flags |= VHF_ISVEHICLE;
 
-       self.vehicle_viewport           = spawn();
-       self.vehicle_hudmodel           = spawn();
-       self.tur_head                           = spawn();
+       self.vehicle_viewport           = new(vehicle_viewport);
+       self.vehicle_hudmodel           = new(vehicle_hudmodel);
+       self.tur_head                           = new(tur_head);
        self.tur_head.owner                     = self;
        self.takedamage                         = DAMAGE_NO;
        self.bot_attack                         = true;
index 6e9099a..244b4e2 100644 (file)
@@ -859,9 +859,9 @@ spawnfunc(vehicle_bumblebee)
                                self.vehicle_shieldent.alpha = -1;
                                self.vehicle_shieldent.effects = EF_LOWPRECISION | EF_NODRAW;
 
-                               self.gun1 = spawn();
-                               self.gun2 = spawn();
-                               self.gun3 = spawn();
+                               self.gun1 = new(vehicle_playerslot);
+                               self.gun2 = new(vehicle_playerslot);
+                               self.gun3 = new(bumblebee_raygun);
 
                                self.vehicle_flags |= VHF_MULTISLOT;
 
@@ -869,8 +869,6 @@ spawnfunc(vehicle_bumblebee)
                                self.gun2.owner = self;
                                self.gun3.owner = self;
 
-                               self.gun1.classname = self.gun2.classname = "vehicle_playerslot";
-
                                setmodel(self.gun1, MDL_VEH_BUMBLEBEE_CANNON_RIGHT);
                                setmodel(self.gun2, MDL_VEH_BUMBLEBEE_CANNON_LEFT);
                                setmodel(self.gun3, MDL_VEH_BUMBLEBEE_CANNON_CENTER);
index 7d90dd4..c81f5d9 100644 (file)
@@ -671,10 +671,10 @@ spawnfunc(vehicle_raptor)
 
                                self.frame = 0;
 
-                               self.bomb1 = spawn();
-                               self.bomb2 = spawn();
-                               self.gun1  = spawn();
-                               self.gun2  = spawn();
+                               self.bomb1 = new(raptor_bomb);
+                               self.bomb2 = new(raptor_bomb);
+                               self.gun1  = new(raptor_gun);
+                               self.gun2  = new(raptor_gun);
 
                                setmodel(self.bomb1, MDL_VEH_RAPTOR_CB_FOLDED);
                                setmodel(self.bomb2, MDL_VEH_RAPTOR_CB_FOLDED);
@@ -705,7 +705,7 @@ spawnfunc(vehicle_raptor)
                                self.angles = self.bomb1.angles;
                                self.bomb1.angles = '0 0 0';
 
-                               spinner = spawn();
+                               spinner = new(raptor_spinner);
                                spinner.owner = self;
                                setmodel(spinner, MDL_VEH_RAPTOR_PROP);
                                setattachment(spinner, self, "engine_left");
@@ -713,7 +713,7 @@ spawnfunc(vehicle_raptor)
                                spinner.avelocity = '0 90 0';
                                self.bomb1.gun1 = spinner;
 
-                               spinner = spawn();
+                               spinner = new(raptor_spinner);
                                spinner.owner = self;
                                setmodel(spinner, MDL_VEH_RAPTOR_PROP);
                                setattachment(spinner, self, "engine_right");
index 965827f..c2440e6 100644 (file)
@@ -584,8 +584,7 @@ void W_Arc_Beam(float burst)
        if(time - self.beam_prev > 1)
                sound(self, CH_WEAPON_A, SND_ARC_FIRE, VOL_BASE, ATTN_NORM);
 
-       entity beam = self.arc_beam = spawn();
-       beam.classname = "W_Arc_Beam";
+       entity beam = self.arc_beam = new(W_Arc_Beam);
        beam.solid = SOLID_NOT;
        beam.think = W_Arc_Beam_Think;
        beam.owner = self;
index 2aa8bbd..3503a91 100644 (file)
@@ -101,9 +101,8 @@ void W_Blaster_Attack(
        W_SetupShot_Dir(actor, s_forward, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_B, atk_damage);
        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       entity missile = spawn();
+       entity missile = new(blasterbolt);
        missile.owner = missile.realowner = actor;
-       missile.classname = "blasterbolt";
        missile.bot_dodge = true;
        missile.bot_dodgerating = atk_damage;
        PROJECTILE_MAKETRIGGER(missile);
index 083d7e0..c8c1389 100644 (file)
@@ -366,10 +366,9 @@ void W_Crylink_Attack(Weapon thiswep)
        proj = prevproj = firstproj = world;
        for(counter = 0; counter < shots; ++counter)
        {
-               proj = spawn();
+               proj = new(spike);
                proj.reset = W_Crylink_Reset;
                proj.realowner = proj.owner = self;
-               proj.classname = "spike";
                proj.bot_dodge = true;
                proj.bot_dodgerating = WEP_CVAR_PRI(crylink, damage);
                if(shots == 1) {
@@ -475,10 +474,9 @@ void W_Crylink_Attack2(Weapon thiswep)
        proj = prevproj = firstproj = world;
        for(counter = 0; counter < shots; ++counter)
        {
-               proj = spawn();
+               proj = new(spike);
                proj.reset = W_Crylink_Reset;
                proj.realowner = proj.owner = self;
-               proj.classname = "spike";
                proj.bot_dodge = true;
                proj.bot_dodgerating = WEP_CVAR_SEC(crylink, damage);
                if(shots == 1) {
@@ -614,9 +612,8 @@ void W_Crylink_Attack2(Weapon thiswep)
 
                                                pos = W_Crylink_LinkJoin(actor.crylink_lastgroup, WEP_CVAR_BOTH(crylink, isprimary, joinspread) * WEP_CVAR_BOTH(crylink, isprimary, speed));
 
-                                               linkjoineffect = spawn();
+                                               linkjoineffect = new(linkjoineffect);
                                                linkjoineffect.think = W_Crylink_LinkJoinEffect_Think;
-                                               linkjoineffect.classname = "linkjoineffect";
                                                linkjoineffect.nextthink = time + w_crylink_linkjoin_time;
                                                linkjoineffect.owner = actor;
                                                setorigin(linkjoineffect, pos);
index 63acee3..b0df034 100644 (file)
@@ -264,8 +264,7 @@ void W_Electro_Attack_Bolt(Weapon thiswep)
 
        Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       proj = spawn();
-       proj.classname = "electro_bolt";
+       proj = new(electro_bolt);
        proj.owner = proj.realowner = self;
        proj.bot_dodge = true;
        proj.bot_dodgerating = WEP_CVAR_PRI(electro, damage);
@@ -364,8 +363,7 @@ void W_Electro_Attack_Orb(Weapon thiswep)
 
        Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       entity proj = spawn();
-       proj.classname = "electro_orb";
+       entity proj = new(electro_orb);
        proj.owner = proj.realowner = self;
        proj.use = W_Electro_Explode;
        proj.think = adaptor_think2use_hittype_splash;
index 477aef8..43f4142 100644 (file)
@@ -188,8 +188,7 @@ void W_Fireball_Attack1(void)
 
        Send_Effect(EFFECT_FIREBALL_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       proj = spawn();
-       proj.classname = "plasma_prim";
+       proj = new(plasma_prim);
        proj.owner = proj.realowner = self;
        proj.bot_dodge = true;
        proj.bot_dodgerating = WEP_CVAR_PRI(fireball, damage);
@@ -324,9 +323,8 @@ void W_Fireball_Attack2(void)
 
        Send_Effect(EFFECT_FIREBALL_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       proj = spawn();
+       proj = new(grenade);
        proj.owner = proj.realowner = self;
-       proj.classname = "grenade";
        proj.bot_dodge = true;
        proj.bot_dodgerating = WEP_CVAR_SEC(fireball, damage);
        proj.movetype = MOVETYPE_BOUNCE;
index c9d1c52..203f566 100644 (file)
@@ -133,9 +133,8 @@ void W_Hagar_Attack(Weapon thiswep)
 
        Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       missile = spawn();
+       missile = new(missile);
        missile.owner = missile.realowner = self;
-       missile.classname = "missile";
        missile.bot_dodge = true;
        missile.bot_dodgerating = WEP_CVAR_PRI(hagar, damage);
 
@@ -176,9 +175,8 @@ void W_Hagar_Attack2(Weapon thiswep)
 
        Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       missile = spawn();
+       missile = new(missile);
        missile.owner = missile.realowner = self;
-       missile.classname = "missile";
        missile.bot_dodge = true;
        missile.bot_dodgerating = WEP_CVAR_SEC(hagar, damage);
 
@@ -236,9 +234,8 @@ void W_Hagar_Attack2_Load_Release(int slot)
        missile = world;
        for(counter = 0; counter < shots; ++counter)
        {
-               missile = spawn();
+               missile = new(missile);
                missile.owner = missile.realowner = self;
-               missile.classname = "missile";
                missile.bot_dodge = true;
                missile.bot_dodgerating = WEP_CVAR_SEC(hagar, damage);
 
index 639847a..e1ec82b 100644 (file)
@@ -87,9 +87,8 @@ void W_HLAC_Attack(Weapon thiswep)
                self.punchangle_y = random() - 0.5;
        }
 
-       missile = spawn();
+       missile = new(hlacbolt);
        missile.owner = missile.realowner = self;
-       missile.classname = "hlacbolt";
        missile.bot_dodge = true;
 
     missile.bot_dodgerating = WEP_CVAR_PRI(hlac, damage);
@@ -130,9 +129,8 @@ void W_HLAC_Attack2(void)
        W_SetupShot(self, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage));
        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       missile = spawn();
+       missile = new(hlacbolt);
        missile.owner = missile.realowner = self;
-       missile.classname = "hlacbolt";
        missile.bot_dodge = true;
 
     missile.bot_dodgerating = WEP_CVAR_SEC(hlac, damage);
index fa12ace..b5a811b 100644 (file)
@@ -67,8 +67,7 @@ void W_MineLayer_Stick(entity to)
 
        // in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
 
-       entity newmine;
-       newmine = spawn();
+       entity newmine = spawn();
        newmine.classname = self.classname;
 
        newmine.bot_dodge = self.bot_dodge;
index e1a2959..2a29f6b 100644 (file)
@@ -209,9 +209,8 @@ void W_Mortar_Attack(Weapon thiswep)
 
        Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       gren = spawn();
+       gren = new(grenade);
        gren.owner = gren.realowner = self;
-       gren.classname = "grenade";
        gren.bot_dodge = true;
        gren.bot_dodgerating = WEP_CVAR_PRI(mortar, damage);
        gren.movetype = MOVETYPE_BOUNCE;
@@ -258,9 +257,8 @@ void W_Mortar_Attack2(Weapon thiswep)
 
        Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       gren = spawn();
+       gren = new(grenade);
        gren.owner = gren.realowner = self;
-       gren.classname = "grenade";
        gren.bot_dodge = true;
        gren.bot_dodgerating = WEP_CVAR_SEC(mortar, damage);
        gren.movetype = MOVETYPE_BOUNCE;
index 89019c4..35689da 100644 (file)
@@ -251,11 +251,10 @@ void W_Porto_Attack(float type)
 
        //Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       gren = spawn();
+       gren = new(porto);
        gren.cnt = type;
        gren.owner = gren.realowner = self;
        gren.playerid = self.playerid;
-       gren.classname = "porto";
        gren.bot_dodge = true;
        gren.bot_dodgerating = 200;
        gren.movetype = MOVETYPE_BOUNCEMISSILE;
index 9bac673..cb55f46 100644 (file)
@@ -258,9 +258,8 @@ void W_Seeker_Fire_Missile(Weapon thiswep, vector f_diff, entity m_target)
 
        //self.detornator         = false;
 
-       missile                 = spawn();
+       missile                 = new(seeker_missile);
        missile.owner           = missile.realowner = self;
-       missile.classname       = "seeker_missile";
        missile.bot_dodge       = true;
        missile.bot_dodgerating = WEP_CVAR(seeker, missile_damage);
 
@@ -348,9 +347,8 @@ void W_Seeker_Fire_Flac(Weapon thiswep)
 
        Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
 
-       missile                                 = spawn();
+       missile                                 = new(missile);
        missile.owner                   = missile.realowner = self;
-       missile.classname               = "missile";
        missile.bot_dodge               = true;
        missile.bot_dodgerating = WEP_CVAR(seeker, flac_damage);
        missile.touch                   = W_Seeker_Flac_Explode;
@@ -524,9 +522,8 @@ void W_Seeker_Tag_Touch(void)
                else
                {
                        //sprint(self.realowner, strcat("You just tagged ^2", other.netname, "^7 with a tracking device!\n"));
-                       e             = spawn();
+                       e             = new(tag_tracker);
                        e.cnt         = WEP_CVAR(seeker, missile_count);
-                       e.classname   = "tag_tracker";
                        e.owner       = self.owner;
                        e.realowner   = self.realowner;
 
@@ -563,9 +560,8 @@ void W_Seeker_Fire_Tag(Weapon thiswep)
 
        W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(TAG_FIRE), CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count));
 
-       missile                 = spawn();
+       missile                 = new(seeker_tag);
        missile.owner           = missile.realowner = self;
-       missile.classname       = "seeker_tag";
        missile.bot_dodge       = true;
        missile.bot_dodgerating = 50;
        missile.touch           = W_Seeker_Tag_Touch;
index 9706156..df2c25d 100644 (file)
@@ -234,8 +234,8 @@ void W_Shockwave_Melee(Weapon thiswep, entity actor, int slot, int fire)
        sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTN_NORM);
        weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR(shockwave, melee_animtime), w_ready);
 
-       entity meleetemp;
-       meleetemp = spawn();
+       entity meleetemp = new(meleetemp);
+       make_pure(meleetemp);
        meleetemp.owner = meleetemp.realowner = actor;
        meleetemp.think = W_Shockwave_Melee_Think;
        meleetemp.nextthink = time + WEP_CVAR(shockwave, melee_delay) * W_WeaponRateFactor();
index e3f85da..b3eef16 100644 (file)
@@ -186,8 +186,8 @@ void W_Shotgun_Attack2(Weapon thiswep, entity actor, int slot, int fire)
        sound(actor, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTEN_NORM);
        weapon_thinkf(actor, slot, WFRAME_FIRE2, WEP_CVAR_SEC(shotgun, animtime), w_ready);
 
-       entity meleetemp;
-       meleetemp = spawn();
+       entity meleetemp = new(meleetemp);
+       make_pure(meleetemp);
        meleetemp.realowner = actor;
        meleetemp.think = W_Shotgun_Melee_Think;
        meleetemp.nextthink = time + WEP_CVAR_SEC(shotgun, melee_delay) * W_WeaponRateFactor();
index d420850..46dc5ee 100644 (file)
@@ -150,8 +150,7 @@ void W_RocketMinsta_Attack2(void)
 
     while(counter < total)
        {
-        proj = spawn ();
-        proj.classname = "plasma_prim";
+        proj = new(plasma_prim);
         proj.owner = proj.realowner = self;
         proj.bot_dodge = true;
         proj.bot_dodgerating = autocvar_g_rm_laser_damage;
@@ -203,8 +202,7 @@ void W_RocketMinsta_Attack3 (void)
 
     while(counter < total)
        {
-        proj = spawn ();
-        proj.classname = "plasma_prim";
+        proj = new(plasma_prim);
         proj.owner = proj.realowner = self;
         proj.bot_dodge = true;
         proj.bot_dodgerating = autocvar_g_rm_laser_damage;
index eb56dce..749e4a6 100644 (file)
@@ -38,10 +38,10 @@ Remove self
        void defer(float fdelay, void() func)
        {
                SELFPARAM();
-               entity e;
 
-               e           = spawn();
-               e.owner     = self;
+               entity e    = new(deferred);
+               make_pure(e);
+               e.owner     = this;
                e.use       = func;
                e.think     = defer_think;
                e.nextthink = time + fdelay;
index c304380..615aa51 100644 (file)
 .void(entity this, bool isNew)m_read;
 
 #ifdef CSQC
-       #define Net_Accept() \
+       #define Net_Accept(classname) \
                do \
                { \
-                       if (!this)    this = spawn(); \
+                       if (!this)    this = new(classname); \
                } \
                while (0)
        #define Net_Reject() \
                void Ent_Read##id(entity this, param) \
                { \
                        this = self; \
+                       this.sourceLocFile = __FILE__; \
+                       this.sourceLocLine = __LINE__; \
                } \
-               REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, spawn()) \
+               REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, new(net_linked_packet)) \
                { \
+                       make_pure(this); \
                        this.netname = #id; \
                        this.m_read = Ent_Read##id; \
                } \
 #else
        #define REGISTER_NET_LINKED(id, param) \
                const bool NET_##id##_istemp = false; \
-               REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, spawn()) \
+               REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, new(net_linked_packet)) \
                { \
+                       make_pure(this); \
                        this.netname = #id; \
                }
 #endif
 
-REGISTRY(LinkedEntities, BIT(0))
+REGISTRY(LinkedEntities, BITS(2))
 REGISTER_REGISTRY(RegisterLinkedEntities)
 REGISTRY_SORT(LinkedEntities, netname, 0)
 STATIC_INIT(RegisterLinkedEntities_renumber)
@@ -115,8 +119,9 @@ STATIC_INIT(RegisterLinkedEntities_renumber)
 #ifdef CSQC
        #define REGISTER_NET_TEMP(id, param) \
                void Net_Read##id(entity this, param); \
-               REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, spawn()) \
+               REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, new(net_temp_packet)) \
                { \
+                       make_pure(this); \
                        this.netname = #id; \
                        this.m_read = Net_Read##id; \
                } \
@@ -124,13 +129,14 @@ STATIC_INIT(RegisterLinkedEntities_renumber)
 #else
        #define REGISTER_NET_TEMP(id, param) \
                const bool NET_##id##_istemp = true; \
-               REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, spawn()) \
+               REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, new(net_temp_packet)) \
                { \
+                       make_pure(this); \
                        this.netname = #id; \
                }
 #endif
 
-REGISTRY(TempEntities, BIT(0))
+REGISTRY(TempEntities, BITS(2))
 REGISTER_REGISTRY(RegisterTempEntities)
 REGISTRY_SORT(TempEntities, netname, 0)
 STATIC_INIT(RegisterTempEntities_renumber)
@@ -164,6 +170,8 @@ STATIC_INIT(RegisterTempEntities_renumber)
                        return v;
                }
        #else
+               const int MSG_ENTITY = 5;
+
                void WriteInt24_t(float dst, float val)
                {
                        float v;
index 6a9a2e3..2925e9e 100644 (file)
        #define NULL (world)
 #endif
 
+.vector origin;
+.bool pure_data;
+#define make_pure(e) \
+       do \
+       { \
+               (e).pure_data = true; \
+       } \
+       while (0)
+#define is_pure(e) ((e).pure_data)
+
 .string classname;
 /** Location entity was spawned from in source */
 .string sourceLocFile;
 .int sourceLocLine;
 entity _spawn();
-entity __spawn(string _classname, string _sourceFile, int _sourceLine)
+entity __spawn(string _classname, string _sourceFile, int _sourceLine, bool pure)
 {
        entity this = _spawn();
        this.classname = _classname;
        this.sourceLocFile = _sourceFile;
        this.sourceLocLine = _sourceLine;
+       if (pure) make_pure(this);
        return this;
 }
 
@@ -30,13 +41,13 @@ entity __spawn(string _classname, string _sourceFile, int _sourceLine)
 #ifndef QCC_SUPPORT_ENTITYCLASS
        #define entityclass_2(name, base) typedef entity name
        #define class(name)
-       #define new(class) __spawn( #class, __FILE__, __LINE__)
+       #define new(class) __spawn( #class, __FILE__, __LINE__, false)
 #else
        #define entityclass_2(name, base) entityclass name : base {}
        #define class(name) [[class(name)]]
-       #define new(class) ((class) __spawn( #class, __FILE__, __LINE__))
+       #define new(class) ((class) __spawn( #class, __FILE__, __LINE__, false))
 #endif
-#define spawn() new(entity)
+#define spawn() __spawn("entity", __FILE__, __LINE__, false)
 
 // Classes have a `spawn##cname(entity)` constructor
 // The parameter is used across [[accumulate]] functions
@@ -82,6 +93,7 @@ STATIC_INIT(RegisterClasses)
        void cname##_vtbl_init() \
        { \
                cname e = new(vtbl); \
+               make_pure(e); \
                spawn##cname##_static(e); \
                e.vtblname = #cname; \
                /* Top level objects refer to themselves */ \
@@ -164,7 +176,7 @@ CLASS(Object, );
                }
                return s;
        }
-       METHOD(Object, display, void(entity this, void(string name, string icon)returns))
+       METHOD(Object, display, void(entity this, void(string name, string icon) returns))
        {
                returns(sprintf("entity %i", this), "nopreview_map");
        }
index dfb3d7f..fecc79b 100644 (file)
@@ -2,8 +2,8 @@
 
 entity Sort_Spawn()
 {
-       entity sort;
-       sort = spawn();
+       entity sort = new(sortlist);
+       make_pure(sort);
        sort.sort_next = NULL;
        sort.chain = sort;
        return sort;
index f4242eb..8a17854 100644 (file)
@@ -33,6 +33,11 @@ noref bool require_spawnfunc_prefix;
                void spawnfunc_##id(entity this) \
                { \
                        this = self; \
+                       if (!this.sourceLocFile) \
+                       { \
+                               this.sourceLocFile = __FILE__; \
+                               this.sourceLocLine = __LINE__; \
+                       } \
                        if (!this.spawnfunc_checked) \
                        { \
                                for (int i = 0, n = numentityfields(); i < n; ++i) \
@@ -68,6 +73,8 @@ noref bool require_spawnfunc_prefix;
                /**/
 
        #define FIELDS_UNION(fld) \
+               FIELD_SCALAR(fld, sourceLocFile) \
+               FIELD_SCALAR(fld, sourceLocLine) \
                FIELD_SCALAR(fld, Version) \
                FIELD_SCALAR(fld, ammo_cells) \
                FIELD_SCALAR(fld, ammo_nails) \
index c60201b..0a48ef6 100644 (file)
@@ -94,8 +94,8 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
                                // attempts to close will result in a reading handle
 
                                // create a writing end that does nothing yet
-                               e = spawn();
-                               e.classname = "url_single_fopen_file";
+                               e = new(url_single_fopen_file);
+                               make_pure(e);
                                e.url_url = strzone(url);
                                e.url_fh = URL_FH_CURL;
                                e.url_wbuf = buf_create();
@@ -143,8 +143,8 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
                                // Make a dummy handle object (no buffers at
                                // all). Wait for data to come from the
                                // server, then call the callback
-                               e = spawn();
-                               e.classname = "url_single_fopen_file";
+                               e = new(url_single_fopen_file);
+                               make_pure(e);
                                e.url_url = strzone(url);
                                e.url_fh = URL_FH_CURL;
                                e.url_rbuf = -1;
@@ -165,8 +165,8 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
                {
                        case FILE_WRITE:
                        case FILE_APPEND:
-                               e = spawn();
-                               e.classname = "url_single_fopen_stdout";
+                               e = new(url_single_fopen_stdout);
+                               make_pure(e);
                                e.url_fh = URL_FH_STDOUT;
                                e.url_ready = rdy;
                                e.url_ready_pass = pass;
@@ -189,8 +189,8 @@ void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
                }
                else
                {
-                       e = spawn();
-                       e.classname = "url_single_fopen_file";
+                       e = new(url_single_fopen_file);
+                       make_pure(e);
                        e.url_fh = fh;
                        e.url_ready = rdy;
                        e.url_ready_pass = pass;
@@ -364,9 +364,8 @@ void url_multi_fopen(string url, int mode, url_ready_func rdy, entity pass)
                return;
        }
 
-       entity me;
-       me = spawn();
-       me.classname = "url_multi";
+       entity me = new(url_multi);
+       make_pure(me);
        me.url_url = strzone(url);
        me.url_attempt = 0;
        me.url_mode = mode;
index aba39c2..4921605 100644 (file)
@@ -30,8 +30,7 @@ void WarpZone_Read(float isnew)
        warpzone_warpzones_exist = 1;
        if (!self.enemy)
        {
-               self.enemy = spawn();
-               self.enemy.classname = "warpzone_from";
+               self.enemy = new(warpzone_from);
        }
        self.classname = "trigger_warpzone";
 
@@ -149,8 +148,8 @@ void WarpZone_Camera_Read(float isnew)
 void CL_RotateMoves(vector ang) = #638;
 void WarpZone_Teleported_Read(float isnew)
 {SELFPARAM();
-       vector v;
        self.classname = "warpzone_teleported";
+       vector v;
        v.x = ReadCoord();
        v.y = ReadCoord();
        v.z = ReadCoord();
index 6fe901b..a142b82 100644 (file)
@@ -186,8 +186,8 @@ void WarpZone_Trace_InitTransform()
 {
        if(!WarpZone_trace_transform)
        {
-               WarpZone_trace_transform = spawn();
-               WarpZone_trace_transform.classname = "warpzone_trace_transform";
+               WarpZone_trace_transform = new(warpzone_trace_transform);
+               make_pure(WarpZone_trace_transform);
        }
        WarpZone_Accumulator_Clear(WarpZone_trace_transform);
 }
@@ -572,37 +572,20 @@ vector WarpZoneLib_NearestPointOnBox(vector mi, vector ma, vector org)
 
 bool WarpZoneLib_BadEntity(entity e)
 {
-       string myclassname = e.classname;
-       if (e.instanceOfObject) return true;
-       switch(myclassname)
+       string s = e.classname;
+       if (is_pure(e)) return true;
+       switch (s)
        {
-               case "deathtype":
-               case "weaponentity":
-               case "exteriorweaponentity":
-               case "csqc_score_team":
-               case "pingplreport":
-               case "ent_client_scoreinfo":
-               case "saved_cvar_value":
-               case "accuracy":
                case "entcs_sender":
                case "entcs_receiver":
-               case "clientinit":
-               case "sprite_waypoint":
-               case "waypoint":
-               case "gibsplash":
-               //case "net_linked": // actually some real entities are linked without classname, fail
+               // case "net_linked": // actually some real entities are linked without classname, fail
                case "":
                        return true;
        }
 
-       if(startsWith(myclassname, "msg_"))
-               return true;
-
-       if(startsWith(myclassname, "target_"))
-               return true;
+       if (startsWith(s, "target_")) return true;
 
-       if(startsWith(myclassname, "info_"))
-               return true;
+       if (startsWith(s, "info_")) return true;
 
        return false;
 }
@@ -703,8 +686,7 @@ void WarpZone_RefSys_CheckCreate(entity me)
 {
        if(me.WarpZone_refsys.owner != me)
        {
-               me.WarpZone_refsys = spawn();
-               me.WarpZone_refsys.classname = "warpzone_refsys";
+               me.WarpZone_refsys = new(warpzone_refsys);
                me.WarpZone_refsys.owner = me;
                me.WarpZone_refsys.think = WarpZone_RefSys_GC;
                me.WarpZone_refsys.nextthink = time + 1;
index e21e4ca..ec109da 100644 (file)
@@ -137,7 +137,7 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
                // instead of fixangle, send the transform to the client for smoother operation
                player.fixangle = false;
 
-               entity ts = spawn();
+               entity ts = new(warpzone_teleported);
                setmodel(ts, MDL_Null);
                ts.SendEntity = WarpZone_Teleported_Send;
                ts.SendFlags = 0xFFFFFF;
@@ -147,7 +147,6 @@ float WarpZone_Teleport(entity wz, entity player, float f0, float f1)
                ts.owner = player;
                ts.enemy = wz;
                ts.effects = EF_NODEPTHTEST;
-               ts.classname = "warpzone_teleported";
                ts.angles = wz.warpzone_transform;
        }
 #endif
index 2cee616..3819036 100644 (file)
@@ -173,9 +173,7 @@ void RegisterSLCategories()
        #define SLIST_CATEGORY(name,enoverride,dioverride,str) \
                SET_FIELD_COUNT(name, CATEGORY_FIRST, category_ent_count) \
                CHECK_MAX_COUNT(name, MAX_CATEGORIES, category_ent_count, "SLIST_CATEGORY") \
-               cat = spawn(); \
-               categories[name - 1] = cat; \
-               cat.classname = "slist_category"; \
+               cat = categories[name - 1] = new(slist_category); \
                cat.cat_name = strzone(#name); \
                cat.cat_enoverride_string = strzone(SLIST_CATEGORY_AUTOCVAR(name)); \
                cat.cat_dioverride_string = strzone(dioverride); \
index 50e1d45..9541540 100644 (file)
@@ -19,7 +19,7 @@ float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, f
        if (targ.solid < SOLID_BBOX) // SOLID_NOT and SOLID_TRIGGER
                return false; // could never hit it
        if (!tracetossent)
-               tracetossent = spawn();
+               tracetossent = new(tracetossent);
        tracetossent.owner = ignore;
        setsize(tracetossent, m1, m2);
        savesolid = targ.solid;
@@ -38,7 +38,7 @@ float findtrajectorywithleading(vector org, vector m1, vector m2, entity targ, f
        }
 
        if (!tracetossfaketarget)
-               tracetossfaketarget = spawn();
+               tracetossfaketarget = new(tracetossfaketarget);
        tracetossfaketarget.solid = savesolid;
        tracetossfaketarget.movetype = targ.movetype;
        _setmodel(tracetossfaketarget, targ.model); // no low precision
index 9dfc26d..e62c99b 100644 (file)
@@ -1118,9 +1118,8 @@ void bot_setcurrentcommand()
 
        if(!self.bot_cmd_current)
        {
-               self.bot_cmd_current = spawn();
-               self.bot_cmd_current.classname = "bot_cmd";
-               self.bot_cmd_current.is_bot_cmd = 1;
+               self.bot_cmd_current = new(bot_cmd);
+               self.bot_cmd_current.is_bot_cmd = true;
        }
 
        bot_cmd = self.bot_cmd_current;
index 156ad79..fe767b8 100644 (file)
@@ -27,9 +27,9 @@ entity waypoint_spawn(vector m1, vector m2, float f)
                w = find(w, classname, "waypoint");
        }
 
-       w = spawn();
+       w = new(waypoint);
+       make_pure(w);
        w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
-       w.classname = "waypoint";
        w.wpflags = f;
        setorigin(w, (m1 + m2) * 0.5);
        setsize(w, m1 - w.origin, m2 - w.origin);
index 4b64055..1313cb7 100644 (file)
@@ -150,8 +150,7 @@ float CheatImpulse(float i)
                        // shared with regular waypoint init, so this is not a cheat by itself
                        if(!self.personal)
                        {
-                               self.personal = spawn();
-                               self.personal.classname = "personal_wp";
+                               self.personal = new(personal_wp);
                        }
                        self.personal.origin = self.origin;
                        self.personal.v_angle = self.v_angle;
@@ -402,8 +401,7 @@ float CheatCommand(float argc)
                        break;
                case "dragbox_spawn": {
                        IS_CHEAT(0, argc, 0);
-                       entity e = spawn();
-                       e.classname = "dragbox_box";
+                       entity e = new(dragbox_box);
                        e.think = DragBox_Think;
                        e.nextthink = time;
                        e.solid = -1; // black
@@ -413,8 +411,7 @@ float CheatCommand(float argc)
                        else
                                e.cnt = max(0, drag_lastcnt);
 
-                       e.aiment = spawn();
-                       e.aiment.classname = "dragbox_corner_1";
+                       e.aiment = new(dragbox_corner_1);
                        e.aiment.owner = e;
                        setmodel(e.aiment, MDL_MARKER);
                        e.aiment.skin = 0;
@@ -427,8 +424,7 @@ float CheatCommand(float argc)
                                setorigin(e.aiment, trace_endpos);
                        }
 
-                       e.enemy = spawn();
-                       e.enemy.classname = "dragbox_corner_2";
+                       e.enemy = new(dragbox_corner_2);
                        e.enemy.owner = e;
                        setmodel(e.enemy, MDL_MARKER);
                        e.enemy.skin = 1;
@@ -442,13 +438,11 @@ float CheatCommand(float argc)
                        else
                                setorigin(e.enemy, e.aiment.origin + 32 * end);
 
-                       e.killindicator = spawn();
-                       e.killindicator.classname = "drag_digit";
+                       e.killindicator = new(drag_digit);
                        e.killindicator.owner = e;
                        setattachment(e.killindicator, e, "");
                        setorigin(e.killindicator, '0 0 -8');
-                       e.killindicator.killindicator = spawn();
-                       e.killindicator.killindicator.classname = "drag_digit";
+                       e.killindicator.killindicator = new(drag_digit);
                        e.killindicator.killindicator.owner = e;
                        setattachment(e.killindicator.killindicator, e, "");
                        setorigin(e.killindicator.killindicator, '0 0 8');
@@ -457,8 +451,7 @@ float CheatCommand(float argc)
                }
                case "dragpoint_spawn": {
                        IS_CHEAT(0, argc, 0);
-                       entity e = spawn();
-                       e.classname = "dragpoint";
+                       entity e = new(dragpoint);
                        e.think = DragBox_Think;
                        e.nextthink = time;
                        e.solid = 0; // nothing special
@@ -478,13 +471,11 @@ float CheatCommand(float argc)
                                move_out_of_solid(e);
                        }
 
-                       e.killindicator = spawn();
-                       e.killindicator.classname = "drag_digit";
+                       e.killindicator = new(drag_digit);
                        e.killindicator.owner = e;
                        setattachment(e.killindicator, e, "");
                        setorigin(e.killindicator, '0 0 40');
-                       e.killindicator.killindicator = spawn();
-                       e.killindicator.killindicator.classname = "drag_digit";
+                       e.killindicator.killindicator = new(drag_digit);
                        e.killindicator.killindicator.owner = e;
                        setattachment(e.killindicator.killindicator, e, "");
                        setorigin(e.killindicator.killindicator, '0 0 56');
@@ -713,9 +704,8 @@ float CheatCommand(float argc)
                        break;
                case "teleporttotarget":
                        IS_CHEAT(0, argc, 0);
-                       setself(spawn());
+                       setself(new(cheattriggerteleport));
                        setorigin(self, self.origin);
-                       self.classname = "cheattriggerteleport";
                        self.target = argv(1);
                        teleport_findtarget();
                        if(!wasfreed(self))
index 09ce11a..8f1e3e9 100644 (file)
@@ -96,9 +96,10 @@ bool ClientData_Send(entity this, entity to, int sf)
 
 void ClientData_Attach()
 {SELFPARAM();
-       Net_LinkEntity(self.clientdata = spawn(), false, 0, ClientData_Send);
-       self.clientdata.drawonlytoclient = self;
-       self.clientdata.owner = self;
+       Net_LinkEntity(this.clientdata = new(clientdata), false, 0, ClientData_Send);
+       make_pure(this.clientdata);
+       self.clientdata.drawonlytoclient = this;
+       self.clientdata.owner = this;
 }
 
 void ClientData_Detach()
@@ -535,7 +536,8 @@ void PutClientInServer()
                this.revival_time = 0;
                this.air_finished = time + 12;
 
-               entity spawnevent = spawn();
+               entity spawnevent = new(spawnevent);
+               make_pure(spawnevent);
                spawnevent.owner = this;
                Net_LinkEntity(spawnevent, false, 0.5, SpawnEvent_Send);
 
@@ -693,8 +695,9 @@ void ClientInit_CheckUpdate()
 
 void ClientInit_Spawn()
 {SELFPARAM();
-       entity e = spawn();
-       e.classname = "clientinit";
+
+       entity e = new(clientinit);
+       make_pure(e);
        e.think = ClientInit_CheckUpdate;
        Net_LinkEntity(e, false, 0, ClientInit_SendEntity);
 
@@ -1338,7 +1341,7 @@ void UpdateChatBubble()
        // spawn a chatbubble entity if needed
        if (!self.chatbubbleentity)
        {
-               self.chatbubbleentity = spawn();
+               self.chatbubbleentity = new(chatbubbleentity);
                self.chatbubbleentity.owner = self;
                self.chatbubbleentity.exteriormodeltoclient = self;
                self.chatbubbleentity.think = ChatBubbleThink;
index 205c2a0..83c599d 100644 (file)
@@ -52,7 +52,7 @@ void CopyBody(float keepvelocity)
 {SELFPARAM();
        if (self.effects & EF_NODRAW)
                return;
-       setself(spawn());
+       setself(new(body));
        self.enemy = this;
        self.lip = this.lip;
        self.colormap = this.colormap;
@@ -62,7 +62,6 @@ void CopyBody(float keepvelocity)
        self.angles = this.angles;
        self.v_angle = this.v_angle;
        self.avelocity = this.avelocity;
-       self.classname = "body";
        self.damageforcescale = this.damageforcescale;
        self.effects = this.effects;
        self.glowmod = this.glowmod;
index 26d108a..7475c5a 100644 (file)
@@ -372,8 +372,7 @@ float RadarMap_Make(float argc)
 
        if (!radarmapper)
        {
-               radarmapper = spawn();
-               radarmapper.classname = "radarmapper";
+               radarmapper = new(radarmapper);
                radarmapper.think = RadarMap_Think;
                radarmapper.nextthink = time;
                radarmapper.count = 8;  // default to the --trace method, as it is faster now
index c65bd8f..fe7b05b 100644 (file)
@@ -1000,8 +1000,7 @@ void GameCommand_make_mapinfo(float request)
                {
                        entity tmp_entity;
 
-                       tmp_entity = spawn();
-                       tmp_entity.classname = "make_mapinfo";
+                       tmp_entity = new(make_mapinfo);
                        tmp_entity.think = make_mapinfo_Think;
                        tmp_entity.nextthink = time;
                        MapInfo_Enumerate();
index 1e60cd0..d7c8298 100644 (file)
@@ -86,7 +86,8 @@ bool Nagger_SendEntity(entity this, entity to, float sendflags)
 
 void Nagger_Init()
 {
-       Net_LinkEntity(nagger = spawn(), false, 0, Nagger_SendEntity);
+       Net_LinkEntity(nagger = new(nagger), false, 0, Nagger_SendEntity);
+       make_pure(nagger);
 }
 
 void Nagger_VoteChanged()
index 961b001..95b13f1 100644 (file)
@@ -18,8 +18,6 @@ const int RESPAWN_SILENT = 2;
 
 #define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT)
 
-const int MSG_ENTITY = 5; // csqc
-
 const int NUM_PLAYERSKINS_TEAMPLAY = 3;
 
 const int ASSAULT_VALUE_INACTIVE = 1000;
index cf275c0..f69ea7a 100644 (file)
@@ -68,6 +68,7 @@ void entcs_think()
 entity attach_entcs(entity e)
 {
        entity ent = e.entcs = new(entcs_sender);
+       make_pure(ent);
        ent.owner = e;
        ent.think = entcs_think;
        ent.nextthink = time;
index 802eabd..36495a1 100644 (file)
@@ -49,7 +49,8 @@ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad
        if(!sound_allowed(MSG_BROADCAST, dmgowner))
                deathtype |= 0x8000;
 
-       e = spawn();
+       e = new(damageinfo);
+       make_pure(e);
        setorigin(e, org);
        e.projectiledeathtype = deathtype;
        e.dmg = coredamage;
@@ -114,8 +115,7 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
                {
                        if(!GiveFrags_randomweapons)
                        {
-                               GiveFrags_randomweapons = spawn();
-                               GiveFrags_randomweapons.classname = "GiveFrags_randomweapons";
+                               GiveFrags_randomweapons = new(GiveFrags_randomweapons);
                        }
 
                        if(warmup_stage)
@@ -563,10 +563,8 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
        targ.revive_speed = freeze_time;
        self.bot_attack = false;
 
-       entity ice, head;
-       ice = spawn();
+       entity ice = new(ice);
        ice.owner = targ;
-       ice.classname = "ice";
        ice.scale = targ.scale;
        ice.think = Ice_Think;
        ice.nextthink = time;
@@ -582,6 +580,7 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
 
        RemoveGrapplingHook(targ);
 
+       entity head;
        FOR_EACH_PLAYER(head)
        if(head.hook.aiment == targ)
                RemoveGrapplingHook(head);
@@ -889,9 +888,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                vector farce = damage_explosion_calcpush(self.damageforcescale * force, self.velocity, autocvar_g_balance_damagepush_speedfactor);
                if(self.movetype == MOVETYPE_PHYSICS)
                {
-                       entity farcent;
-                       farcent = spawn();
-                       farcent.classname = "farce";
+                       entity farcent = new(farce);
                        farcent.enemy = self;
                        farcent.movedir = farce * 10;
                        if(self.mass)
@@ -1140,8 +1137,7 @@ float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
                if(!e.fire_burner)
                {
                        // print("adding a fire burner to ", e.classname, "\n");
-                       e.fire_burner = spawn();
-                       e.fire_burner.classname = "fireburner";
+                       e.fire_burner = new(fireburner);
                        e.fire_burner.think = fireburner_think;
                        e.fire_burner.nextthink = time;
                        e.fire_burner.owner = e;
index f9f4083..eecb046 100644 (file)
@@ -93,20 +93,20 @@ bool g_clientmodel_genericsendentity(entity this, entity to, int sf)
        WriteByte(MSG_ENTITY, ENT_CLIENT_WALL);
        WriteByte(MSG_ENTITY, sf);
 
-       if(sf & 1)
+       if(sf & BIT(0))
        {
                if(sf & 0x40)
                        WriteShort(MSG_ENTITY, self.colormap);
        }
 
-       if(sf & 2)
+       if(sf & BIT(1))
        {
                WriteCoord(MSG_ENTITY, self.origin.x);
                WriteCoord(MSG_ENTITY, self.origin.y);
                WriteCoord(MSG_ENTITY, self.origin.z);
        }
 
-       if(sf & 4)
+       if(sf & BIT(2))
        {
                if(sf & 0x10)
                {
@@ -116,7 +116,7 @@ bool g_clientmodel_genericsendentity(entity this, entity to, int sf)
                }
        }
 
-       if(sf & 8)
+       if(sf & BIT(3))
        {
                if(sf & 0x80)
                {
index b016acd..d59c4b4 100644 (file)
@@ -2,28 +2,28 @@
 
 .int state;
 
+REGISTER_NET_TEMP(net_gibsplash, bool isNew)
+
 bool Violence_GibSplash_SendEntity(entity this, entity to, int sf)
 {
-       WriteByte(MSG_ENTITY, ENT_CLIENT_GIBSPLASH);
-       WriteByte(MSG_ENTITY, self.state); // actually type
-       WriteByte(MSG_ENTITY, bound(1, self.cnt * 16, 255)); // gibbage amount multiplier
-       WriteShort(MSG_ENTITY, floor(self.origin.x / 4)); // not using a coord here, as gibs don't need this accuracy
-       WriteShort(MSG_ENTITY, floor(self.origin.y / 4)); // not using a coord here, as gibs don't need this accuracy
-       WriteShort(MSG_ENTITY, floor(self.origin.z / 4)); // not using a coord here, as gibs don't need this accuracy
-       WriteShort(MSG_ENTITY, self.oldorigin.x); // acrually compressed velocity
+       int channel = MSG_ONE;
+       msg_entity = to;
+       WriteHeader(channel, net_gibsplash);
+       WriteByte(channel, this.state); // actually type
+       WriteByte(channel, bound(1, this.cnt * 16, 255)); // gibbage amount multiplier
+       WriteShort(channel, floor(this.origin.x / 4)); // not using a coord here, as gibs don't need this accuracy
+       WriteShort(channel, floor(this.origin.y / 4)); // not using a coord here, as gibs don't need this accuracy
+       WriteShort(channel, floor(this.origin.z / 4)); // not using a coord here, as gibs don't need this accuracy
+       WriteShort(channel, this.oldorigin.x); // acrually compressed velocity
        return true;
 }
 
-// TODO maybe convert this to a TE?
 void Violence_GibSplash_At(vector org, vector dir, float type, float amount, entity gibowner, entity attacker)
 {SELFPARAM();
        if(g_cts) // no gibs in CTS
                return;
 
-       entity e;
-
-       e = spawn();
-       e.classname = "gibsplash";
+       entity e = new(gibsplash);
        e.cnt = amount;
        e.state = type; // should stay smaller than 15
        if(!sound_allowed(MSG_BROADCAST, gibowner) || !sound_allowed(MSG_BROADCAST, attacker))
@@ -42,7 +42,8 @@ void Violence_GibSplash_At(vector org, vector dir, float type, float amount, ent
 
        e.oldorigin_x = compressShortVector(e.velocity);
 
-       Net_LinkEntity(e, false, 0.2, Violence_GibSplash_SendEntity);
+       entity cl; FOR_EACH_REALCLIENT(cl) Violence_GibSplash_SendEntity(e, cl, 0);
+       remove(e);
 }
 
 void Violence_GibSplash(entity source, float type, float amount, entity attacker)
index 01e69f4..25fcdfd 100644 (file)
@@ -83,8 +83,8 @@ void PingPLReport_Think()
 }
 void PingPLReport_Spawn()
 {
-       pingplreport = spawn();
-       pingplreport.classname = "pingplreport";
+       pingplreport = new(pingplreport);
+       make_pure(pingplreport);
        pingplreport.think = PingPLReport_Think;
        pingplreport.nextthink = time;
 }
@@ -528,7 +528,8 @@ void RandomSeed_Think()
 }
 void RandomSeed_Spawn()
 {SELFPARAM();
-       randomseed = spawn();
+       randomseed = new(randomseed);
+       make_pure(randomseed);
        randomseed.think = RandomSeed_Think;
        Net_LinkEntity(randomseed, false, 0, RandomSeed_Send);
 
@@ -546,13 +547,11 @@ spawnfunc(__init_dedicated_server)
 
        remove = remove_unsafely;
 
-       entity e;
-       e = spawn();
+       entity e = spawn();
        e.think = GotoFirstMap;
        e.nextthink = time; // this is usually 1 at this point
 
-       e = spawn();
-       e.classname = "info_player_deathmatch"; // safeguard against player joining
+       e = new(info_player_deathmatch);  // safeguard against player joining
 
        self.classname = "worldspawn"; // safeguard against various stuff ;)
 
index a60970d..7463fef 100644 (file)
@@ -318,9 +318,7 @@ void Ban_LoadBans()
                }
        }
 
-       entity e;
-       e = spawn();
-       e.classname = "bansyncer";
+       entity e = new(bansyncer);
        e.think = OnlineBanList_Think;
        e.nextthink = time + 1;
 }
index 604e9ee..50b5780 100644 (file)
@@ -1649,10 +1649,7 @@ bool modeleffect_SendEntity(entity this, entity to, int sf)
 
 void modeleffect_spawn(string m, float s, float f, vector o, vector v, vector ang, vector angv, float s0, float s2, float a, float t1, float t2)
 {
-       entity e;
-       float sz;
-       e = spawn();
-       e.classname = "modeleffect";
+       entity e = new(modeleffect);
        _setmodel(e, m);
        e.frame = f;
        setorigin(e, o);
@@ -1671,7 +1668,7 @@ void modeleffect_spawn(string m, float s, float f, vector o, vector v, vector an
                e.scale2 = s2 / max6(-e.mins.x, -e.mins.y, -e.mins.z, e.maxs.x, e.maxs.y, e.maxs.z);
        else
                e.scale2 = -s2;
-       sz = max(e.scale, e.scale2);
+       float sz = max(e.scale, e.scale2);
        setsize(e, e.mins * sz, e.maxs * sz);
        Net_LinkEntity(e, false, 0.1, modeleffect_SendEntity);
 }
index 73e992c..594e89b 100644 (file)
@@ -467,13 +467,12 @@ void ctf_CaptureShield_Touch()
 
 void ctf_CaptureShield_Spawn(entity flag)
 {SELFPARAM();
-       entity shield = spawn();
+       entity shield = new(ctf_captureshield);
 
        shield.enemy = self;
        shield.team = self.team;
        shield.touch = ctf_CaptureShield_Touch;
        shield.customizeentityforclient = ctf_CaptureShield_Customize;
-       shield.classname = "ctf_captureshield";
        shield.effects = EF_ADDITIVE;
        shield.movetype = MOVETYPE_NOCLIP;
        shield.solid = SOLID_TRIGGER;
index 8961e6b..ea14243 100644 (file)
@@ -462,13 +462,11 @@ MUTATOR_HOOKFUNCTION(ka, DropSpecialItems)
 
 void ka_SpawnBall() // loads various values for the ball, runs only once at start of match
 {
-       entity e;
-       e = spawn();
+       entity e = new(keepawayball);
        e.model = "models/orbs/orbblue.md3";
        precache_model(e.model);
        _setmodel(e, e.model);
        setsize(e, '-16 -16 -20', '16 16 20'); // 20 20 20 was too big, player is only 16 16 24... gotta cheat with the Z (20) axis so that the particle isn't cut off
-       e.classname = "keepawayball";
        e.damageforcescale = autocvar_g_keepawayball_damageforcescale;
        e.takedamage = DAMAGE_YES;
        e.solid = SOLID_TRIGGER;
index 5982cf2..6f46cef 100644 (file)
@@ -802,8 +802,7 @@ void key_reset()
 const string STR_ITEM_KH_KEY = "item_kh_key";
 void kh_Key_Spawn(entity initial_owner, float angle, float i)  // runs every time a new flag is created, ie after all the keys have been collected
 {
-       entity key;
-       key = spawn();
+       entity key = spawn();
        key.count = i;
        key.classname = STR_ITEM_KH_KEY;
        key.touch = kh_Key_Touch;
index 51ddcad..02f1dff 100644 (file)
@@ -203,7 +203,7 @@ void ons_CaptureShield_Reset()
 
 void ons_CaptureShield_Spawn(entity generator, bool is_generator)
 {
-       entity shield = spawn();
+       entity shield = new(ons_captureshield);
 
        shield.enemy = generator;
        shield.team = generator.team;
@@ -211,7 +211,6 @@ void ons_CaptureShield_Spawn(entity generator, bool is_generator)
        shield.reset = ons_CaptureShield_Reset;
        shield.touch = ons_CaptureShield_Touch;
        shield.customizeentityforclient = ons_CaptureShield_Customize;
-       shield.classname = "ons_captureshield";
        shield.effects = EF_ADDITIVE;
        shield.movetype = MOVETYPE_NOCLIP;
        shield.solid = SOLID_TRIGGER;
@@ -712,12 +711,11 @@ void onslaught_controlpoint_icon_link(entity e, void() spawnproc);
 
 void ons_ControlPoint_Icon_Spawn(entity cp, entity player)
 {
-       entity e = spawn();
+       entity e = new(onslaught_controlpoint_icon);
 
        setsize(e, CPICON_MIN, CPICON_MAX);
        setorigin(e, cp.origin + CPICON_OFFSET);
 
-       e.classname = "onslaught_controlpoint_icon";
        e.owner = cp;
        e.max_health = autocvar_g_onslaught_cp_health;
        e.health = autocvar_g_onslaught_cp_buildhealth;
index cc567d2..ccbf9e3 100644 (file)
@@ -69,10 +69,9 @@ void nade_burn_spawn(entity _nade)
 
 void nade_spawn(entity _nade)
 {
-       entity timer = spawn();
+       entity timer = new(nade_timer);
        setmodel(timer, MDL_NADE_TIMER);
        setattachment(timer, _nade, "");
-       timer.classname = "nade_timer";
        timer.colormap = _nade.colormap;
        timer.glowmod = _nade.glowmod;
        timer.think = nade_timer_think;
@@ -164,11 +163,10 @@ void nade_napalm_ball()
 
        spamsound(self, CH_SHOTS, SND(FIREBALL_FIRE), VOL_BASE, ATTEN_NORM);
 
-       proj = spawn ();
+       proj = new(grenade);
        proj.owner = self.owner;
        proj.realowner = self.realowner;
        proj.team = self.owner.team;
-       proj.classname = "grenade";
        proj.bot_dodge = true;
        proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage;
        proj.movetype = MOVETYPE_BOUNCE;
@@ -360,10 +358,9 @@ void nade_ice_boom()
        if ( autocvar_g_nades_ice_explode )
        {
                setmodel(fountain, MDL_PROJECTILE_GRENADE);
-               entity timer = spawn();
+               entity timer = new(nade_timer);
                setmodel(timer, MDL_NADE_TIMER);
                setattachment(timer, fountain, "");
-               timer.classname = "nade_timer";
                timer.colormap = self.colormap;
                timer.glowmod = self.glowmod;
                timer.think = nade_timer_think;
@@ -827,10 +824,7 @@ void nade_prime()
        if(self.fake_nade)
                remove(self.fake_nade);
 
-       entity n = spawn(), fn = spawn();
-
-       n.classname = "nade";
-       fn.classname = "fake_nade";
+       entity n = new(nade), fn = new(fake_nade);
 
        if(self.items & ITEM_Strength.m_itemid && autocvar_g_nades_bonus_onstrength)
                n.nade_type = self.nade_type;
index 0df6acc..017a8a2 100644 (file)
@@ -108,7 +108,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerDies)
                other = world;
        }
 
-       setself(spawn());
+       setself(new(droppedweapon)); // hax
        self.ok_item = true;
        self.noalign = true;
        self.pickup_anyway = true;
@@ -118,7 +118,6 @@ MUTATOR_HOOKFUNCTION(ok, PlayerDies)
        self.reset = SUB_Remove;
        setorigin(self, frag_target.origin + '0 0 32');
        self.velocity = '0 0 200' + normalize(targ.origin - self.origin) * 500;
-       self.classname = "droppedweapon"; // hax
        SUB_SetFade(self, time + 5, 1);
        setself(this);
 
@@ -247,10 +246,9 @@ MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
        {
                if(self.classname == "item_strength")
                {
-                       entity wep = spawn();
+                       entity wep = new(weapon_hmg);
                        setorigin(wep, self.origin);
                        setmodel(wep, MDL_OK_HMG);
-                       wep.classname = "weapon_hmg";
                        wep.ok_item = true;
                        wep.noalign = self.noalign;
                        wep.cnt = self.cnt;
@@ -264,10 +262,9 @@ MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
 
                if(self.classname == "item_invincible")
                {
-                       entity wep = spawn();
+                       entity wep = new(weapon_rpc);
                        setorigin(wep, self.origin);
                        setmodel(wep, MDL_OK_RPC);
-                       wep.classname = "weapon_rpc";
                        wep.ok_item = true;
                        wep.noalign = self.noalign;
                        wep.cnt = self.cnt;
index dbee6a1..9369da4 100644 (file)
@@ -165,8 +165,7 @@ entity sandbox_ObjectSpawn(float database)
 {SELFPARAM();
        // spawn a new object with default properties
 
-       entity e = spawn();
-       e.classname = "object";
+       entity e = new(object);
        e.takedamage = DAMAGE_AIM;
        e.damageforcescale = 1;
        e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
index 800f033..9a199bd 100644 (file)
@@ -471,9 +471,8 @@ entity pathlib_astar(vector from,vector to)
     {
         LOG_TRACE("AStar: Goal found on first node!\n");
 
-        open           = spawn();
+        open           = new(path_end);
         open.owner     = open;
-        open.classname = "path_end";
         setorigin(open,path.origin);
 
         pathlib_cleanup();
index 9b1d719..1860046 100644 (file)
@@ -624,8 +624,7 @@ entity Portal_Spawn(entity own, vector org, vector ang)
        if(!CheckWireframeBox(own, org - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
                return world;
 
-       portal = spawn();
-       portal.classname = "portal";
+       portal = new(portal);
        portal.aiment = own;
        setorigin(portal, org);
        portal.mangle = ang;
index 678baec..8e4ae30 100644 (file)
@@ -87,9 +87,8 @@ bool TeamScore_SendEntity(entity this, entity to, float sendflags)
 
 void TeamScore_Spawn(float t, string name)
 {
-       entity ts;
-       ts = spawn();
-       ts.classname = "csqc_score_team";
+       entity ts = new(csqc_score_team);
+       make_pure(ts);
        ts.netname = name; // not used yet, FIXME
        ts.team = t;
        Net_LinkEntity(ts, false, 0, TeamScore_SendEntity);
@@ -211,8 +210,8 @@ void ScoreInfo_Init(float teams)
        }
        else
        {
-               scores_initialized = spawn();
-               scores_initialized.classname = "ent_client_scoreinfo";
+               scores_initialized = new(ent_client_scoreinfo);
+               make_pure(scores_initialized);
                Net_LinkEntity(scores_initialized, false, 0, ScoreInfo_SendEntity);
        }
        if(teams >= 1)
@@ -316,10 +315,10 @@ void Score_ClearAll()
 
 void PlayerScore_Attach(entity player)
 {
-       entity sk;
        if(player.scorekeeper)
                error("player already has a scorekeeper");
-       sk = spawn();
+       entity sk = new(scorekeeper);
+       make_pure(sk);
        sk.owner = player;
        Net_LinkEntity(sk, false, 0, PlayerScore_SendEntity);
        player.scorekeeper = sk;
index a1abfa5..ecd7497 100644 (file)
@@ -117,9 +117,7 @@ void relocate_spawnpoint()
     {
         // show where spawnpoints point at too
         makevectors(self.angles);
-        entity e;
-        e = spawn();
-        e.classname = "info_player_foo";
+        entity e = new(info_player_foo);
         setorigin(e, self.origin + v_forward * 24);
         setsize(e, '-8 -8 -8', '8 8 8');
         e.solid = SOLID_TRIGGER;
index 4941b55..beaab08 100644 (file)
@@ -547,16 +547,13 @@ MODEL(FLOCKER, "models/turrets/rocket.md3");
 
 void spawn_flocker()
 {SELFPARAM();
-    entity flocker;
-
-    flocker = spawn ();
+    entity flocker = new(flocker);
 
     setorigin(flocker, self.origin + '0 0 32');
     setmodel (flocker, MDL_FLOCKER);
     setsize (flocker, '-3 -3 -3', '3 3 3');
 
     flocker.flock_id   = self.flock_id;
-    flocker.classname  = "flocker";
     flocker.owner      = self;
     flocker.think      = flocker_think;
     flocker.nextthink  = time + random() * 5;
@@ -649,12 +646,11 @@ spawnfunc(flockerspawn)
     self.think     = flockerspawn_think;
     self.nextthink = time + 0.25;
 
-    self.enemy = spawn();
+    self.enemy = new(FLock Hunter);
 
     setmodel(self.enemy, MDL_FLOCKER);
     setorigin(self.enemy,self.origin + '0 0 768' + (randomvec() * 128));
 
-    self.enemy.classname = "FLock Hunter";
     self.enemy.scale     = 3;
     self.enemy.effects   = EF_LOWPRECISION;
     self.enemy.movetype  = MOVETYPE_BOUNCEMISSILE;
index 1ffcb60..7dbc614 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "../common/constants.qh"
 #include "../common/deathtypes/all.qh"
+#include "../common/debug.qh"
 #include "../common/mapinfo.qh"
 #include "../common/util.qh"
 
index f8bc6a1..019bcda 100644 (file)
@@ -40,6 +40,7 @@ bool accuracy_send(entity this, entity to, int sf)
 void accuracy_init(entity e)
 {
        entity a = e.accuracy = new(accuracy);
+       make_pure(a);
        a.owner = e;
        a.drawonlytoclient = e;
        Net_LinkEntity(a, false, 0, accuracy_send);
index 900b450..0670183 100644 (file)
@@ -36,10 +36,9 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
        string s;
        var .int ammotype = (get_weaponinfo(wpn)).ammo_field;
 
-       entity wep = spawn();
+       entity wep = new(droppedweapon);
 
        setorigin(wep, org);
-       wep.classname = "droppedweapon";
        wep.velocity = velo;
        wep.owner = wep.enemy = own;
        wep.flags |= FL_TOSSED;
index e64391d..ff87430 100644 (file)
@@ -175,13 +175,13 @@ void CL_WeaponEntity_SetModel(entity this, int slot, string name)
                // if we don't, this is a "real" animated model
                if (gettagindex(this, "weapon"))
                {
-                       if (!this.weaponentity[slot]) this.weaponentity[slot] = spawn();
+                       if (!this.weaponentity[slot]) this.weaponentity[slot] = new(weaponentity);
                        _setmodel(this.weaponentity[slot], W_Model(strcat("v_", name, ".md3")));
                        setattachment(this.weaponentity[slot], this, "weapon");
                }
                else if (gettagindex(this, "tag_weapon"))
                {
-                       if (!this.weaponentity[slot]) this.weaponentity[slot] = spawn();
+                       if (!this.weaponentity[slot]) this.weaponentity[slot] = new(weaponentity);
                        _setmodel(this.weaponentity[slot], W_Model(strcat("v_", name, ".md3")));
                        setattachment(this.weaponentity[slot], this, "tag_weapon");
                }
@@ -442,6 +442,7 @@ void CL_ExteriorWeaponentity_Think()
 void CL_SpawnWeaponentity(entity e, int slot)
 {
        entity view = e.weaponentity[slot] = new(weaponentity);
+       make_pure(view);
        view.solid = SOLID_NOT;
        view.owner = e;
        setmodel(view, MDL_Null);  // precision set when changed
@@ -455,8 +456,8 @@ void CL_SpawnWeaponentity(entity e, int slot)
 
        if (slot == 0)
        {
-               entity exterior = e.exteriorweaponentity = spawn();
-               exterior.classname = "exteriorweaponentity";
+               entity exterior = e.exteriorweaponentity = new(exteriorweaponentity);
+               make_pure(exterior);
                exterior.solid = SOLID_NOT;
                exterior.exteriorweaponentity = exterior;
                exterior.owner = e;