]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/weapons/projectile.qc
Fix typo
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / weapons / projectile.qc
index 4ebe4afcfb7e8c55c64f6f8f0425c46b0f393976..7f64e9ab98787708f96a5aa05e9ea783183d4e3f 100644 (file)
@@ -6,6 +6,7 @@
 #include "../mutators/events.qh"
 
 #include <common/constants.qh>
+#include <common/net_linked.qh>
 #include <common/physics/movetypes/movetypes.qh>
 
 #include <lib/csqcmodel/interpolate.qh>
 .float scale;
 .vector colormod;
 
-void SUB_Stop()
+void SUB_Stop(entity this, entity toucher)
 {
-       SELFPARAM();
-       self.move_velocity = self.move_avelocity = '0 0 0';
-       self.move_movetype = MOVETYPE_NONE;
+       this.velocity = this.avelocity = '0 0 0';
+       set_movetype(this, MOVETYPE_NONE);
 }
 
 void Projectile_ResetTrail(entity this, vector to)
@@ -59,44 +59,44 @@ void Projectile_Draw(entity this)
        float t;
        float a;
 
-       f = self.move_flags;
+       f = this.flags;
 
-       if (self.count & 0x80)
+       if (this.count & 0x80)
        {
-               // self.move_flags &= ~FL_ONGROUND;
-               if (self.move_movetype == MOVETYPE_NONE || self.move_movetype == MOVETYPE_FLY)
-                       Movetype_Physics_NoMatchServer(self);
+               // UNSET_ONGROUND(this);
+               if (this.move_movetype == MOVETYPE_NONE || this.move_movetype == MOVETYPE_FLY)
+                       Movetype_Physics_NoMatchServer(this);
                // the trivial movetypes do not have to match the
                // server's ticrate as they are ticrate independent
                // NOTE: this assumption is only true if MOVETYPE_FLY
                // projectiles detonate on impact. If they continue
                // moving, we might still be ticrate dependent.
                else
-                       Movetype_Physics_MatchServer(self, autocvar_cl_projectiles_sloppy);
-               if (!(self.move_flags & FL_ONGROUND))
-                       if (self.velocity != '0 0 0')
-                               self.move_angles = self.angles = vectoangles(self.velocity);
+                       Movetype_Physics_MatchServer(this, autocvar_cl_projectiles_sloppy);
+               if (!IS_ONGROUND(this))
+                       if (this.velocity != '0 0 0')
+                               this.angles = vectoangles(this.velocity);
        }
        else
        {
-               InterpolateOrigin_Do(self);
+               InterpolateOrigin_Do(this);
        }
 
-       if (self.count & 0x80)
+       if (this.count & 0x80)
        {
-               drawn = (time >= self.spawntime - 0.02);
-               t = max(time, self.spawntime);
+               drawn = (time >= this.spawntime - 0.02);
+               t = max(time, this.spawntime);
        }
        else
        {
-               drawn = (self.iflags & IFLAG_VALID);
+               drawn = (this.iflags & IFLAG_VALID);
                t = time;
        }
 
        if (!(f & FL_ONGROUND))
        {
                rot = '0 0 0';
-               switch (self.cnt)
+               switch (this.cnt)
                {
                        /*
                        case PROJECTILE_GRENADE:
@@ -109,29 +109,32 @@ void Projectile_Draw(entity this)
                        case PROJECTILE_HOOKBOMB:
                                rot = '1000 0 0';  // forward
                                break;
+                       case PROJECTILE_ROCKET:
+                               rot = '0 0 720'; // spinning
+                               break;
                        default:
                                break;
                }
 
-               if (Projectile_isnade(self.cnt))
-                       rot = self.avelocity;
+               if (Projectile_isnade(this.cnt))
+                       rot = this.avelocity;
 
-               self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
+               this.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(this.angles), rot * (t - this.spawntime)));
        }
 
        vector ang;
-       ang = self.angles;
+       ang = this.angles;
        ang.x = -ang.x;
        makevectors(ang);
 
-       a = 1 - (time - self.fade_time) * self.fade_rate;
-       self.alpha = bound(0, self.alphamod * a, 1);
-       if (self.alpha <= 0)
+       a = 1 - (time - this.fade_time) * this.fade_rate;
+       this.alpha = bound(0, this.alphamod * a, 1);
+       if (this.alpha <= 0)
                drawn = 0;
-       self.renderflags = 0;
+       this.renderflags = 0;
 
-       trailorigin = self.origin;
-       switch (self.cnt)
+       trailorigin = this.origin;
+       switch (this.cnt)
        {
                case PROJECTILE_GRENADE:
                case PROJECTILE_GRENADE_BOUNCING:
@@ -141,46 +144,45 @@ void Projectile_Draw(entity this)
                        break;
        }
 
-       if (Projectile_isnade(self.cnt))
+       if (Projectile_isnade(this.cnt))
                trailorigin += v_up * 4;
 
        if (drawn)
-               Projectile_DrawTrail(self, trailorigin);
+               Projectile_DrawTrail(this, trailorigin);
        else
-               Projectile_ResetTrail(self, trailorigin);
+               Projectile_ResetTrail(this, trailorigin);
 
-       self.drawmask = 0;
+       this.drawmask = 0;
 
        if (!drawn)
                return;
 
-       switch (self.cnt)
+       switch (this.cnt)
        {
                // Possibly add dlights here.
                default:
                        break;
        }
 
-       self.drawmask = MASK_NORMAL;
+       this.drawmask = MASK_NORMAL;
 }
 
-void loopsound(entity e, int ch, string samp, float vol, float attn)
+void loopsound(entity e, int ch, Sound samp, float vol, float attn)
 {
-       SELFPARAM();
-       if (self.silent)
+    TC(int, ch);
+       if (e.silent)
                return;
 
-       _sound(e, ch, samp, vol, attn);
+       sound(e, ch, samp, vol, attn);
        e.snd_looping = ch;
 }
 
-void Ent_RemoveProjectile()
+void Ent_RemoveProjectile(entity this)
 {
-       SELFPARAM();
-       if (self.count & 0x80)
+       if (this.count & 0x80)
        {
-               tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.05, MOVE_NORMAL, self);
-               Projectile_DrawTrail(self, trace_endpos);
+               tracebox(this.origin, this.mins, this.maxs, this.origin + this.velocity * 0.05, MOVE_NORMAL, this);
+               Projectile_DrawTrail(this, trace_endpos);
        }
 }
 
@@ -201,286 +203,305 @@ NET_HANDLE(ENT_CLIENT_PROJECTILE, bool isnew)
        // projectiles don't send angles, because they always follow the velocity
 
        int f = ReadByte();
-       self.count = (f & 0x80);
-       self.flags |= FL_PROJECTILE;
-       self.iflags = (self.iflags & IFLAG_INTERNALMASK) | IFLAG_AUTOANGLES | IFLAG_ANGLES | IFLAG_ORIGIN;
-       self.solid = SOLID_TRIGGER;
-       // self.effects = EF_NOMODELFLAGS;
+       this.count = (f & 0x80);
+       this.flags |= FL_PROJECTILE;
+       this.iflags = (this.iflags & IFLAG_INTERNALMASK) | IFLAG_AUTOANGLES | IFLAG_ANGLES | IFLAG_ORIGIN;
+       this.solid = SOLID_TRIGGER;
+       // this.effects = EF_NOMODELFLAGS;
 
        // this should make collisions with bmodels more exact, but it leads to
        // projectiles no longer being able to lie on a bmodel
-       self.move_nomonsters = MOVE_WORLDONLY;
+       this.move_nomonsters = MOVE_WORLDONLY;
        if (f & 0x40)
-               self.move_flags |= FL_ONGROUND;
+               SET_ONGROUND(this);
        else
-               self.move_flags &= ~FL_ONGROUND;
+               UNSET_ONGROUND(this);
 
-       if (!self.move_time)
+       if (!this.move_time)
        {
                // for some unknown reason, we don't need to care for
                // sv_gameplayfix_delayprojectiles here.
-               self.move_time = time;
-               self.spawntime = time;
+               this.move_time = time;
+               this.spawntime = time;
        }
        else
        {
-               self.move_time = max(self.move_time, time);
+               this.move_time = max(this.move_time, time);
        }
 
-       if (!(self.count & 0x80))
-               InterpolateOrigin_Undo(self);
+       if (!(this.count & 0x80))
+               InterpolateOrigin_Undo(this);
 
        if (f & 1)
        {
-               self.origin_x = ReadCoord();
-               self.origin_y = ReadCoord();
-               self.origin_z = ReadCoord();
-               setorigin(self, self.origin);
-               if (self.count & 0x80)
+               this.origin_x = ReadCoord();
+               this.origin_y = ReadCoord();
+               this.origin_z = ReadCoord();
+               setorigin(this, this.origin);
+               if (this.count & 0x80)
                {
-                       self.velocity_x = ReadCoord();
-                       self.velocity_y = ReadCoord();
-                       self.velocity_z = ReadCoord();
+                       this.velocity_x = ReadCoord();
+                       this.velocity_y = ReadCoord();
+                       this.velocity_z = ReadCoord();
                        if (f & 0x10)
-                               self.gravity = ReadCoord();
+                               this.gravity = ReadCoord();
                        else
-                               self.gravity = 0;  // none
-                       self.move_origin = self.origin;
-                       self.move_velocity = self.velocity;
+                               this.gravity = 0;  // none
                }
 
-               if (time == self.spawntime || (self.count & 0x80) || (f & 0x08))
+               if (time == this.spawntime || (this.count & 0x80) || (f & 0x08))
                {
-                       self.trail_oldorigin = self.origin;
-                       if (!(self.count & 0x80))
-                               InterpolateOrigin_Reset();
+                       this.trail_oldorigin = this.origin;
+                       if (!(this.count & 0x80))
+                               InterpolateOrigin_Reset(this);
                }
 
                if (f & 0x20)
                {
-                       self.fade_time = time + ReadByte() * ticrate;
-                       self.fade_rate = 1 / (ReadByte() * ticrate);
+                       this.fade_time = time + ReadByte() * ticrate;
+                       this.fade_rate = 1 / (ReadByte() * ticrate);
                }
                else
                {
-                       self.fade_time = 0;
-                       self.fade_rate = 0;
+                       this.fade_time = 0;
+                       this.fade_rate = 0;
                }
 
-               self.team = ReadByte() - 1;
+               int myteam = ReadByte();
+               this.team = myteam - 1;
+
+               if(teamplay)
+               {
+                       if(myteam)
+                               this.colormap = (this.team) * 0x11; // note: team - 1 on server (client uses different numbers)
+                       else
+                               this.colormap = 0x00;
+                       this.colormap |= BIT(10); // RENDER_COLORMAPPED
+               }
+               else
+                       this.colormap = myteam;
+               // TODO: projectiles use glowmaps for their color, not teams
+               #if 0
+               if(this.colormap > 0)
+                       this.glowmod = colormapPaletteColor(this.colormap & 0x0F, true) * 2;
+               else
+                       this.glowmod = '1 1 1';
+               #endif
        }
 
        if (f & 2)
        {
-               self.cnt = ReadByte();
+               this.cnt = ReadByte();
 
-               self.silent = (self.cnt & 0x80);
-               self.cnt = (self.cnt & 0x7F);
+               this.silent = (this.cnt & 0x80);
+               this.cnt = (this.cnt & 0x7F);
 
-               self.scale = 1;
-               self.traileffect = 0;
-               switch (self.cnt)
+               this.scale = 1;
+               this.traileffect = 0;
+               switch (this.cnt)
                {
-                       #define HANDLE(id) case PROJECTILE_##id: setmodel(self, MDL_PROJECTILE_##id);
-                       HANDLE(ELECTRO)            self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-                       HANDLE(ROCKET)             self.traileffect = EFFECT_TR_ROCKET.m_id; self.scale = 2; break;
-                       HANDLE(CRYLINK)            self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
-                       HANDLE(CRYLINK_BOUNCING)   self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
-                       HANDLE(ELECTRO_BEAM)       self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-                       HANDLE(GRENADE)            self.traileffect = EFFECT_TR_GRENADE.m_id; break;
-                       HANDLE(GRENADE_BOUNCING)   self.traileffect = EFFECT_TR_GRENADE.m_id; break;
-                       HANDLE(MINE)               self.traileffect = EFFECT_TR_GRENADE.m_id; break;
-                       HANDLE(BLASTER)            self.traileffect = EFFECT_Null.m_id; break;
-                       HANDLE(HLAC)               self.traileffect = EFFECT_Null.m_id; break;
-                       HANDLE(PORTO_RED)          self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
-                       HANDLE(PORTO_BLUE)         self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
-                       HANDLE(HOOKBOMB)           self.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
-                       HANDLE(HAGAR)              self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
-                       HANDLE(HAGAR_BOUNCING)     self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
-                       HANDLE(FIREBALL)           self.modelindex = 0; self.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
-                       HANDLE(FIREMINE)           self.modelindex = 0; self.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
-                       HANDLE(TAG)                self.traileffect = EFFECT_TR_ROCKET.m_id; break;
-                       HANDLE(FLAC)               self.scale = 0.4; self.traileffect = EFFECT_FLAC_TRAIL.m_id; break;
-                       HANDLE(SEEKER)             self.traileffect = EFFECT_SEEKER_TRAIL.m_id; break;
-
-                       HANDLE(MAGE_SPIKE)         self.traileffect = EFFECT_TR_VORESPIKE.m_id; break;
-                       HANDLE(SHAMBLER_LIGHTNING) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-
-                       HANDLE(RAPTORBOMB)         self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
-                       HANDLE(RAPTORBOMBLET)      self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
-                       HANDLE(RAPTORCANNON)       self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
-
-                       HANDLE(SPIDERROCKET)       self.traileffect = EFFECT_SPIDERBOT_ROCKET_TRAIL.m_id; break;
-                       HANDLE(WAKIROCKET)         self.traileffect = EFFECT_RACER_ROCKET_TRAIL.m_id; break;
-                       HANDLE(WAKICANNON)         self.traileffect = EFFECT_Null.m_id; break;
-
-                       HANDLE(BUMBLE_GUN)         self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-                       HANDLE(BUMBLE_BEAM)        self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-
-                       HANDLE(RPC)                self.traileffect = EFFECT_TR_ROCKET.m_id; break;
-
-                       HANDLE(ROCKETMINSTA_LASER) self.traileffect = EFFECT_ROCKETMINSTA_LASER(self.team).m_id; break;
+#define HANDLE(id) case PROJECTILE_##id: setmodel(this, MDL_PROJECTILE_##id);
+                       HANDLE(ELECTRO)            this.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+                       HANDLE(ROCKET)             this.traileffect = EFFECT_TR_ROCKET.m_id; this.scale = 2; break;
+                       HANDLE(CRYLINK)            this.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+                       HANDLE(CRYLINK_BOUNCING)   this.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+                       HANDLE(ELECTRO_BEAM)       this.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+                       HANDLE(GRENADE)            this.traileffect = EFFECT_TR_GRENADE.m_id; break;
+                       HANDLE(GRENADE_BOUNCING)   this.traileffect = EFFECT_TR_GRENADE.m_id; break;
+                       HANDLE(MINE)               this.traileffect = EFFECT_TR_GRENADE.m_id; break;
+                       HANDLE(BLASTER)            this.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(ARC_BOLT)           this.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(HLAC)               this.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(PORTO_RED)          this.traileffect = EFFECT_TR_WIZSPIKE.m_id; this.scale = 4; break;
+                       HANDLE(PORTO_BLUE)         this.traileffect = EFFECT_TR_WIZSPIKE.m_id; this.scale = 4; break;
+                       HANDLE(HOOKBOMB)           this.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
+                       HANDLE(HAGAR)              this.traileffect = EFFECT_HAGAR_ROCKET.m_id; this.scale = 0.75; break;
+                       HANDLE(HAGAR_BOUNCING)     this.traileffect = EFFECT_HAGAR_ROCKET.m_id; this.scale = 0.75; break;
+                       HANDLE(FIREBALL)           this.modelindex = 0; this.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
+                       HANDLE(FIREMINE)           this.modelindex = 0; this.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
+                       HANDLE(TAG)                this.traileffect = EFFECT_TR_ROCKET.m_id; break;
+                       HANDLE(FLAC)               this.scale = 0.4; this.traileffect = EFFECT_FLAC_TRAIL.m_id; break;
+                       HANDLE(SEEKER)             this.traileffect = EFFECT_SEEKER_TRAIL.m_id; break;
+
+                       HANDLE(MAGE_SPIKE)         this.traileffect = EFFECT_TR_VORESPIKE.m_id; break;
+                       HANDLE(SHAMBLER_LIGHTNING) this.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+
+                       HANDLE(RAPTORBOMB)         this.gravity = 1; this.avelocity = '0 0 180'; this.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(RAPTORBOMBLET)      this.gravity = 1; this.avelocity = '0 0 180'; this.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(RAPTORCANNON)       this.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+
+                       HANDLE(SPIDERROCKET)       this.traileffect = EFFECT_SPIDERBOT_ROCKET_TRAIL.m_id; break;
+                       HANDLE(WAKIROCKET)         this.traileffect = EFFECT_RACER_ROCKET_TRAIL.m_id; break;
+                       HANDLE(WAKICANNON)         this.traileffect = EFFECT_Null.m_id; break;
+
+                       HANDLE(BUMBLE_GUN)         this.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+                       HANDLE(BUMBLE_BEAM)        this.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+
+                       HANDLE(RPC)                this.traileffect = EFFECT_TR_ROCKET.m_id; break;
+
+                       HANDLE(ROCKETMINSTA_LASER) this.traileffect = EFFECT_ROCKETMINSTA_LASER(this.team).m_id; break;
 #undef HANDLE
                        default:
-                               if (MUTATOR_CALLHOOK(Ent_Projectile, self))
+                               if (MUTATOR_CALLHOOK(Ent_Projectile, this))
                                        break;
 
                                error("Received invalid CSQC projectile, can't work with this!");
                                break;
                }
 
-               self.mins = '0 0 0';
-               self.maxs = '0 0 0';
-               self.colormod = '0 0 0';
-               self.move_touch = SUB_Stop;
-               self.move_movetype = MOVETYPE_TOSS;
-               self.alphamod = 1;
+               this.mins = '0 0 0';
+               this.maxs = '0 0 0';
+               this.colormod = '0 0 0';
+               settouch(this, SUB_Stop);
+               set_movetype(this, MOVETYPE_TOSS);
+               this.alphamod = 1;
 
-               switch (self.cnt)
+               switch (this.cnt)
                {
                        case PROJECTILE_ELECTRO:
                                // only new engines support sound moving with object
-                               loopsound(self, CH_SHOTS_SINGLE, SND(ELECTRO_FLY), VOL_BASE, ATTEN_NORM);
-                               self.mins = '0 0 -4';
-                               self.maxs = '0 0 -4';
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
-                               self.move_bounce_factor = WEP_CVAR_SEC(electro, bouncefactor);
-                               self.move_bounce_stopspeed = WEP_CVAR_SEC(electro, bouncestop);
+                               loopsound(this, CH_SHOTS_SINGLE, SND_ELECTRO_FLY, VOL_BASE, ATTEN_NORM);
+                               this.mins = '-4 -4 -4';
+                               this.maxs = '4 4 4';
+                               set_movetype(this, MOVETYPE_BOUNCE);
+                               settouch(this, func_null);
+                               this.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
+                               this.bouncestop = WEP_CVAR_SEC(electro, bouncestop);
                                break;
                        case PROJECTILE_RPC:
                        case PROJECTILE_ROCKET:
-                               loopsound(self, CH_SHOTS_SINGLE, SND(ROCKET_FLY), VOL_BASE, ATTEN_NORM);
-                               self.mins = '-3 -3 -3';
-                               self.maxs = '3 3 3';
+                               loopsound(this, CH_SHOTS_SINGLE, SND_ROCKET_FLY, VOL_BASE, ATTEN_NORM);
+                               this.mins = '-3 -3 -3';
+                               this.maxs = '3 3 3';
                                break;
                        case PROJECTILE_GRENADE:
-                               self.mins = '-3 -3 -3';
-                               self.maxs = '3 3 3';
+                               this.mins = '-3 -3 -3';
+                               this.maxs = '3 3 3';
                                break;
                        case PROJECTILE_GRENADE_BOUNCING:
-                               self.mins = '-3 -3 -3';
-                               self.maxs = '3 3 3';
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
-                               self.move_bounce_factor = WEP_CVAR(mortar, bouncefactor);
-                               self.move_bounce_stopspeed = WEP_CVAR(mortar, bouncestop);
+                               this.mins = '-3 -3 -3';
+                               this.maxs = '3 3 3';
+                               set_movetype(this, MOVETYPE_BOUNCE);
+                               settouch(this, func_null);
+                               this.bouncefactor = WEP_CVAR(mortar, bouncefactor);
+                               this.bouncestop = WEP_CVAR(mortar, bouncestop);
                                break;
                        case PROJECTILE_SHAMBLER_LIGHTNING:
-                               self.mins = '-8 -8 -8';
-                               self.maxs = '8 8 8';
-                               self.scale = 2.5;
-                               self.avelocity = randomvec() * 720;
+                               this.mins = '-8 -8 -8';
+                               this.maxs = '8 8 8';
+                               this.scale = 2.5;
+                               this.avelocity = randomvec() * 720;
                                break;
                        case PROJECTILE_MINE:
-                               self.mins = '-4 -4 -4';
-                               self.maxs = '4 4 4';
+                               this.mins = '-4 -4 -4';
+                               this.maxs = '4 4 4';
                                break;
                        case PROJECTILE_PORTO_RED:
-                               self.colormod = '2 1 1';
-                               self.alphamod = 0.5;
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
+                               this.colormod = '2 1 1';
+                               this.alphamod = 0.5;
+                               set_movetype(this, MOVETYPE_BOUNCE);
+                               settouch(this, func_null);
                                break;
                        case PROJECTILE_PORTO_BLUE:
-                               self.colormod = '1 1 2';
-                               self.alphamod = 0.5;
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
+                               this.colormod = '1 1 2';
+                               this.alphamod = 0.5;
+                               set_movetype(this, MOVETYPE_BOUNCE);
+                               settouch(this, func_null);
                                break;
                        case PROJECTILE_HAGAR_BOUNCING:
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
+                               set_movetype(this, MOVETYPE_BOUNCE);
+                               settouch(this, func_null);
                                break;
                        case PROJECTILE_CRYLINK_BOUNCING:
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
+                               set_movetype(this, MOVETYPE_BOUNCE);
+                               settouch(this, func_null);
                                break;
                        case PROJECTILE_FIREBALL:
-                               loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM);
-                               self.mins = '-16 -16 -16';
-                               self.maxs = '16 16 16';
+                               loopsound(this, CH_SHOTS_SINGLE, SND_FIREBALL_FLY2, VOL_BASE, ATTEN_NORM);
+                               this.mins = '-16 -16 -16';
+                               this.maxs = '16 16 16';
                                break;
                        case PROJECTILE_FIREMINE:
-                               loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY), VOL_BASE, ATTEN_NORM);
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
-                               self.mins = '-4 -4 -4';
-                               self.maxs = '4 4 4';
+                               loopsound(this, CH_SHOTS_SINGLE, SND_FIREBALL_FLY, VOL_BASE, ATTEN_NORM);
+                               set_movetype(this, MOVETYPE_BOUNCE);
+                               settouch(this, func_null);
+                               this.mins = '-4 -4 -4';
+                               this.maxs = '4 4 4';
                                break;
                        case PROJECTILE_TAG:
-                               self.mins = '-2 -2 -2';
-                               self.maxs = '2 2 2';
+                               this.mins = '-2 -2 -2';
+                               this.maxs = '2 2 2';
                                break;
                        case PROJECTILE_FLAC:
-                               self.mins = '-2 -2 -2';
-                               self.maxs = '2 2 2';
+                               this.mins = '-2 -2 -2';
+                               this.maxs = '2 2 2';
                                break;
                        case PROJECTILE_SEEKER:
-                               loopsound(self, CH_SHOTS_SINGLE, SND(TAG_ROCKET_FLY), VOL_BASE, ATTEN_NORM);
-                               self.mins = '-4 -4 -4';
-                               self.maxs = '4 4 4';
+                               loopsound(this, CH_SHOTS_SINGLE, SND_TAG_ROCKET_FLY, VOL_BASE, ATTEN_NORM);
+                               this.mins = '-4 -4 -4';
+                               this.maxs = '4 4 4';
                                break;
                        case PROJECTILE_RAPTORBOMB:
-                               self.mins = '-3 -3 -3';
-                               self.maxs = '3 3 3';
+                               this.mins = '-3 -3 -3';
+                               this.maxs = '3 3 3';
                                break;
                        case PROJECTILE_RAPTORBOMBLET:
                                break;
                        case PROJECTILE_RAPTORCANNON:
                                break;
                        case PROJECTILE_SPIDERROCKET:
-                               loopsound(self, CH_SHOTS_SINGLE, SND(TAG_ROCKET_FLY), VOL_BASE, ATTEN_NORM);
+                               loopsound(this, CH_SHOTS_SINGLE, SND_TAG_ROCKET_FLY, VOL_BASE, ATTEN_NORM);
                                break;
                        case PROJECTILE_WAKIROCKET:
-                               loopsound(self, CH_SHOTS_SINGLE, SND(TAG_ROCKET_FLY), VOL_BASE, ATTEN_NORM);
+                               loopsound(this, CH_SHOTS_SINGLE, SND_TAG_ROCKET_FLY, VOL_BASE, ATTEN_NORM);
                                break;
                        /*
                        case PROJECTILE_WAKICANNON:
                            break;
                        case PROJECTILE_BUMBLE_GUN:
                            // only new engines support sound moving with object
-                           loopsound(self, CH_SHOTS_SINGLE, SND(ELECTRO_FLY), VOL_BASE, ATTEN_NORM);
-                           self.mins = '0 0 -4';
-                           self.maxs = '0 0 -4';
-                           self.move_movetype = MOVETYPE_BOUNCE;
-                           self.move_touch = func_null;
-                           self.move_bounce_factor = WEP_CVAR_SEC(electro, bouncefactor);
-                           self.move_bounce_stopspeed = WEP_CVAR_SEC(electro, bouncestop);
+                           loopsound(this, CH_SHOTS_SINGLE, SND_ELECTRO_FLY, VOL_BASE, ATTEN_NORM);
+                           this.mins = '0 0 -4';
+                           this.maxs = '0 0 -4';
+                           this.move_movetype = MOVETYPE_BOUNCE;
+                           settouch(this, func_null);
+                           this.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
+                           this.bouncestop = WEP_CVAR_SEC(electro, bouncestop);
                            break;
                        */
                        default:
                                break;
                }
 
-               MUTATOR_CALLHOOK(EditProjectile, self);
+               MUTATOR_CALLHOOK(EditProjectile, this);
 
-               setsize(self, self.mins, self.maxs);
+               setsize(this, this.mins, this.maxs);
        }
 
        return = true;
 
-       if (self.gravity)
+       if (this.gravity)
        {
-               if (self.move_movetype == MOVETYPE_FLY)
-                       self.move_movetype = MOVETYPE_TOSS;
-               if (self.move_movetype == MOVETYPE_BOUNCEMISSILE)
-                       self.move_movetype = MOVETYPE_BOUNCE;
+               if (this.move_movetype == MOVETYPE_FLY)
+                       set_movetype(this, MOVETYPE_TOSS);
+               if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
+                       set_movetype(this, MOVETYPE_BOUNCE);
        }
        else
        {
-               if (self.move_movetype == MOVETYPE_TOSS)
-                       self.move_movetype = MOVETYPE_FLY;
-               if (self.move_movetype == MOVETYPE_BOUNCE)
-                       self.move_movetype = MOVETYPE_BOUNCEMISSILE;
+               if (this.move_movetype == MOVETYPE_TOSS)
+                       set_movetype(this, MOVETYPE_FLY);
+               if (this.move_movetype == MOVETYPE_BOUNCE)
+                       set_movetype(this, MOVETYPE_BOUNCEMISSILE);
        }
 
-       if (!(self.count & 0x80))
+       if (!(this.count & 0x80))
                InterpolateOrigin_Note(this);
 
-       self.classname = "csqcprojectile";
-       self.draw = Projectile_Draw;
-       self.entremove = Ent_RemoveProjectile;
+       this.classname = "csqcprojectile";
+       this.draw = Projectile_Draw;
+       if (isnew) IL_PUSH(g_drawables, this);
+       this.entremove = Ent_RemoveProjectile;
 }
 
 PRECACHE(Projectiles)