]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
This commit is dedicated to TimePath
authorMario <mario@smbclan.net>
Sun, 29 Nov 2015 03:49:04 +0000 (13:49 +1000)
committerMario <mario@smbclan.net>
Sun, 29 Nov 2015 03:49:04 +0000 (13:49 +1000)
# Conflicts:
# qcsrc/common/movetypes/movetypes.qc
# qcsrc/common/movetypes/toss.qc
# qcsrc/common/mutators/mutator/dodging/dodging.qc
# qcsrc/common/mutators/mutator/multijump/multijump.qc
# qcsrc/common/physics.qc
# qcsrc/common/physics.qh
# qcsrc/common/stats.qh
# qcsrc/server/autocvars.qh

98 files changed:
balance-nexuiz25.cfg
balance-overkill.cfg
balance-samual.cfg
balance-xdf.cfg
balance-xonotic.cfg
balance-xpm.cfg
qcsrc/client/hook.qc
qcsrc/client/hud/hud.qh
qcsrc/client/miscfunctions.qc
qcsrc/client/miscfunctions.qh
qcsrc/client/mutators/events.qh
qcsrc/client/scoreboard.qc
qcsrc/client/shownames.qc
qcsrc/client/weapons/projectile.qc
qcsrc/common/csqcmodel_settings.qh
qcsrc/common/effects/qc/casings.qc
qcsrc/common/effects/qc/gibs.qc
qcsrc/common/ent_cs.qc
qcsrc/common/ent_cs.qh
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_monsters.qh
qcsrc/common/movetypes/follow.qc
qcsrc/common/movetypes/movetypes.qc
qcsrc/common/movetypes/movetypes.qh
qcsrc/common/movetypes/push.qc
qcsrc/common/movetypes/push.qh
qcsrc/common/movetypes/step.qc
qcsrc/common/movetypes/toss.qc
qcsrc/common/movetypes/toss.qh
qcsrc/common/movetypes/walk.qc
qcsrc/common/movetypes/walk.qh
qcsrc/common/mutators/all.inc
qcsrc/common/mutators/events.qh
qcsrc/common/mutators/mutator/buffs/buffs.qc
qcsrc/common/mutators/mutator/bugrigs/bugrigs.qc [new file with mode: 0644]
qcsrc/common/mutators/mutator/bugrigs/module.inc [new file with mode: 0644]
qcsrc/common/mutators/mutator/dodging/dodging.qc
qcsrc/common/mutators/mutator/dodging/module.inc
qcsrc/common/mutators/mutator/doublejump/doublejump.qc [new file with mode: 0644]
qcsrc/common/mutators/mutator/doublejump/module.inc [new file with mode: 0644]
qcsrc/common/mutators/mutator/multijump/multijump.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/physics.qc
qcsrc/common/physics.qh
qcsrc/common/stats.qh
qcsrc/common/triggers/func/door.qc
qcsrc/common/triggers/func/plat.qc
qcsrc/common/triggers/func/train.qc
qcsrc/common/triggers/subs.qh
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/turret/ewheel.qc
qcsrc/common/turrets/turret/flac.qc
qcsrc/common/turrets/turret/fusionreactor.qc
qcsrc/common/turrets/turret/hellion.qc
qcsrc/common/turrets/turret/hk.qc
qcsrc/common/turrets/turret/machinegun.qc
qcsrc/common/turrets/turret/mlrs.qc
qcsrc/common/turrets/turret/phaser.qc
qcsrc/common/turrets/turret/plasma.qc
qcsrc/common/turrets/turret/plasma_dual.qc
qcsrc/common/turrets/turret/tesla.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/util.qc
qcsrc/common/vehicles/vehicle/raptor_weapons.qc
qcsrc/common/viewloc.qc
qcsrc/common/viewloc.qh
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/lib/_all.inc
qcsrc/lib/arraylist.qh
qcsrc/lib/counting.qh
qcsrc/lib/csqcmodel/cl_model.qc
qcsrc/lib/csqcmodel/cl_model.qh
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/csqcmodel/cl_player.qh
qcsrc/lib/math.qh
qcsrc/lib/oo.qh
qcsrc/lib/player.qh [deleted file]
qcsrc/lib/registry.qh
qcsrc/lib/static.qh
qcsrc/menu/xonotic/playermodel.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/server/anticheat.qc
qcsrc/server/anticheat.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/events.qh
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_race.qc
qcsrc/server/playerdemo.qc
qcsrc/server/playerdemo.qh
qcsrc/server/sv_main.qc
qcsrc/server/t_items.qc
qcsrc/server/teamplay.qc

index 6e18dc092a59d488192a2ca693d6f54de37d7e03..3ac47371ee350ab68ce3fe4c5c2c3d2dfe769696 100644 (file)
@@ -182,6 +182,8 @@ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage wi
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
 set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
 set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
+set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
 set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
 set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
 set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
index a99d342babf184895cccd11fa4b8a875ebaea505..a691a191838bdae351692863f639a759fb1e5059 100644 (file)
@@ -182,6 +182,8 @@ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage wi
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
 set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
 set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
+set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
 set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
 set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
 set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
index 379bc207d199b19c71cd247520369be06ad6af2b..6d7831adac2624bbe88528ddc4388f7059cd18d5 100644 (file)
@@ -182,6 +182,8 @@ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage wi
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
 set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
 set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
+set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
 set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
 set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
 set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
index 07d4c6c723c83c83ea65f3e08ba6543a03a849e8..07b38e830a8f988235a1ba0306db0c488f8c21f3 100644 (file)
@@ -182,6 +182,8 @@ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage wi
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
 set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
 set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
+set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
 set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
 set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
 set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
index 3bc87d607c34a08143d71700a183ea4f348f2383..ddc40e288eda5c3a8aaa18e47b96ac2f9772236b 100644 (file)
@@ -182,6 +182,8 @@ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage wi
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
 set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
 set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
+set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
 set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
 set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
 set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
index a99044add9757a9e03474911c400b3ef0d6badde..e0aa8b08270ddd73312518916661e2db0fb101cb 100644 (file)
@@ -182,6 +182,8 @@ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage wi
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
 set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
 set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
+set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
 set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
 set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
 set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
index f39e8eaa45d60944cd141001484ad97452931d58..e8bd4432162f947c541b737d80c732cec61e2f37 100644 (file)
@@ -106,7 +106,7 @@ void Draw_GrapplingHook(entity this)
                                case NUM_TEAM_2: tex = "particles/hook_blue"; rgb = '0.3 0.3 1'; break;
                                case NUM_TEAM_3: tex = "particles/hook_yellow"; rgb = '1 1 0.3'; break;
                                case NUM_TEAM_4: tex = "particles/hook_pink"; rgb = '1 0.3 1'; break;
-                               default: tex = "particles/hook_white"; rgb = getcsqcplayercolor(self.sv_entnum); break;
+                               default: tex = "particles/hook_white"; rgb = getcsqcplayercolor(self.sv_entnum - 1); break;
                        }
                        break;
                case NET_ENT_CLIENT_ARC_BEAM: // todo
index 7762d16c03706cfb6791238a11867674fbe92214..764a526b9b950e91c8ca847ad27a0862f4f22828 100644 (file)
@@ -150,9 +150,6 @@ float current_player;
 
 float stringwidth_colors(string s, vector theSize);
 float stringwidth_nocolors(string s, vector theSize);
-float GetPlayerColorForce(int i);
-int GetPlayerColor(int i);
-string GetPlayerName(int i);
 void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float length_ratio, bool vertical, float baralign, vector theColor, float theAlpha, int drawflag);
 
 .int panel_showflags;
index bbe0722fd7dad9464b9a8df5a3d1ceb7537d3059..673cf00f1bf8bb1666636b34477bd60cef16bc5e 100644 (file)
@@ -482,27 +482,6 @@ void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector
        }
 }
 
-// TODO: entcs
-float getplayeralpha(int pl)
-{
-       entity e = CSQCModel_server2csqc(pl + 1);
-       return (e) ? e.alpha : 1;
-}
-
-// TODO: entcs
-vector getcsqcplayercolor(int pl)
-{
-       entity e = CSQCModel_server2csqc(pl);
-       return (e && e.colormap > 0) ? colormapPaletteColor(((e.colormap >= 1024) ? e.colormap : stof(getplayerkeyvalue(e.colormap - 1, "colors"))) & 0x0F, true) : '1 1 1';
-}
-
-// TODO: entcs
-bool getplayerisdead(int pl)
-{
-       entity e = CSQCModel_server2csqc(pl + 1);
-       return e ? e.csqcmodel_isdead : false;
-}
-
 /** engine callback */
 void URI_Get_Callback(int id, float status, string data)
 {
index 520b5e47de7196597d7bae4a198d7b7b741de665..ddac22e8dab42c07f560372bd795ee0e4cf564cf 100644 (file)
@@ -35,8 +35,6 @@ float PreviewExists(string name);
 vector rotate(vector v, float a);
 
 
-string ColorTranslateRGB(string s);
-
 // decolorizes and team colors the player name when needed
 string playername(string thename, float teamid);
 
@@ -143,12 +141,6 @@ void PolyDrawModel(entity e);
 
 void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag);
 
-float getplayeralpha(float pl);
-
-vector getcsqcplayercolor(float pl);
-
-float getplayerisdead(float pl);
-
 const int MAX_ACCURACY_LEVELS = 10;
 float acc_lev[MAX_ACCURACY_LEVELS];
 vector acc_col[MAX_ACCURACY_LEVELS];
index baaba14aef2a0f6d5607f688f1d79192486f4d0c..937e3170b56e8368181906ab2851994b23786f59 100644 (file)
@@ -88,17 +88,6 @@ MUTATOR_HOOKABLE(ClearModelParams, EV_NO_ARGS);
 string checkmodel_input, checkmodel_command;
 MUTATOR_HOOKABLE(GetModelParams, EV_GetModelParams);
 
-/** called when a player presses the jump key */
-#define EV_PlayerJump(i, o) \
-       /**/ i(float, player_multijump) \
-       /**/ i(float, player_jumpheight) \
-       /**/ o(float, player_multijump) \
-       /**/ o(float, player_jumpheight) \
-       /**/
-float player_multijump;
-float player_jumpheight;
-MUTATOR_HOOKABLE(PlayerJump, EV_PlayerJump);
-
 /** Called checking if 3rd person mode should be forced on */
 #define EV_WantEventchase(i, o) \
        /** entity id */ i(entity, __self) \
index 965e98068b49678439e74b030955cac3e5b9a6e6..655e7290412262c8611472f43f75d71f2fcfad03 100644 (file)
@@ -303,8 +303,8 @@ void Cmd_HUD_Help()
 
 #define HUD_DefaultColumnLayout() \
 "ping pl name | " \
-"-teams,rc,lms/kills +ft,tdm/kills -teams,lms/deaths +ft,tdm/deaths -teams,lms,rc,ka/suicides +ft,tdm/suicides -rc,dm,tdm,ka,ft/frags " /* tdm already has this in "score" */ \
-"dmg dmgtaken " \
+"-teams,cts,lms/kills +ft,tdm/kills -teams,lms/deaths +ft,tdm/deaths -teams,lms,rc,ka/suicides +ft,tdm/suicides -cts,dm,tdm,ka,ft/frags " /* tdm already has this in "score" */ \
+"-rc,cts,nb/dmg -rc,cts,nb/dmgtaken " \
 "+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns +ons/caps +ons/takes " \
 "+lms/lives +lms/rank " \
 "+kh/caps +kh/pushes +kh/destroyed " \
index 6bcd343b9626e1528781c37573d3bfd99159d19e..f13efdde050df357b3f98e3f14d74b56e1624bf4 100644 (file)
 // self.pointtime = last time you pointed at this player
 // self.csqcmodel_isdead = value of csqcmodel_isdead to know when the player is dead or not
 
+LinkedList shownames_ent;
+STATIC_INIT(shownames_ent)
+{
+       shownames_ent = LL_NEW();
+       for (int i = 0; i < maxclients; ++i)
+       {
+               entity e = new(shownames_tag);
+               e.sv_entnum = i + 1;
+               LL_PUSH(shownames_ent, e);
+       }
+}
+
 const float SHOWNAMES_FADESPEED = 4;
 const float SHOWNAMES_FADEDELAY = 0.4;
 void Draw_ShowNames(entity this)
@@ -41,19 +53,17 @@ void Draw_ShowNames(entity this)
        if (autocvar_hud_shownames_antioverlap)
        {
                // fade tag out if another tag that is closer to you overlaps
-               for (entity e = world; (e = find(e, classname, "shownames_tag")); )
-               {
-                       if (e == this) continue;
-                       vector eo = project_3d_to_2d(e.origin);
+               LL_EACH(shownames_ent, it != this && entcs_receiver(i), LAMBDA(
+                       vector eo = project_3d_to_2d(it.origin);
                        if (eo.z < 0 || eo.x < 0 || eo.y < 0 || eo.x > vid_conwidth || eo.y > vid_conheight) continue;
                        eo.z = 0;
                        if (vlen((eX * o.x + eY * o.y) - eo) < autocvar_hud_shownames_antioverlap_distance
-                           && dist > vlen(e.origin - view_origin))
+                           && dist > vlen(it.origin - view_origin))
                        {
                                overlap = true;
                                break;
                        }
-               }
+               ));
        }
        bool onscreen = (o.z >= 0 && o.x >= 0 && o.y >= 0 && o.x <= vid_conwidth && o.y <= vid_conheight);
        float crosshairdistance = sqrt(pow(o.x - vid_conwidth / 2, 2) + pow(o.y - vid_conheight / 2, 2));
@@ -152,18 +162,6 @@ void Draw_ShowNames(entity this)
        }
 }
 
-LinkedList shownames_ent;
-STATIC_INIT(shownames_ent)
-{
-       shownames_ent = LL_NEW();
-       for (int i = 0; i < maxclients; ++i)
-       {
-               entity e = new(shownames_tag);
-               e.sv_entnum = i + 1;
-               LL_PUSH(shownames_ent, e);
-       }
-}
-
 void Draw_ShowNames_All()
 {
        if (!autocvar_hud_shownames) return;
index e0244d4bf982d4b927b5a4386a8d6d65f0081745..1591bad96b5ccba33b54f72a29acbb93cf1bad3f 100644 (file)
@@ -65,14 +65,14 @@ void Projectile_Draw(entity this)
        {
                // self.move_flags &= ~FL_ONGROUND;
                if (self.move_movetype == MOVETYPE_NONE || self.move_movetype == MOVETYPE_FLY)
-                       Movetype_Physics_NoMatchServer();
+                       Movetype_Physics_NoMatchServer(self);
                // 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(autocvar_cl_projectiles_sloppy);
+                       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);
index 066f48517eff63b64d31b4c4fda8aa7e2e64403e..d86efb5e979f7bf81ba8b44c2a049a6a8c609d38 100644 (file)
@@ -62,7 +62,8 @@
        CSQCMODEL_PROPERTY(BIT(11), int, ReadByte, WriteByte, traileffect) \
        CSQCMODEL_PROPERTY_SCALED(BIT(12), float, ReadByte, WriteByte, scale, 16, 0, 255) \
        CSQCMODEL_PROPERTY(BIT(13), int, ReadInt24_t, WriteInt24_t, dphitcontentsmask) \
-       CSQCMODEL_PROPERTY(BIT(14), TAG_VIEWLOC_TYPE, ReadShort, WriteEntity, TAG_VIEWLOC_NAME)
+       CSQCMODEL_PROPERTY(BIT(14), TAG_VIEWLOC_TYPE, ReadShort, WriteEntity, TAG_VIEWLOC_NAME) \
+       CSQCMODEL_PROPERTY(BIT(15), int, ReadByte, WriteByte, multijump_count)
 // TODO get rid of colormod/glowmod here, find good solution for vortex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody
 
 // add hook function calls here
index 815555df6a500977ec362fee09255f302974dec4..7393217891139454e6848872f4f54937bac3cc1d 100644 (file)
@@ -52,7 +52,7 @@ void Casing_Draw(entity this)
         self.flags &= ~FL_ONGROUND;
     }
 
-    Movetype_Physics_MatchTicrate(autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
+    Movetype_Physics_MatchTicrate(self, autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
     if (wasfreed(self))
         return; // deleted by touch function
 
index ab8dbb8ccf23c85002afaae76f13aad9bcb43fd2..3c778b52ba363feab38f4edfdcdf8e2dfacc181a 100644 (file)
@@ -137,7 +137,7 @@ void Gib_Draw(entity this)
        vector oldorg;
        oldorg = self.origin;
 
-       Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
+       Movetype_Physics_MatchTicrate(self, autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
        if(wasfreed(self))
                return;
 
index 0098dbc5ea2cf26eb63109298443850c8b2cff15..c07fad0d5242fc08dc7a9e1c26b1d79d98c6bee3 100644 (file)
@@ -52,7 +52,7 @@
        bool entcs_send(entity this, entity to, int sf)
        {
                entity player = this.owner;
-               sf |= 1;
+               sf |= BIT(0) | BIT(1);
                if (IS_PLAYER(to) || to.caplayer)                                  // unless spectating,
                {
                        bool same_team = (to == player) || (teamplay && player.team == to.team);
        {
                SELFPARAM();
                this.nextthink = time;
-               entity e = CSQCModel_server2csqc(this.sv_entnum + 1);
+               entity e = CSQCModel_server2csqc(this.sv_entnum);
                bool exists = e != NULL;
                if (exists)
                {
                InterpolateOrigin_Undo(this);
                int sf = ReadShort();
                this.has_sv_origin = false;
-               this.m_entcs_private = boolean(sf & 1);
+               this.m_entcs_private = boolean(sf & BIT(0));
                int i = 1;
                #define X(public, fld, sv, cl) { if (sf & BIT(i)) cl; } i += 1;
                ENTCS_NETPROPS(X);
index 6d9685c4be8dbe86eab14157456166b1ccc3812e..7f773527b073f34b85907ee481e4442bd38f28fd 100644 (file)
@@ -11,7 +11,7 @@ REGISTER_NET_LINKED(ENT_CLIENT_ENTCS)
 .bool has_sv_origin;
 
 #ifdef SVQC
-/**
+/*
  * The point of these entities is to avoid the problems
  * with clientprediction.
  * If you add SendEntity to players, the engine will not
@@ -21,34 +21,105 @@ REGISTER_NET_LINKED(ENT_CLIENT_ENTCS)
  * in onslaught... YAY ;)
  */
 
-.entity entcs;
+       .entity entcs;
 
-bool entcs_send(entity this, entity to, int sf);
+       bool entcs_send(entity this, entity to, int sf);
 
-void entcs_think();
+       void entcs_think();
 
-void entcs_attach(entity e);
+       void entcs_attach(entity e);
 
-void entcs_detach(entity e);
+       void entcs_detach(entity e);
 
-.int m_forceupdate;
+       .int m_forceupdate;
 
 /** Force an origin update, for player sounds */
-#define entcs_force_origin(e) ((e).entcs.m_forceupdate = BIT(2))
+       #define entcs_force_origin(e) ((e).entcs.m_forceupdate = BIT(2))
 
 #endif
 
 #ifdef CSQC
 
-AL_declare(_entcs);
-STATIC_INIT(_entcs)
-{
-    AL_init(_entcs, 255, NULL, e); // 255 is the engine limit on maxclients
-}
-#define entcs_receiver(...) EVAL(OVERLOAD(entcs_receiver, __VA_ARGS__))
-#define entcs_receiver_1(i) AL_gete(_entcs, i)
-#define entcs_receiver_2(i, v) AL_sete(_entcs, i, v)
-#define entcs_is_self(e) ((e).sv_entnum + 1 == player_localentnum)
+       AL_declare(_entcs);
+       STATIC_INIT(_entcs)
+       {
+               AL_init(_entcs, 255, NULL, e);  // 255 is the engine limit on maxclients
+       }
+       SHUTDOWN(_entcs)
+       {
+               AL_delete(_entcs);
+       }
+       #define entcs_receiver(...) EVAL(OVERLOAD(entcs_receiver, __VA_ARGS__))
+       #define entcs_receiver_1(i) AL_gete(_entcs, i)
+       #define entcs_receiver_2(i, v) AL_sete(_entcs, i, v)
+       #define entcs_is_self(e) ((e).sv_entnum == player_localentnum - 1)
+
+       /**
+       * @param i zero indexed player
+       * @returns 0 if not teamplay
+       */
+       int GetPlayerColorForce(int i)
+       {
+               return (!teamplay) ? 0 : stof(getplayerkeyvalue(i, "colors")) & 15;
+       }
+
+       /**
+       * @param i zero indexed player
+       * @returns 0 if not teamplay | NUM_TEAM_##N | NUM_SPECTATOR
+       */
+       int GetPlayerColor(int i)
+       {
+               bool unconnected = !playerslots[i].gotscores;
+               bool spec = unconnected || stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR;
+               return (spec) ? NUM_SPECTATOR : GetPlayerColorForce(i);
+       }
+
+       /**
+       * @param i zero indexed player
+       */
+       string GetPlayerName(int i)
+       {
+               return ColorTranslateRGB(getplayerkeyvalue(i, "name"));
+       }
+
+    /**
+     * @param i zero indexed player
+     */
+       entity CSQCModel_server2csqc(int i);
+
+    .float alpha;
+
+    /**
+     * @param i zero indexed player
+     */
+       float getplayeralpha(int i)
+       {
+               entity e = CSQCModel_server2csqc(i);
+               return e ? e.alpha : 1;
+       }
+
+    /**
+     * @param i zero indexed player
+     */
+       vector getcsqcplayercolor(int i)
+       {
+               entity e = CSQCModel_server2csqc(i);
+               return (!e || e.colormap <= 0)
+                      ? '1 1 1'
+                          : colormapPaletteColor(((e.colormap >= 1024)
+                       ? e.colormap
+                       : stof(getplayerkeyvalue(e.colormap - 1, "colors"))) & 15, true)
+               ;
+       }
+
+    /**
+     * @param i zero indexed player
+     */
+       bool getplayerisdead(int i)
+       {
+               entity e = CSQCModel_server2csqc(i);
+               return e ? e.csqcmodel_isdead : false;
+       }
 
 #endif
 
index 10ee911d95c447dbc093dc676e7cbb895501fcf5..a25a89e7dde125194dedfe8124412ed8bc2edc20 100644 (file)
@@ -38,6 +38,8 @@ REGISTER_WEAPON(SPIDER_ATTACK, NEW(SpiderAttack));
 
 #ifdef SVQC
 
+.float spider_slowness; // effect time of slowness inflicted by spiders
+
 .float spider_web_delay;
 
 float autocvar_g_monster_spider_attack_web_damagetime;
@@ -50,6 +52,41 @@ float autocvar_g_monster_spider_attack_bite_delay;
 
 void M_Spider_Attack_Web();
 
+REGISTER_MUTATOR(spiderweb, true);
+
+MUTATOR_HOOKFUNCTION(spiderweb, PlayerPhysics)
+{
+       if (time >= self.spider_slowness)
+               return false;
+       PHYS_MAXSPEED(self) *= 0.5; // half speed while slow from spider
+       PHYS_MAXAIRSPEED(self) *= 0.5;
+       PHYS_AIRSPEEDLIMIT_NONQW(self) *= 0.5;
+       PHYS_AIRSTRAFEACCELERATE(self) *= 0.5;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(spiderweb, MonsterMove)
+{
+       if(time < self.spider_slowness)
+       {
+               monster_speed_run *= 0.5;
+               monster_speed_walk *= 0.5;
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(spiderweb, PlayerSpawn)
+{
+       self.spider_slowness = 0;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(spiderweb, MonsterSpawn)
+{
+       self.spider_slowness = 0;
+       return false;
+}
+
 SOUND(SpiderAttack_FIRE, W_Sound("electro_fire"));
 METHOD(SpiderAttack, wr_think, void(SpiderAttack thiswep, entity actor, .entity weaponentity, int fire)) {
     bool isPlayer = IS_PLAYER(actor);
index 7ee3e3eab72d84228fe2360e7d46a8137ede8fe1..45fc349275768074459f11407fd5ccc94269b27f 100644 (file)
@@ -806,12 +806,6 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed)
        runspeed = bound(0, monster_speed_run * MONSTER_SKILLMOD(self), runspeed * 2.5); // limit maxspeed to prevent craziness
        walkspeed = bound(0, monster_speed_walk * MONSTER_SKILLMOD(self), walkspeed * 2.5); // limit maxspeed to prevent craziness
 
-       if(time < self.spider_slowness)
-       {
-               runspeed *= 0.5;
-               walkspeed *= 0.5;
-       }
-
        if(teamplay)
        if(autocvar_g_monsters_teams)
        if(DIFF_TEAM(self.monster_follow, self))
@@ -1358,7 +1352,6 @@ bool Monster_Spawn(int mon_id)
        self.deadflag                   = DEAD_NO;
        self.noalign                    = ((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM));
        self.spawn_time                 = time;
-       self.spider_slowness    = 0;
        self.gravity                    = 1;
        self.monster_moveto             = '0 0 0';
        self.monster_face               = '0 0 0';
index acf94eb7d78ad9f35b80ed1d9777cc0292889439..bad6242bc5954b914ec9a88da1bc3071728849ca 100644 (file)
@@ -33,7 +33,6 @@ int monsters_killed;
 
 // other properties
 .bool monster_attack; // indicates whether an entity can be attacked by monsters
-.float spider_slowness; // effect time of slowness inflicted by spiders
 
 // monster state declarations
 const int MONSTER_MOVE_FOLLOW = 1; // monster will follow if in range, or stand still
index b636772687ebdc66113ffec3ad69fdabe7995082..2d3e24f44c93ec5e8d4f34b0800d806336f2039d 100644 (file)
@@ -1,31 +1,31 @@
-void _Movetype_Physics_Follow() // SV_Physics_Follow
-{SELFPARAM();
-       entity e = self.move_aiment; // TODO: networking?
+void _Movetype_Physics_Follow(entity this) // SV_Physics_Follow
+{
+       entity e = this.move_aiment; // TODO: networking?
 
        // LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects
-       if(self.move_angles == self.move_punchangle)
+       if(this.move_angles == this.move_punchangle)
        {
-               self.move_origin = e.move_origin + self.view_ofs;
+               this.move_origin = e.move_origin + this.view_ofs;
        }
        else
        {
                vector ang, v;
-               ang_x = -self.move_punchangle_x;
-               ang_y = self.move_punchangle_y;
-               ang_z = self.move_punchangle_z;
+               ang_x = -this.move_punchangle_x;
+               ang_y = this.move_punchangle_y;
+               ang_z = this.move_punchangle_z;
                makevectors(ang);
-               v_x = self.view_ofs_x * v_forward_x + self.view_ofs_y * v_right_x + self.view_ofs_z * v_up_x;
-               v_y = self.view_ofs_x * v_forward_y + self.view_ofs_y * v_right_y + self.view_ofs_z * v_up_y;
-               v_z = self.view_ofs_x * v_forward_z + self.view_ofs_y * v_right_z + self.view_ofs_z * v_up_z;
+               v_x = this.view_ofs_x * v_forward_x + this.view_ofs_y * v_right_x + this.view_ofs_z * v_up_x;
+               v_y = this.view_ofs_x * v_forward_y + this.view_ofs_y * v_right_y + this.view_ofs_z * v_up_y;
+               v_z = this.view_ofs_x * v_forward_z + this.view_ofs_y * v_right_z + this.view_ofs_z * v_up_z;
                ang_x = -e.move_angles_x;
                ang_y = e.move_angles_y;
                ang_z = e.move_angles_z;
                makevectors(ang);
-               self.move_origin_x = v_x * v_forward_x + v_y * v_forward_y + v_z * v_forward_z + e.move_origin_x;
-               self.move_origin_x = v_x * v_right_x + v_y * v_right_y + v_z * v_right_z + e.move_origin_y;
-               self.move_origin_x = v_x * v_up_x + v_y * v_up_y + v_z * v_up_z + e.move_origin_z;
+               this.move_origin_x = v_x * v_forward_x + v_y * v_forward_y + v_z * v_forward_z + e.move_origin_x;
+               this.move_origin_x = v_x * v_right_x + v_y * v_right_y + v_z * v_right_z + e.move_origin_y;
+               this.move_origin_x = v_x * v_up_x + v_y * v_up_y + v_z * v_up_z + e.move_origin_z;
        }
 
-       self.move_angles = e.move_angles + self.v_angle;
-       _Movetype_LinkEdict(false);
+       this.move_angles = e.move_angles + this.v_angle;
+       _Movetype_LinkEdict(this, false);
 }
index fb49f93fa522060f6eef259955601e5f027e7d92..dd7a4572fffcb745650101629c9bd9c4c3ffd500 100644 (file)
        #include "../../server/autocvars.qh"
 #endif
 
-void _Movetype_WallFriction(vector stepnormal)  // SV_WallFriction
+void _Movetype_WallFriction(entity this, vector stepnormal)  // SV_WallFriction
 {
        /*float d, i;
        vector into, side;
-       makevectors(self.v_angle);
+       makevectors(this.v_angle);
        d = (stepnormal * v_forward) + 0.5;
 
        if(d < 0)
        {
-           i = (stepnormal * self.move_velocity);
+           i = (stepnormal * this.move_velocity);
            into = i * stepnormal;
-           side = self.move_velocity - into;
-           self.move_velocity_x = side.x * (1 * d);
-           self.move_velocity_y = side.y * (1 * d);
+           side = this.move_velocity - into;
+           this.move_velocity_x = side.x * (1 * d);
+           this.move_velocity_y = side.y * (1 * d);
        }*/
 }
 
 vector planes[MAX_CLIP_PLANES];
-int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float stepheight) // SV_FlyMove
-{SELFPARAM();
+int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnormal, float stepheight) // SV_FlyMove
+{
        int blocked = 0, bumpcount;
        int i, j, numplanes = 0;
        float time_left = dt, grav = 0;
@@ -44,29 +44,29 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step
 
        if(applygravity)
        {
-               self.move_didgravity = 1;
-               grav = dt * (PHYS_ENTGRAVITY(self) ? PHYS_ENTGRAVITY(self) : 1) * PHYS_GRAVITY(this);
+               this.move_didgravity = 1;
+               grav = dt * (PHYS_ENTGRAVITY(this) ? PHYS_ENTGRAVITY(this) : 1) * PHYS_GRAVITY(this);
 
-               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(self.move_flags & FL_ONGROUND))
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND))
                {
                        if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                               self.move_velocity_z -= grav * 0.5;
+                               this.move_velocity_z -= grav * 0.5;
                        else
-                               self.move_velocity_z -= grav;
+                               this.move_velocity_z -= grav;
                }
        }
 
-       original_velocity = primal_velocity = restore_velocity = self.move_velocity;
+       original_velocity = primal_velocity = restore_velocity = this.move_velocity;
 
        for(bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++)
        {
-               if(self.move_velocity == '0 0 0')
+               if(this.move_velocity == '0 0 0')
                        break;
 
-               push = self.move_velocity * time_left;
-               vector prev_origin = self.move_origin;
-               _Movetype_PushEntity(push, true);
-               if(trace_startsolid && self.move_origin != prev_origin)
+               push = this.move_velocity * time_left;
+               vector prev_origin = this.move_origin;
+               _Movetype_PushEntity(this, push, true);
+               if(trace_startsolid && this.move_origin != prev_origin)
                {
                        // we got teleported by a touch function
                        // let's abort the move
@@ -78,7 +78,7 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step
                // abort move if we're stuck in the world (and didn't make it out)
                if(trace_startsolid && trace_allsolid)
                {
-                       self.move_velocity = restore_velocity;
+                       this.move_velocity = restore_velocity;
                        return 3;
                }
 
@@ -101,47 +101,47 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step
                                        trace_ent = world;
                                }
 
-                               self.move_flags |= FL_ONGROUND;
-                               self.move_groundentity = trace_ent;
+                               this.move_flags |= FL_ONGROUND;
+                               this.move_groundentity = trace_ent;
                        }
                }
                else if(stepheight)
                {
                        // step - handle it immediately
-                       vector org = self.move_origin;
+                       vector org = this.move_origin;
                        vector steppush = '0 0 1' * stepheight;
 
-                       _Movetype_PushEntity(steppush, true);
-                       if(trace_startsolid && self.move_origin != org)
+                       _Movetype_PushEntity(this, steppush, true);
+                       if(trace_startsolid && this.move_origin != org)
                        {
                                blocked |= 8;
                                break;
                        }
-                       _Movetype_PushEntity(push, true);
-                       if(trace_startsolid && self.move_origin != org)
+                       _Movetype_PushEntity(this, push, true);
+                       if(trace_startsolid && this.move_origin != org)
                        {
                                blocked |= 8;
                                break;
                        }
                        float trace2_fraction = trace_fraction;
-                       steppush = '0 0 1' * (org_z - self.move_origin_z);
-                       _Movetype_PushEntity(steppush, true);
-                       if(trace_startsolid && self.move_origin != org)
+                       steppush = '0 0 1' * (org_z - this.move_origin_z);
+                       _Movetype_PushEntity(this, steppush, true);
+                       if(trace_startsolid && this.move_origin != org)
                        {
                                blocked |= 8;
                                break;
                        }
 
                        // accept the new position if it made some progress...
-                       if(fabs(self.move_origin_x - org_x) >= 0.03125 || fabs(self.move_origin_y - org_y) >= 0.03125)
+                       if(fabs(this.move_origin_x - org_x) >= 0.03125 || fabs(this.move_origin_y - org_y) >= 0.03125)
                        {
-                               trace_endpos = self.move_origin;
+                               trace_endpos = this.move_origin;
                                time_left *= 1 - trace2_fraction;
                                numplanes = 0;
                                continue;
                        }
                        else
-                               self.move_origin = org;
+                               this.move_origin = org;
                }
                else
                {
@@ -155,7 +155,7 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step
                if(my_trace_fraction >= 0.001)
                {
                        // actually covered some distance
-                       original_velocity = self.move_velocity;
+                       original_velocity = this.move_velocity;
                        numplanes = 0;
                }
 
@@ -165,7 +165,7 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step
                if(numplanes >= MAX_CLIP_PLANES)
                {
                        // this shouldn't really happen
-                       self.move_velocity = '0 0 0';
+                       this.move_velocity = '0 0 0';
                        blocked = 3;
                        break;
                }
@@ -194,14 +194,14 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step
                if(i != numplanes)
                {
                        // go along this plane
-                       self.move_velocity = new_velocity;
+                       this.move_velocity = new_velocity;
                }
                else
                {
                        // go along the crease
                        if(numplanes != 2)
                        {
-                               self.move_velocity = '0 0 0';
+                               this.move_velocity = '0 0 0';
                                blocked = 7;
                                break;
                        }
@@ -213,39 +213,39 @@ int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float step
                        dir.x *= ilength;
                        dir.y *= ilength;
                        dir.z *= ilength;
-                       float d = (dir * self.move_velocity);
-                       self.move_velocity = dir * d;
+                       float d = (dir * this.move_velocity);
+                       this.move_velocity = dir * d;
                }
 
                // if current velocity is against the original velocity,
                // stop dead to avoid tiny occilations in sloping corners
-               if((self.move_velocity * primal_velocity) <= 0)
+               if((this.move_velocity * primal_velocity) <= 0)
                {
-                       self.move_velocity = '0 0 0';
+                       this.move_velocity = '0 0 0';
                        break;
                }
        }
 
        // LordHavoc: this came from QW and allows you to get out of water more easily
-       if(GAMEPLAYFIX_EASIERWATERJUMP && (self.move_flags & FL_WATERJUMP) && !(blocked & 8))
-               self.move_velocity = primal_velocity;
+       if(GAMEPLAYFIX_EASIERWATERJUMP && (this.move_flags & FL_WATERJUMP) && !(blocked & 8))
+               this.move_velocity = primal_velocity;
 
        if(applygravity)
        {
-               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(self.move_flags & FL_ONGROUND))
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(this.move_flags & FL_ONGROUND))
                {
                        if(GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                               self.move_velocity_z -= grav * 0.5f;
+                               this.move_velocity_z -= grav * 0.5f;
                }
        }
 
        return blocked;
 }
 
-void _Movetype_CheckVelocity()  // SV_CheckVelocity
+void _Movetype_CheckVelocity(entity this)  // SV_CheckVelocity
 {
-       // if(vlen(self.move_velocity) < 0.0001)
-       // self.move_velocity = '0 0 0';
+       // if(vlen(this.move_velocity) < 0.0001)
+       // this.move_velocity = '0 0 0';
 }
 
 bool _Movetype_CheckWater(entity ent)  // SV_CheckWater
@@ -315,22 +315,22 @@ void _Movetype_CheckWaterTransition(entity ent)  // SV_CheckWaterTransition
        }
 }
 
-void _Movetype_Impact(entity oth)  // SV_Impact
-{SELFPARAM();
+void _Movetype_Impact(entity this, entity oth)  // SV_Impact
+{
        entity oldother = other;
 
-       if(self.move_touch)
+       if(this.move_touch)
        {
                other = oth;
 
-               self.move_touch();
+               WITH(entity, self, this, this.move_touch());
 
                other = oldother;
        }
 
        if(oth.move_touch)
        {
-               other = self;
+               other = this;
 
                WITH(entity, self, oth, oth.move_touch());
 
@@ -338,15 +338,14 @@ void _Movetype_Impact(entity oth)  // SV_Impact
        }
 }
 
-void _Movetype_LinkEdict_TouchAreaGrid()  // SV_LinkEdict_TouchAreaGrid
-{SELFPARAM();
+void _Movetype_LinkEdict_TouchAreaGrid(entity this)  // SV_LinkEdict_TouchAreaGrid
+{
        entity oldother = other;
 
-       for (entity e = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); e; e = e.chain)
+       for (entity e = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin)); e; e = e.chain)
        {
                if(e.move_touch && boxesoverlap(e.absmin, e.absmax, this.absmin, this.absmax))
                {
-                       setself(e);
                        other = this;
 
                        trace_allsolid = false;
@@ -359,32 +358,31 @@ void _Movetype_LinkEdict_TouchAreaGrid()  // SV_LinkEdict_TouchAreaGrid
                        trace_plane_dist = 0;
                        trace_ent = this;
 
-                       e.move_touch();
+                       WITH(entity, self, e, e.move_touch());
                }
        }
 
        other = oldother;
-       setself(this);
 }
 
-void _Movetype_LinkEdict(bool touch_triggers)  // SV_LinkEdict
-{SELFPARAM();
+void _Movetype_LinkEdict(entity this, bool touch_triggers)  // SV_LinkEdict
+{
        vector mi, ma;
-       if(self.solid == SOLID_BSP)
+       if(this.solid == SOLID_BSP)
        {
                // TODO set the absolute bbox
-               mi = self.mins;
-               ma = self.maxs;
+               mi = this.mins;
+               ma = this.maxs;
        }
        else
        {
-               mi = self.mins;
-               ma = self.maxs;
+               mi = this.mins;
+               ma = this.maxs;
        }
-       mi += self.move_origin;
-       ma += self.move_origin;
+       mi += this.move_origin;
+       ma += this.move_origin;
 
-       if(self.move_flags & FL_ITEM)
+       if(this.move_flags & FL_ITEM)
        {
                mi.x -= 15;
                mi.y -= 15;
@@ -403,53 +401,53 @@ void _Movetype_LinkEdict(bool touch_triggers)  // SV_LinkEdict
                ma.z += 1;
        }
 
-       self.absmin = mi;
-       self.absmax = ma;
+       this.absmin = mi;
+       this.absmax = ma;
 
        if(touch_triggers)
-               _Movetype_LinkEdict_TouchAreaGrid();
+               _Movetype_LinkEdict_TouchAreaGrid(this);
 }
 
-bool _Movetype_TestEntityPosition(vector ofs)  // SV_TestEntityPosition
-{SELFPARAM();
-//     vector org = self.move_origin + ofs;
+bool _Movetype_TestEntityPosition(entity this, vector ofs)  // SV_TestEntityPosition
+{
+//     vector org = this.move_origin + ofs;
 
-       int cont = self.dphitcontentsmask;
-       self.dphitcontentsmask = DPCONTENTS_SOLID;
-       tracebox(self.move_origin, self.mins, self.maxs, self.move_origin, MOVE_NOMONSTERS, self);
-       self.dphitcontentsmask = cont;
+       int cont = this.dphitcontentsmask;
+       this.dphitcontentsmask = DPCONTENTS_SOLID;
+       tracebox(this.move_origin, this.mins, this.maxs, this.move_origin, MOVE_NOMONSTERS, this);
+       this.dphitcontentsmask = cont;
 
        if(trace_startsolid)
                return true;
 
-       if(vlen(trace_endpos - self.move_origin) > 0.0001)
-               self.move_origin = trace_endpos;
+       if(vlen(trace_endpos - this.move_origin) > 0.0001)
+               this.move_origin = trace_endpos;
        return false;
 }
 
-bool _Movetype_UnstickEntity()  // SV_UnstickEntity
-{SELFPARAM();
-       if(!_Movetype_TestEntityPosition('0 0 0')) return true;
-       if(!_Movetype_TestEntityPosition('-1 0 0')) goto success;
-       if(!_Movetype_TestEntityPosition('1 0 0')) goto success;
-       if(!_Movetype_TestEntityPosition('0 -1 0')) goto success;
-       if(!_Movetype_TestEntityPosition('0 1 0')) goto success;
-       if(!_Movetype_TestEntityPosition('-1 -1 0')) goto success;
-       if(!_Movetype_TestEntityPosition('1 -1 0')) goto success;
-       if(!_Movetype_TestEntityPosition('-1 1 0')) goto success;
-       if(!_Movetype_TestEntityPosition('1 1 0')) goto success;
+bool _Movetype_UnstickEntity(entity this)  // SV_UnstickEntity
+{
+       if(!_Movetype_TestEntityPosition(this, '0 0 0')) return true;
+       if(!_Movetype_TestEntityPosition(this, '-1 0 0')) goto success;
+       if(!_Movetype_TestEntityPosition(this, '1 0 0')) goto success;
+       if(!_Movetype_TestEntityPosition(this, '0 -1 0')) goto success;
+       if(!_Movetype_TestEntityPosition(this, '0 1 0')) goto success;
+       if(!_Movetype_TestEntityPosition(this, '-1 -1 0')) goto success;
+       if(!_Movetype_TestEntityPosition(this, '1 -1 0')) goto success;
+       if(!_Movetype_TestEntityPosition(this, '-1 1 0')) goto success;
+       if(!_Movetype_TestEntityPosition(this, '1 1 0')) goto success;
        for (int i = 1; i <= 17; ++i)
        {
-               if(!_Movetype_TestEntityPosition('0 0 -1' * i)) goto success;
-               if(!_Movetype_TestEntityPosition('0 0 1' * i)) goto success;
+               if(!_Movetype_TestEntityPosition(this, '0 0 -1' * i)) goto success;
+               if(!_Movetype_TestEntityPosition(this, '0 0 1' * i)) goto success;
        }
        LOG_TRACEF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n",
-               num_for_edict(self), self.classname, vtos(self.move_origin));
+               num_for_edict(this), this.classname, vtos(this.move_origin));
        return false;
        : success;
        LOG_TRACEF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n",
-               num_for_edict(self), self.classname, vtos(self.move_origin));
-       _Movetype_LinkEdict(true);
+               num_for_edict(this), this.classname, vtos(this.move_origin));
+       _Movetype_LinkEdict(this, true);
        return true;
 }
 
@@ -464,34 +462,34 @@ vector _Movetype_ClipVelocity(vector vel, vector norm, float f)  // SV_ClipVeloc
        return vel;
 }
 
-void _Movetype_PushEntityTrace(vector push)
-{SELFPARAM();
-       vector end = self.move_origin + push;
+void _Movetype_PushEntityTrace(entity this, vector push)
+{
+       vector end = this.move_origin + push;
        int type;
-       if(self.move_nomonsters)
-               type = max(0, self.move_nomonsters);
-       else if(self.move_movetype == MOVETYPE_FLYMISSILE)
+       if(this.move_nomonsters)
+               type = max(0, this.move_nomonsters);
+       else if(this.move_movetype == MOVETYPE_FLYMISSILE)
                type = MOVE_MISSILE;
-       else if(self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
+       else if(this.solid == SOLID_TRIGGER || this.solid == SOLID_NOT)
                type = MOVE_NOMONSTERS;
        else
                type = MOVE_NORMAL;
 
-       tracebox(self.move_origin, self.mins, self.maxs, end, type, self);
+       tracebox(this.move_origin, this.mins, this.maxs, end, type, this);
 }
 
-float _Movetype_PushEntity(vector push, bool failonstartsolid)  // SV_PushEntity
-{SELFPARAM();
-       _Movetype_PushEntityTrace(push);
+float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid)  // SV_PushEntity
+{
+       _Movetype_PushEntityTrace(this, push);
 
        if(trace_startsolid && failonstartsolid)
                return trace_fraction;
 
-       self.move_origin = trace_endpos;
+       this.move_origin = trace_endpos;
 
        if(trace_fraction < 1)
-               if(self.solid >= SOLID_TRIGGER && (!(self.move_flags & FL_ONGROUND) || (self.move_groundentity != trace_ent)))
-                       _Movetype_Impact(trace_ent);
+               if(this.solid >= SOLID_TRIGGER && (!(this.move_flags & FL_ONGROUND) || (this.move_groundentity != trace_ent)))
+                       _Movetype_Impact(this, trace_ent);
 
        return trace_fraction;
 }
@@ -554,121 +552,121 @@ void makevectors_matrix(vector myangles)  // AngleVectorsFLU
        }
 }
 
-void _Movetype_Physics_Frame(float movedt)
-{SELFPARAM();
-       self.move_didgravity = -1;
-       switch (self.move_movetype)
+void _Movetype_Physics_Frame(entity this, float movedt)
+{
+       this.move_didgravity = -1;
+       switch (this.move_movetype)
        {
                case MOVETYPE_PUSH:
                case MOVETYPE_FAKEPUSH:
-                       _Movetype_Physics_Pusher(movedt);
+                       _Movetype_Physics_Pusher(this, movedt);
                        break;
                case MOVETYPE_NONE:
                        break;
                case MOVETYPE_FOLLOW:
-                       _Movetype_Physics_Follow();
+                       _Movetype_Physics_Follow(this);
                        break;
                case MOVETYPE_NOCLIP:
-                       _Movetype_CheckWater(self);
-                       self.move_origin = self.move_origin + TICRATE * self.move_velocity;
-                       self.move_angles = self.move_angles + TICRATE * self.move_avelocity;
-                       _Movetype_LinkEdict(false);
+                       _Movetype_CheckWater(this);
+                       this.move_origin = this.move_origin + TICRATE * this.move_velocity;
+                       this.move_angles = this.move_angles + TICRATE * this.move_avelocity;
+                       _Movetype_LinkEdict(this, false);
                        break;
                case MOVETYPE_STEP:
-                       _Movetype_Physics_Step(movedt);
+                       _Movetype_Physics_Step(this, movedt);
                        break;
                case MOVETYPE_WALK:
-                       _Movetype_Physics_Walk(movedt);
+                       _Movetype_Physics_Walk(this, movedt);
                        break;
                case MOVETYPE_TOSS:
                case MOVETYPE_BOUNCE:
                case MOVETYPE_BOUNCEMISSILE:
                case MOVETYPE_FLYMISSILE:
                case MOVETYPE_FLY:
-                       _Movetype_Physics_Toss(movedt);
+                       _Movetype_Physics_Toss(this, movedt);
                        break;
        }
 }
 
-void Movetype_Physics_NoMatchServer()  // optimized
-{SELFPARAM();
-       float movedt = time - self.move_time;
-       self.move_time = time;
+void Movetype_Physics_NoMatchServer(entity this)  // optimized
+{
+       float movedt = time - this.move_time;
+       this.move_time = time;
 
-       _Movetype_Physics_Frame(movedt);
-       if(wasfreed(self))
+       _Movetype_Physics_Frame(this, movedt);
+       if(wasfreed(this))
                return;
 
-       self.avelocity = self.move_avelocity;
-       self.velocity = self.move_velocity;
-       self.angles = self.move_angles;
-       setorigin(self, self.move_origin);
+       this.avelocity = this.move_avelocity;
+       this.velocity = this.move_velocity;
+       this.angles = this.move_angles;
+       setorigin(this, this.move_origin);
 }
 
-void Movetype_Physics_MatchServer(bool sloppy)
+void Movetype_Physics_MatchServer(entity this, bool sloppy)
 {
-       Movetype_Physics_MatchTicrate(TICRATE, sloppy);
+       Movetype_Physics_MatchTicrate(this, TICRATE, sloppy);
 }
 
-void Movetype_Physics_MatchTicrate(float tr, bool sloppy)  // SV_Physics_Entity
-{SELFPARAM();
+void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Physics_Entity
+{
        if(tr <= 0)
        {
-               Movetype_Physics_NoMatchServer();
+               Movetype_Physics_NoMatchServer(this);
                return;
        }
 
-       float dt = time - self.move_time;
+       float dt = time - this.move_time;
 
        int n = max(0, floor(dt / tr));
        dt -= n * tr;
-       self.move_time += n * tr;
+       this.move_time += n * tr;
 
-       if(!self.move_didgravity)
-               self.move_didgravity = ((self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS) && !(self.move_flags & FL_ONGROUND));
+       if(!this.move_didgravity)
+               this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.move_flags & FL_ONGROUND));
 
        for (int i = 0; i < n; ++i)
        {
-               _Movetype_Physics_Frame(tr);
-               if(wasfreed(self))
+               _Movetype_Physics_Frame(this, tr);
+               if(wasfreed(this))
                        return;
        }
 
-       self.avelocity = self.move_avelocity;
+       this.avelocity = this.move_avelocity;
 
-       if(dt > 0 && self.move_movetype != MOVETYPE_NONE && !(self.move_flags & FL_ONGROUND))
+       if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.move_flags & FL_ONGROUND))
        {
                // now continue the move from move_time to time
-               self.velocity = self.move_velocity;
+               this.velocity = this.move_velocity;
 
-               if(self.move_didgravity > 0)
+               if(this.move_didgravity > 0)
                {
-                       self.velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
+                       this.velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
                            * dt
-                           * (self.gravity ? self.gravity : 1)
+                           * (this.gravity ? this.gravity : 1)
                            * PHYS_GRAVITY(this);
                }
 
-               self.angles = self.move_angles + dt * self.avelocity;
+               this.angles = this.move_angles + dt * this.avelocity;
 
-               if(sloppy || self.move_movetype == MOVETYPE_NOCLIP)
+               if(sloppy || this.move_movetype == MOVETYPE_NOCLIP)
                {
-                       setorigin(self, self.move_origin + dt * self.velocity);
+                       setorigin(this, this.move_origin + dt * this.velocity);
                }
                else
                {
-                       _Movetype_PushEntityTrace(dt * self.velocity);
+                       _Movetype_PushEntityTrace(this, dt * this.velocity);
                        if(!trace_startsolid)
-                               setorigin(self, trace_endpos);
+                               setorigin(this, trace_endpos);
                }
 
-               if(self.move_didgravity > 0 && GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       self.velocity_z -= 0.5 * dt * (self.gravity ? self.gravity : 1) * PHYS_GRAVITY(this);
+               if(this.move_didgravity > 0 && GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
+                       this.velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
        }
        else
        {
-               self.velocity = self.move_velocity;
-               self.angles = self.move_angles;
-               setorigin(self, self.move_origin);
+               this.velocity = this.move_velocity;
+               this.angles = this.move_angles;
+               setorigin(this, this.move_origin);
        }
 }
index 5f04fc9db2ee92c7b04f66261ceb8f1ae0da2a68..d913c5dc501d7f0ceb3b73a2dfcc2a5a0a7dde9d 100644 (file)
@@ -31,27 +31,27 @@ float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
 .float move_suspendedinair;
 .float move_didgravity;
 
-void _Movetype_WallFriction(vector stepnormal);
-int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float stepheight);
-void _Movetype_CheckVelocity();
+void _Movetype_WallFriction(entity this, vector stepnormal);
+int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnormal, float stepheight);
+void _Movetype_CheckVelocity(entity this);
 void _Movetype_CheckWaterTransition(entity ent);
 float _Movetype_CheckWater(entity ent);
-void _Movetype_LinkEdict_TouchAreaGrid();
-void _Movetype_LinkEdict(float touch_triggers);
-float _Movetype_TestEntityPosition(vector ofs);
-float _Movetype_UnstickEntity();
+void _Movetype_LinkEdict_TouchAreaGrid(entity this);
+void _Movetype_LinkEdict(entity this, float touch_triggers);
+float _Movetype_TestEntityPosition(entity this, vector ofs);
+float _Movetype_UnstickEntity(entity this);
 vector _Movetype_ClipVelocity(vector vel, vector norm, float f);
-void _Movetype_PushEntityTrace(vector push);
-float _Movetype_PushEntity(vector push, float failonstartsolid);
+void _Movetype_PushEntityTrace(entity this, vector push);
+float _Movetype_PushEntity(entity this, vector push, float failonstartsolid);
 void makevectors_matrix(vector myangles);
 
-void Movetype_Physics_MatchTicrate(float tr, bool sloppy);
-void Movetype_Physics_MatchServer(bool sloppy);
-void Movetype_Physics_NoMatchServer();
-void _Movetype_LinkEdict(float touch_triggers);
-void _Movetype_LinkEdict_TouchAreaGrid();
+void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy);
+void Movetype_Physics_MatchServer(entity this, bool sloppy);
+void Movetype_Physics_NoMatchServer(entity this);
+void _Movetype_LinkEdict(entity this, float touch_triggers);
+void _Movetype_LinkEdict_TouchAreaGrid(entity this);
 
-float _Movetype_UnstickEntity();
+float _Movetype_UnstickEntity(entity this);
 
 const int MAX_CLIP_PLANES = 5;
 
index aeb75ded3053773acb45263e9fb46fe86636079b..c45fe5949dfde3360e86f2926e85be585f4f05b6 100644 (file)
@@ -1,12 +1,12 @@
-void _Movetype_PushMove(float dt)  // SV_PushMove
-{SELFPARAM();
-       if (self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0')
+void _Movetype_PushMove(entity this, float dt)  // SV_PushMove
+{
+       if (this.move_velocity == '0 0 0' && this.move_avelocity == '0 0 0')
        {
-               self.move_ltime += dt;
+               this.move_ltime += dt;
                return;
        }
 
-       switch (self.solid)
+       switch (this.solid)
        {
                // LordHavoc: valid pusher types
                case SOLID_BSP:
@@ -17,43 +17,43 @@ void _Movetype_PushMove(float dt)  // SV_PushMove
                // LordHavoc: no collisions
                case SOLID_NOT:
                case SOLID_TRIGGER:
-                       self.move_origin = self.move_origin + dt * self.move_velocity;
-                       self.move_angles = self.move_angles + dt * self.move_avelocity;
-                       self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0));
-                       self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0));
-                       self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0));
-                       self.move_ltime += dt;
-                       _Movetype_LinkEdict(true);
+                       this.move_origin = this.move_origin + dt * this.move_velocity;
+                       this.move_angles = this.move_angles + dt * this.move_avelocity;
+                       this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0));
+                       this.move_angles_y -= 360.0 * floor(this.move_angles.y * (1.0 / 360.0));
+                       this.move_angles_z -= 360.0 * floor(this.move_angles.z * (1.0 / 360.0));
+                       this.move_ltime += dt;
+                       _Movetype_LinkEdict(this, true);
                        return;
                default:
-                       LOG_TRACEF("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid);
+                       LOG_TRACEF("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", this, this.solid);
                        return;
        }
 
-       bool rotated = (self.move_angles * self.move_angles) + (self.move_avelocity * self.move_avelocity) > 0;
+       bool rotated = (this.move_angles * this.move_angles) + (this.move_avelocity * this.move_avelocity) > 0;
 
-       vector move1 = self.move_velocity * dt;
-       vector moveangle = self.move_avelocity * dt;
+       vector move1 = this.move_velocity * dt;
+       vector moveangle = this.move_avelocity * dt;
 
        makevectors_matrix(-moveangle);
 
-//     vector pushorig = self.move_origin;
-//     vector pushang = self.move_angles;
-//     float pushltime = self.move_ltime;
+//     vector pushorig = this.move_origin;
+//     vector pushang = this.move_angles;
+//     float pushltime = this.move_ltime;
 
 // move the pusher to its final position
 
-       self.move_origin = self.move_origin + dt * self.move_velocity;
-       self.move_angles = self.move_angles + dt * self.move_avelocity;
+       this.move_origin = this.move_origin + dt * this.move_velocity;
+       this.move_angles = this.move_angles + dt * this.move_avelocity;
 
-       self.move_ltime += dt;
-       _Movetype_LinkEdict(true);
+       this.move_ltime += dt;
+       _Movetype_LinkEdict(this, true);
 
-       int savesolid = self.solid;
+       int savesolid = this.solid;
 
-       if (self.move_movetype != MOVETYPE_FAKEPUSH)
+       if (this.move_movetype != MOVETYPE_FAKEPUSH)
        {
-               for (entity check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain)
+               for (entity check = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin)); check; check = check.chain)
                {
                        switch (check.move_movetype)
                        {
@@ -67,17 +67,17 @@ void _Movetype_PushMove(float dt)  // SV_PushMove
                                        break;
                        }
 
-                       if (check.owner == self)
+                       if (check.owner == this)
                                continue;
 
-                       if (self.owner == check)
+                       if (this.owner == check)
                                continue;
 
                        vector pivot = check.mins + 0.5 * (check.maxs - check.mins);
                        vector move;
                        if (rotated)
                        {
-                               vector org = (check.move_origin - self.move_origin) + pivot;
+                               vector org = (check.move_origin - this.move_origin) + pivot;
                                vector org2;
                                org2.x = org * v_forward;
                                org2.y = org * v_right;
@@ -93,48 +93,48 @@ void _Movetype_PushMove(float dt)  // SV_PushMove
                        if (check.move_movetype == 32)  // MOVETYPE_PHYSICS
                        {
                                check.move_origin = check.move_origin + move;
-                               WITH(entity, self, check, _Movetype_LinkEdict(true));
+                               WITH(entity, this, check, _Movetype_LinkEdict(this, true));
                                continue;
                        }
 
                        // try moving the contacted entity
-                       self.solid = SOLID_NOT;
+                       this.solid = SOLID_NOT;
                        bool flag;
-                       WITH(entity, self, check, {
-                               flag = _Movetype_PushEntity(move, true);
+                       WITH(entity, this, check, {
+                               flag = _Movetype_PushEntity(this, move, true);
                        });
                        if (!flag)
                        {
                                // entity "check" got teleported
                                check.move_angles_y += trace_fraction * moveangle.y;
-                               self.solid = savesolid;
+                               this.solid = savesolid;
                                continue;  // pushed enough
                        }
                        // FIXME: turn players specially
                        check.move_angles_y += trace_fraction * moveangle.y;
-                       self.solid = savesolid;
+                       this.solid = savesolid;
 
                        // this trace.fraction < 1 check causes items to fall off of pushers
                        // if they pass under or through a wall
                        // the groundentity check causes items to fall off of ledges
-                       if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != self))
+                       if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != this))
                                check.move_flags &= ~FL_ONGROUND;
                }
        }
 
-       self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0));
-       self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0));
-       self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0));
+       this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0));
+       this.move_angles_y -= 360.0 * floor(this.move_angles.y * (1.0 / 360.0));
+       this.move_angles_z -= 360.0 * floor(this.move_angles.z * (1.0 / 360.0));
 }
 
-void _Movetype_Physics_Pusher(float dt)  // SV_Physics_Pusher
-{SELFPARAM();
-       float oldltime = self.move_ltime;
-       float thinktime = self.move_nextthink;
+void _Movetype_Physics_Pusher(entity this, float dt)  // SV_Physics_Pusher
+{
+       float oldltime = this.move_ltime;
+       float thinktime = this.move_nextthink;
        float movetime;
-       if (thinktime < self.move_ltime + dt)
+       if (thinktime < this.move_ltime + dt)
        {
-               movetime = thinktime - self.move_ltime;
+               movetime = thinktime - this.move_ltime;
                if (movetime < 0)
                        movetime = 0;
        }
@@ -144,15 +144,14 @@ void _Movetype_Physics_Pusher(float dt)  // SV_Physics_Pusher
        }
 
        if (movetime)
-               // advances self.move_ltime if not blocked
-               _Movetype_PushMove(movetime);
+               // advances this.move_ltime if not blocked
+               _Movetype_PushMove(this, movetime);
 
-       if (thinktime > oldltime && thinktime <= self.move_ltime)
+       if (thinktime > oldltime && thinktime <= this.move_ltime)
        {
-               self.move_nextthink = 0;
-               self.move_time = time;
+               this.move_nextthink = 0;
+               this.move_time = time;
                other = world;
-               if (self.move_think)
-                       self.move_think();
+               WITH(entity, self, this, this.move_think());
        }
 }
index 685982b144b06e8f3e3967bd1de71da0405f857a..d0c8493b732956a6fc060ed3fe1d54292516d0bd 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef MOVETYPE_PUSH_H
 #define MOVETYPE_PUSH_H
 
-void _Movetype_Physics_Pusher(float dt);
+void _Movetype_Physics_Pusher(entity this, float dt);
 
 #endif
index f4884ba27a23a5137af32c369dade827dc06d282..eec9b4c0965d4b27e640bc29441d503625fca5f7 100644 (file)
@@ -1,23 +1,23 @@
-void _Movetype_Physics_Step(float dt) // SV_Physics_Step
-{SELFPARAM();
-       if(self.move_flags & FL_ONGROUND)
+void _Movetype_Physics_Step(entity this, float dt) // SV_Physics_Step
+{
+       if(this.move_flags & FL_ONGROUND)
        {
-               if(self.velocity_z >= (1.0 / 32.0) && UPWARD_VELOCITY_CLEARS_ONGROUND)
+               if(this.velocity_z >= (1.0 / 32.0) && UPWARD_VELOCITY_CLEARS_ONGROUND)
                {
-                       self.move_flags &= ~FL_ONGROUND;
-                       _Movetype_CheckVelocity();
-                       _Movetype_FlyMove(dt, true, '0 0 0', 0);
-                       _Movetype_LinkEdict(true);
+                       this.move_flags &= ~FL_ONGROUND;
+                       _Movetype_CheckVelocity(this);
+                       _Movetype_FlyMove(this, dt, true, '0 0 0', 0);
+                       _Movetype_LinkEdict(this, true);
                }
        }
        else
        {
-               _Movetype_CheckVelocity();
-               _Movetype_FlyMove(dt, true, '0 0 0', 0);
-               _Movetype_LinkEdict(true);
+               _Movetype_CheckVelocity(this);
+               _Movetype_FlyMove(this, dt, true, '0 0 0', 0);
+               _Movetype_LinkEdict(this, true);
 
                // TODO? movetypesteplandevent
        }
 
-       _Movetype_CheckWaterTransition(self);
+       _Movetype_CheckWaterTransition(this);
 }
index 6f18fbf2aa67d511922d3dfce244ef34dba54e55..51d6b6e13c500df41a65c2780f2bb349d6fefac6 100644 (file)
@@ -1,52 +1,52 @@
 #include "../physics.qh"
 
-void _Movetype_Physics_Toss(float dt)  // SV_Physics_Toss
-{SELFPARAM();
-       if (self.move_flags & FL_ONGROUND)
+void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
+{
+       if (this.move_flags & FL_ONGROUND)
        {
-               if (self.move_velocity.z >= 1 / 32)
+               if (this.move_velocity.z >= 1 / 32)
                {
-                       self.move_flags &= ~FL_ONGROUND;
+                       this.move_flags &= ~FL_ONGROUND;
                }
-               else if (!self.move_groundentity)
+               else if (!this.move_groundentity)
                {
                        return;
                }
-               else if (self.move_suspendedinair && wasfreed(self.move_groundentity))
+               else if (this.move_suspendedinair && wasfreed(this.move_groundentity))
                {
-                       self.move_groundentity = world;
+                       this.move_groundentity = world;
                        return;
                }
        }
 
-       self.move_suspendedinair = false;
+       this.move_suspendedinair = false;
 
-       _Movetype_CheckVelocity();
+       _Movetype_CheckVelocity(this);
 
-       if (self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS)
+       if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
        {
-               self.move_didgravity = 1;
-               self.move_velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
+               this.move_didgravity = 1;
+               this.move_velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
                    * dt
-                   * (self.gravity ? self.gravity : 1)
+                   * (this.gravity ? this.gravity : 1)
                    * PHYS_GRAVITY(this);
        }
 
-       self.move_angles = self.move_angles + self.move_avelocity * dt;
+       this.move_angles = this.move_angles + this.move_avelocity * dt;
 
        float movetime = dt;
        for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
        {
-               vector move = self.move_velocity * movetime;
-               _Movetype_PushEntity(move, true);
-               if (wasfreed(self))
+               vector move = this.move_velocity * movetime;
+               _Movetype_PushEntity(this, move, true);
+               if (wasfreed(this))
                        return;
 
                if (trace_startsolid)
                {
-                       _Movetype_UnstickEntity();
-                       _Movetype_PushEntity(move, false);
-                       if (wasfreed(self))
+                       _Movetype_UnstickEntity(this);
+                       _Movetype_PushEntity(this, move, false);
+                       if (wasfreed(this))
                                return;
                }
 
@@ -55,61 +55,61 @@ void _Movetype_Physics_Toss(float dt)  // SV_Physics_Toss
 
                movetime *= 1 - min(1, trace_fraction);
 
-               if (self.move_movetype == MOVETYPE_BOUNCEMISSILE)
+               if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
                {
-                       self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 2.0);
-                       self.move_flags &= ~FL_ONGROUND;
+                       this.move_velocity = _Movetype_ClipVelocity(this.move_velocity, trace_plane_normal, 2.0);
+                       this.move_flags &= ~FL_ONGROUND;
                }
-               else if (self.move_movetype == MOVETYPE_BOUNCE)
+               else if (this.move_movetype == MOVETYPE_BOUNCE)
                {
-                       float bouncefac = self.move_bounce_factor;     if (!bouncefac)  bouncefac = 0.5;
-                       float bouncestop = self.move_bounce_stopspeed; if (!bouncestop) bouncestop = 60 / 800;
-                       bouncestop *= (self.gravity ? self.gravity : 1) * PHYS_GRAVITY(this);
+                       float bouncefac = this.move_bounce_factor;     if (!bouncefac)  bouncefac = 0.5;
+                       float bouncestop = this.move_bounce_stopspeed; if (!bouncestop) bouncestop = 60 / 800;
+                       bouncestop *= (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
 
-                       self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1 + bouncefac);
+                       this.move_velocity = _Movetype_ClipVelocity(this.move_velocity, trace_plane_normal, 1 + bouncefac);
 
-                       float d = trace_plane_normal * self.move_velocity;
+                       float d = trace_plane_normal * this.move_velocity;
                        if (trace_plane_normal.z > 0.7 && d < bouncestop && d > -bouncestop)
                        {
-                               self.move_flags |= FL_ONGROUND;
-                               self.move_groundentity = trace_ent;
-                               self.move_velocity = '0 0 0';
-                               self.move_avelocity = '0 0 0';
+                               this.move_flags |= FL_ONGROUND;
+                               this.move_groundentity = trace_ent;
+                               this.move_velocity = '0 0 0';
+                               this.move_avelocity = '0 0 0';
                        }
                        else
                        {
-                               self.move_flags &= ~FL_ONGROUND;
+                               this.move_flags &= ~FL_ONGROUND;
                        }
                }
                else
                {
-                       self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.0);
+                       this.move_velocity = _Movetype_ClipVelocity(this.move_velocity, trace_plane_normal, 1.0);
                        if (trace_plane_normal.z > 0.7)
                        {
-                               self.move_flags |= FL_ONGROUND;
-                               self.move_groundentity = trace_ent;
+                               this.move_flags |= FL_ONGROUND;
+                               this.move_groundentity = trace_ent;
                                if (trace_ent.solid == SOLID_BSP)
-                                       self.move_suspendedinair = true;
-                               self.move_velocity = '0 0 0';
-                               self.move_avelocity = '0 0 0';
+                                       this.move_suspendedinair = true;
+                               this.move_velocity = '0 0 0';
+                               this.move_avelocity = '0 0 0';
                        }
                        else
                        {
-                               self.move_flags &= ~FL_ONGROUND;
+                               this.move_flags &= ~FL_ONGROUND;
                        }
                }
 
                // DP revision 8905 (just, WHY...)
-               if (self.move_movetype == MOVETYPE_BOUNCEMISSILE)
+               if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
                        break;
 
                // DP revision 8918 (WHY...)
-               if (self.move_flags & FL_ONGROUND)
+               if (this.move_flags & FL_ONGROUND)
                        break;
        }
 
-       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && self.move_didgravity > 0 && !(self.move_flags & FL_ONGROUND))
-               self.move_velocity_z -= 0.5 * dt * (self.gravity ? self.gravity : 1) * PHYS_GRAVITY(this);
+       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && this.move_didgravity > 0 && !(this.move_flags & FL_ONGROUND))
+               this.move_velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
 
-       _Movetype_CheckWaterTransition(self);
+       _Movetype_CheckWaterTransition(this);
 }
index 63152e007f6f2ab36a81e912e4f08a26ea3df0ec..cf5cf49bbc99af1ce61c3f5c6a9738ff8f626733 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef MOVETYPE_TOSS_H
 #define MOVETYPE_TOSS_H
 
-void _Movetype_Physics_Toss(float dt);
+void _Movetype_Physics_Toss(entity this, float dt);
 
 #endif
index 0f18a47bfc6ee4bcc487f464ddd6eeb625e615ef..23d6e01a8f0ce7e2790222785c05bd377ee5ab84 100644 (file)
@@ -1,5 +1,5 @@
-void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
-{SELFPARAM();
+void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
+{
        vector stepnormal = '0 0 0';
 
        // if frametime is 0 (due to client sending the same timestamp twice), don't move
@@ -7,61 +7,61 @@ void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
                return;
 
        if (GAMEPLAYFIX_UNSTICKPLAYERS)
-               _Movetype_UnstickEntity();
+               _Movetype_UnstickEntity(this);
 
-       bool applygravity = (!_Movetype_CheckWater(self) && self.move_movetype == MOVETYPE_WALK && !(self.move_flags & FL_WATERJUMP));
+       bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.move_flags & FL_WATERJUMP));
 
-       _Movetype_CheckVelocity();
+       _Movetype_CheckVelocity(this);
 
        // do a regular slide move unless it looks like you ran into a step
-       bool oldonground = (self.move_flags & FL_ONGROUND);
+       bool oldonground = (this.move_flags & FL_ONGROUND);
 
-       vector start_origin = self.move_origin;
-       vector start_velocity = self.move_velocity;
+       vector start_origin = this.move_origin;
+       vector start_velocity = this.move_velocity;
 
-       int clip = _Movetype_FlyMove(dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES ? PHYS_STEPHEIGHT : 0);
+       int clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES ? PHYS_STEPHEIGHT : 0);
 
        if (GAMEPLAYFIX_DOWNTRACEONGROUND && !(clip & 1))
        {
                // only try this if there was no floor in the way in the trace (no,
                // this check seems to be not REALLY necessary, because if clip & 1,
                // our trace will hit that thing too)
-               vector upmove = self.move_origin + '0 0 1';
-               vector downmove = self.move_origin - '0 0 1';
+               vector upmove = this.move_origin + '0 0 1';
+               vector downmove = this.move_origin - '0 0 1';
                int type;
-               if (self.move_movetype == MOVETYPE_FLYMISSILE)
+               if (this.move_movetype == MOVETYPE_FLYMISSILE)
                        type = MOVE_MISSILE;
-               else if (self.move_movetype == MOVETYPE_FLY_WORLDONLY)
+               else if (this.move_movetype == MOVETYPE_FLY_WORLDONLY)
                        type = MOVE_WORLDONLY;
-               else if (self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
+               else if (this.solid == SOLID_TRIGGER || this.solid == SOLID_NOT)
                        type = MOVE_NOMONSTERS;
                else type = MOVE_NORMAL;
-               tracebox(upmove, self.mins, self.maxs, downmove, type, self);
+               tracebox(upmove, this.mins, this.maxs, downmove, type, this);
                if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
                        clip |= 1;  // but we HAVE found a floor
        }
 
        // if the move did not hit the ground at any point, we're not on ground
        if (!(clip & 1))
-               self.move_flags &= ~FL_ONGROUND;
+               this.move_flags &= ~FL_ONGROUND;
 
-       _Movetype_CheckVelocity();
-       _Movetype_LinkEdict(true);
+       _Movetype_CheckVelocity(this);
+       _Movetype_LinkEdict(this, true);
 
        if (clip & 8)  // teleport
                return;
 
-       if (self.move_flags & FL_WATERJUMP)
+       if (this.move_flags & FL_WATERJUMP)
                return;
 
        if (PHYS_NOSTEP)
                return;
 
-       vector originalmove_origin = self.move_origin;
-       vector originalmove_velocity = self.move_velocity;
+       vector originalmove_origin = this.move_origin;
+       vector originalmove_velocity = this.move_velocity;
        // originalmove_clip = clip;
-       int originalmove_flags = self.move_flags;
-       entity originalmove_groundentity = self.move_groundentity;
+       int originalmove_flags = this.move_flags;
+       entity originalmove_groundentity = this.move_groundentity;
 
        // if move didn't block on a step, return
        if (clip & 2)
@@ -70,39 +70,39 @@ void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
                if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125)
                        return;
 
-               if (self.move_movetype != MOVETYPE_FLY)
+               if (this.move_movetype != MOVETYPE_FLY)
                {
                        // return if gibbed by a trigger
-                       if (self.move_movetype != MOVETYPE_WALK)
+                       if (this.move_movetype != MOVETYPE_WALK)
                                return;
 
                        // return if attempting to jump while airborn (unless sv_jumpstep)
                        if (!PHYS_JUMPSTEP)
-                               if (!oldonground && self.move_waterlevel == 0)
+                               if (!oldonground && this.move_waterlevel == 0)
                                        return;
                }
 
                // try moving up and forward to go up a step
                // back to start pos
-               self.move_origin = start_origin;
-               self.move_velocity = start_velocity;
+               this.move_origin = start_origin;
+               this.move_velocity = start_velocity;
 
                // move up
                vector upmove = '0 0 1' * PHYS_STEPHEIGHT;
-               vector prev_origin = self.move_origin;
-               _Movetype_PushEntity(upmove, true);
-               if(wasfreed(self))
+               vector prev_origin = this.move_origin;
+               _Movetype_PushEntity(this, upmove, true);
+               if(wasfreed(this))
                        return;
-               if(trace_startsolid && self.move_origin != prev_origin)
+               if(trace_startsolid && this.move_origin != prev_origin)
                {
                        // we got teleported when upstepping... must abort the move
                        return;
                }
 
                // move forward
-               self.move_velocity_z = 0;
-               clip = _Movetype_FlyMove(dt, applygravity, stepnormal, 0);
-               self.move_velocity_z += start_velocity.z;
+               this.move_velocity_z = 0;
+               clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, 0);
+               this.move_velocity_z += start_velocity.z;
                if (clip & 8)
                {
                        // we got teleported when upstepping... must abort the move
@@ -110,22 +110,22 @@ void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
                        return;
                }
 
-               _Movetype_CheckVelocity();
-               _Movetype_LinkEdict(true);
+               _Movetype_CheckVelocity(this);
+               _Movetype_LinkEdict(this, true);
 
                // check for stuckness, possibly due to the limited precision of floats
                // in the clipping hulls
                if (clip
-                   && fabs(originalmove_origin.y - self.move_origin.y) < 0.03125
-                   && fabs(originalmove_origin.x - self.move_origin.x) < 0.03125)
+                   && fabs(originalmove_origin.y - this.move_origin.y) < 0.03125
+                   && fabs(originalmove_origin.x - this.move_origin.x) < 0.03125)
                {
                        // Con_Printf("wall\n");
                        // stepping up didn't make any progress, revert to original move
-                       self.move_origin = originalmove_origin;
-                       self.move_velocity = originalmove_velocity;
+                       this.move_origin = originalmove_origin;
+                       this.move_velocity = originalmove_velocity;
                        // clip = originalmove_clip;
-                       self.move_flags = originalmove_flags;
-                       self.move_groundentity = originalmove_groundentity;
+                       this.move_flags = originalmove_flags;
+                       this.move_groundentity = originalmove_groundentity;
                        // now try to unstick if needed
                        // clip = SV_TryUnstick (ent, oldvel);
                        return;
@@ -135,22 +135,22 @@ void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
 
                // extra friction based on view angle
                if ((clip & 2) && PHYS_WALLFRICTION)
-                       _Movetype_WallFriction(stepnormal);
+                       _Movetype_WallFriction(this, stepnormal);
        }
        // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
-       else if (!GAMEPLAYFIX_STEPDOWN || self.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (self.move_flags & FL_ONGROUND))
+       else if (!GAMEPLAYFIX_STEPDOWN || this.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (this.move_flags & FL_ONGROUND))
        {
                return;
        }
 
        // move down
        vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT + start_velocity.z * dt);
-       vector prev_origin = self.move_origin;
-       _Movetype_PushEntity(downmove, true);
-       if(wasfreed(self))
+       vector prev_origin = this.move_origin;
+       _Movetype_PushEntity(this, downmove, true);
+       if(wasfreed(this))
                return;
 
-       if(trace_startsolid && self.move_origin != prev_origin)
+       if(trace_startsolid && this.move_origin != prev_origin)
        {
                // we got teleported when downstepping... must abort the move
                return;
@@ -167,12 +167,12 @@ void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
                // if the push down didn't end up on good ground, use the move without
                // the step up.  This happens near wall / slope combinations, and can
                // cause the player to hop up higher on a slope too steep to climb
-               self.move_origin = originalmove_origin;
-               self.move_velocity = originalmove_velocity;
-               self.move_flags = originalmove_flags;
-               self.move_groundentity = originalmove_groundentity;
+               this.move_origin = originalmove_origin;
+               this.move_velocity = originalmove_velocity;
+               this.move_flags = originalmove_flags;
+               this.move_groundentity = originalmove_groundentity;
        }
 
-       _Movetype_CheckVelocity();
-       _Movetype_LinkEdict(true);
+       _Movetype_CheckVelocity(this);
+       _Movetype_LinkEdict(this, true);
 }
index 10493c96f4e93fe9d28521dc7fc26416f5b33342..a920c7a4f831fed875c282b41a362b04c7f2bb30 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef MOVETYPE_WALK_H
 #define MOVETYPE_WALK_H
 
-void _Movetype_Physics_Walk(float dt);
+void _Movetype_Physics_Walk(entity this, float dt);
 
 #endif
index bef00c649e890c2b71cb34a392ae4c9d77542b1a..e99092c660896d524f4c97e268dd8be7bead69b1 100644 (file)
 #include "mutator/bloodloss/module.inc"
 #include "mutator/breakablehook/module.inc"
 #include "mutator/buffs/module.inc"
+#include "mutator/bugrigs/module.inc"
 #include "mutator/campcheck/module.inc"
 #include "mutator/cloaked/module.inc"
 #include "mutator/damagetext/module.inc"
 #include "mutator/dodging/module.inc"
+#include "mutator/doublejump/module.inc"
 #include "mutator/hook/module.inc"
 #include "mutator/instagib/module.inc"
 #include "mutator/invincibleproj/module.inc"
index 82898237c53f38e6a212b62ff4f7089ff348bc5b..ed57753bdece4b34514d6bf241518690967d5853 100644 (file)
@@ -61,4 +61,33 @@ MUTATOR_HOOKABLE(IsFlying, EV_IsFlying);
     /**/
 MUTATOR_HOOKABLE(WP_Format, EV_WP_Format);
 
+/**
+ * called before any player physics, may adjust variables for movement,
+ * is run AFTER bot code and idle checking on the server
+ */
+#define EV_PlayerPhysics(i, o) \
+    /**/ i(entity, __self) \
+    /**/
+MUTATOR_HOOKABLE(PlayerPhysics, EV_PlayerPhysics);
+
+/** called when a player presses the jump key */
+#define EV_PlayerJump(i, o) \
+    /**/ i(entity, __self) \
+    /**/ i(float, player_multijump) \
+    /**/ i(float, player_jumpheight) \
+    /**/ o(float, player_multijump) \
+    /**/ o(float, player_jumpheight) \
+    /**/
+float player_multijump;
+float player_jumpheight;
+MUTATOR_HOOKABLE(PlayerJump, EV_PlayerJump);
+
+/** called during player physics, allows adjusting the movement type used */
+#define EV_PM_Physics(i, o) \
+    /**/ i(entity, __self) \
+    /**/ i(float, pm_maxspeed_mod) \
+    /**/
+float pm_maxspeed_mod;
+MUTATOR_HOOKABLE(PM_Physics, EV_PM_Physics);
+
 #endif
index dbabdd2e2f49bc427b245329c593bf569be42f31..1c9e3a2177b9f3c07f5822392e0232d4d88ba6e7 100644 (file)
@@ -982,7 +982,7 @@ MUTATOR_HOOKFUNCTION(buffs, VehicleEnter)
 {
        vh_vehicle.buffs = vh_player.buffs;
        vh_player.buffs = 0;
-       vh_vehicle.buff_time = vh_player.buff_time - time;
+       vh_vehicle.buff_time = max(0, time - vh_player.buff_time);
        vh_player.buff_time = 0;
        return false;
 }
diff --git a/qcsrc/common/mutators/mutator/bugrigs/bugrigs.qc b/qcsrc/common/mutators/mutator/bugrigs/bugrigs.qc
new file mode 100644 (file)
index 0000000..1943413
--- /dev/null
@@ -0,0 +1,314 @@
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+       #include "../../../../server/antilag.qh"
+#endif
+#include "../../../physics.qh"
+
+
+#if defined(SVQC)
+void bugrigs_SetVars();
+
+REGISTER_MUTATOR(bugrigs, cvar("g_bugrigs"))
+{
+       MUTATOR_ONADD
+       {
+               bugrigs_SetVars();
+       }
+       return false;
+}
+#elif defined(CSQC)
+REGISTER_MUTATOR(bugrigs, true);
+#endif
+
+
+#define PHYS_BUGRIGS(s)                        STAT(BUGRIGS, s)
+#define PHYS_BUGRIGS_ACCEL(s)                  STAT(BUGRIGS_ACCEL, s)
+#define PHYS_BUGRIGS_AIR_STEERING(s)           STAT(BUGRIGS_AIR_STEERING, s)
+#define PHYS_BUGRIGS_ANGLE_SMOOTHING(s)        STAT(BUGRIGS_ANGLE_SMOOTHING, s)
+#define PHYS_BUGRIGS_CAR_JUMPING(s)            STAT(BUGRIGS_CAR_JUMPING, s)
+#define PHYS_BUGRIGS_FRICTION_AIR(s)           STAT(BUGRIGS_FRICTION_AIR, s)
+#define PHYS_BUGRIGS_FRICTION_BRAKE(s)         STAT(BUGRIGS_FRICTION_BRAKE, s)
+#define PHYS_BUGRIGS_FRICTION_FLOOR(s)         STAT(BUGRIGS_FRICTION_FLOOR, s)
+#define PHYS_BUGRIGS_PLANAR_MOVEMENT(s)        STAT(BUGRIGS_PLANAR_MOVEMENT, s)
+#define PHYS_BUGRIGS_REVERSE_SPEEDING(s)       STAT(BUGRIGS_REVERSE_SPEEDING, s)
+#define PHYS_BUGRIGS_REVERSE_SPINNING(s)       STAT(BUGRIGS_REVERSE_SPINNING, s)
+#define PHYS_BUGRIGS_REVERSE_STOPPING(s)       STAT(BUGRIGS_REVERSE_STOPPING, s)
+#define PHYS_BUGRIGS_SPEED_POW(s)              STAT(BUGRIGS_SPEED_POW, s)
+#define PHYS_BUGRIGS_SPEED_REF(s)              STAT(BUGRIGS_SPEED_REF, s)
+#define PHYS_BUGRIGS_STEER(s)                  STAT(BUGRIGS_STEER, s)
+
+#if defined(SVQC)
+
+void bugrigs_SetVars()
+{
+       g_bugrigs = cvar("g_bugrigs");
+       g_bugrigs_planar_movement = cvar("g_bugrigs_planar_movement");
+       g_bugrigs_planar_movement_car_jumping = cvar("g_bugrigs_planar_movement_car_jumping");
+       g_bugrigs_reverse_spinning = cvar("g_bugrigs_reverse_spinning");
+       g_bugrigs_reverse_speeding = cvar("g_bugrigs_reverse_speeding");
+       g_bugrigs_reverse_stopping = cvar("g_bugrigs_reverse_stopping");
+       g_bugrigs_air_steering = cvar("g_bugrigs_air_steering");
+       g_bugrigs_angle_smoothing = cvar("g_bugrigs_angle_smoothing");
+       g_bugrigs_friction_floor = cvar("g_bugrigs_friction_floor");
+       g_bugrigs_friction_brake = cvar("g_bugrigs_friction_brake");
+       g_bugrigs_friction_air = cvar("g_bugrigs_friction_air");
+       g_bugrigs_accel = cvar("g_bugrigs_accel");
+       g_bugrigs_speed_ref = cvar("g_bugrigs_speed_ref");
+       g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
+       g_bugrigs_steer = cvar("g_bugrigs_steer");
+}
+
+#endif
+
+void RaceCarPhysics(entity this)
+{
+       // using this move type for "big rigs"
+       // the engine does not push the entity!
+
+       vector rigvel;
+
+       vector angles_save = this.angles;
+       float accel = bound(-1, this.movement.x / PHYS_MAXSPEED(this), 1);
+       float steer = bound(-1, this.movement.y / PHYS_MAXSPEED(this), 1);
+
+       if (PHYS_BUGRIGS_REVERSE_SPEEDING(this))
+       {
+               if (accel < 0)
+               {
+                       // back accel is DIGITAL
+                       // to prevent speedhack
+                       if (accel < -0.5)
+                               accel = -1;
+                       else
+                               accel = 0;
+               }
+       }
+
+       this.angles_x = 0;
+       this.angles_z = 0;
+       makevectors(this.angles); // new forward direction!
+
+       if (IS_ONGROUND(this) || PHYS_BUGRIGS_AIR_STEERING(this))
+       {
+               float myspeed = this.velocity * v_forward;
+               float upspeed = this.velocity * v_up;
+
+               // responsiveness factor for steering and acceleration
+               float f = 1 / (1 + pow(max(-myspeed, myspeed) / PHYS_BUGRIGS_SPEED_REF(this), PHYS_BUGRIGS_SPEED_POW(this)));
+               //MAXIMA: f(v) := 1 / (1 + (v / PHYS_BUGRIGS_SPEED_REF(this)) ^ PHYS_BUGRIGS_SPEED_POW(this));
+
+               float steerfactor;
+               if (myspeed < 0 && PHYS_BUGRIGS_REVERSE_SPINNING(this))
+                       steerfactor = -myspeed * PHYS_BUGRIGS_STEER(this);
+               else
+                       steerfactor = -myspeed * f * PHYS_BUGRIGS_STEER(this);
+
+               float accelfactor;
+               if (myspeed < 0 && PHYS_BUGRIGS_REVERSE_SPEEDING(this))
+                       accelfactor = PHYS_BUGRIGS_ACCEL(this);
+               else
+                       accelfactor = f * PHYS_BUGRIGS_ACCEL(this);
+               //MAXIMA: accel(v) := f(v) * PHYS_BUGRIGS_ACCEL(this);
+
+               if (accel < 0)
+               {
+                       if (myspeed > 0)
+                       {
+                               myspeed = max(0, myspeed - PHYS_INPUT_TIMELENGTH * (PHYS_BUGRIGS_FRICTION_FLOOR(this) - PHYS_BUGRIGS_FRICTION_BRAKE(this) * accel));
+                       }
+                       else
+                       {
+                               if (!PHYS_BUGRIGS_REVERSE_SPEEDING(this))
+                                       myspeed = min(0, myspeed + PHYS_INPUT_TIMELENGTH * PHYS_BUGRIGS_FRICTION_FLOOR(this));
+                       }
+               }
+               else
+               {
+                       if (myspeed >= 0)
+                       {
+                               myspeed = max(0, myspeed - PHYS_INPUT_TIMELENGTH * PHYS_BUGRIGS_FRICTION_FLOOR(this));
+                       }
+                       else
+                       {
+                               if (PHYS_BUGRIGS_REVERSE_STOPPING(this))
+                                       myspeed = 0;
+                               else
+                                       myspeed = min(0, myspeed + PHYS_INPUT_TIMELENGTH * (PHYS_BUGRIGS_FRICTION_FLOOR(this) + PHYS_BUGRIGS_FRICTION_BRAKE(this) * accel));
+                       }
+               }
+               // terminal velocity = velocity at which 50 == accelfactor, that is, 1549 units/sec
+               //MAXIMA: friction(v) := PHYS_BUGRIGS_FRICTION_FLOOR(this);
+
+               this.angles_y += steer * PHYS_INPUT_TIMELENGTH * steerfactor; // apply steering
+               makevectors(this.angles); // new forward direction!
+
+               myspeed += accel * accelfactor * PHYS_INPUT_TIMELENGTH;
+
+               rigvel = myspeed * v_forward + '0 0 1' * upspeed;
+       }
+       else
+       {
+               float myspeed = vlen(this.velocity);
+
+               // responsiveness factor for steering and acceleration
+               float f = 1 / (1 + pow(max(0, myspeed / PHYS_BUGRIGS_SPEED_REF(this)), PHYS_BUGRIGS_SPEED_POW(this)));
+               float steerfactor = -myspeed * f;
+               this.angles_y += steer * PHYS_INPUT_TIMELENGTH * steerfactor; // apply steering
+
+               rigvel = this.velocity;
+               makevectors(this.angles); // new forward direction!
+       }
+
+       rigvel *= max(0, 1 - vlen(rigvel) * PHYS_BUGRIGS_FRICTION_AIR(this) * PHYS_INPUT_TIMELENGTH);
+       //MAXIMA: airfriction(v) := v * v * PHYS_BUGRIGS_FRICTION_AIR(this);
+       //MAXIMA: total_acceleration(v) := accel(v) - friction(v) - airfriction(v);
+       //MAXIMA: solve(total_acceleration(v) = 0, v);
+
+       if (PHYS_BUGRIGS_PLANAR_MOVEMENT(this))
+       {
+               vector rigvel_xy, neworigin, up;
+               float mt;
+
+               rigvel_z -= PHYS_INPUT_TIMELENGTH * PHYS_GRAVITY(this); // 4x gravity plays better
+               rigvel_xy = vec2(rigvel);
+
+               if (PHYS_BUGRIGS_CAR_JUMPING(this))
+                       mt = MOVE_NORMAL;
+               else
+                       mt = MOVE_NOMONSTERS;
+
+               tracebox(this.origin, this.mins, this.maxs, this.origin + '0 0 1024', mt, this);
+               up = trace_endpos - this.origin;
+
+               // BUG RIGS: align the move to the surface instead of doing collision testing
+               // can we move?
+               tracebox(trace_endpos, this.mins, this.maxs, trace_endpos + rigvel_xy * PHYS_INPUT_TIMELENGTH, mt, this);
+
+               // align to surface
+               tracebox(trace_endpos, this.mins, this.maxs, trace_endpos - up + '0 0 1' * rigvel_z * PHYS_INPUT_TIMELENGTH, mt, this);
+
+               if (trace_fraction < 0.5)
+               {
+                       trace_fraction = 1;
+                       neworigin = this.origin;
+               }
+               else
+                       neworigin = trace_endpos;
+
+               if (trace_fraction < 1)
+               {
+                       // now set angles_x so that the car points parallel to the surface
+                       this.angles = vectoangles(
+                                       '1 0 0' * v_forward_x * trace_plane_normal_z
+                                       +
+                                       '0 1 0' * v_forward_y * trace_plane_normal_z
+                                       +
+                                       '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y)
+                                       );
+                       SET_ONGROUND(this);
+               }
+               else
+               {
+                       // now set angles_x so that the car points forward, but is tilted in velocity direction
+                       UNSET_ONGROUND(this);
+               }
+
+               this.velocity = (neworigin - this.origin) * (1.0 / PHYS_INPUT_TIMELENGTH);
+               this.movetype = MOVETYPE_NOCLIP;
+       }
+       else
+       {
+               rigvel_z -= PHYS_INPUT_TIMELENGTH * PHYS_GRAVITY(this); // 4x gravity plays better
+               this.velocity = rigvel;
+               this.movetype = MOVETYPE_FLY;
+       }
+
+       trace_fraction = 1;
+       tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 4', MOVE_NORMAL, this);
+       if (trace_fraction != 1)
+       {
+               this.angles = vectoangles2(
+                               '1 0 0' * v_forward_x * trace_plane_normal_z
+                               +
+                               '0 1 0' * v_forward_y * trace_plane_normal_z
+                               +
+                               '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y),
+                               trace_plane_normal
+                               );
+       }
+       else
+       {
+               vector vel_local;
+
+               vel_local_x = v_forward * this.velocity;
+               vel_local_y = v_right * this.velocity;
+               vel_local_z = v_up * this.velocity;
+
+               this.angles_x = racecar_angle(vel_local_x, vel_local_z);
+               this.angles_z = racecar_angle(-vel_local_y, vel_local_z);
+       }
+
+       // smooth the angles
+       vector vf1, vu1, smoothangles;
+       makevectors(this.angles);
+       float f = bound(0, PHYS_INPUT_TIMELENGTH * PHYS_BUGRIGS_ANGLE_SMOOTHING(this), 1);
+       if (f == 0)
+               f = 1;
+       vf1 = v_forward * f;
+       vu1 = v_up * f;
+       makevectors(angles_save);
+       vf1 = vf1 + v_forward * (1 - f);
+       vu1 = vu1 + v_up * (1 - f);
+       smoothangles = vectoangles2(vf1, vu1);
+       this.angles_x = -smoothangles_x;
+       this.angles_z =  smoothangles_z;
+
+       PM_ClientMovement_Move(this);
+}
+
+#ifdef SVQC
+.vector bugrigs_prevangles;
+#endif
+MUTATOR_HOOKFUNCTION(bugrigs, PM_Physics)
+{
+       if(!PHYS_BUGRIGS(self) || !IS_PLAYER(self)) { return false; }
+
+#ifdef SVQC
+       self.angles = self.bugrigs_prevangles;
+#endif
+
+       RaceCarPhysics(self);
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(bugrigs, PlayerPhysics)
+{
+       if(!PHYS_BUGRIGS(self)) { return false; }
+#ifdef SVQC
+       self.bugrigs_prevangles = self.angles;
+#endif
+       return false;
+}
+
+#ifdef SVQC
+
+MUTATOR_HOOKFUNCTION(bugrigs, ClientConnect)
+{
+       stuffcmd(self, "cl_cmd settemp chase_active 1\n");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(bugrigs, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":bugrigs");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(bugrigs, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Bug rigs");
+       return false;
+}
+
+#endif
+#endif
diff --git a/qcsrc/common/mutators/mutator/bugrigs/module.inc b/qcsrc/common/mutators/mutator/bugrigs/module.inc
new file mode 100644 (file)
index 0000000..cef744f
--- /dev/null
@@ -0,0 +1,3 @@
+#ifndef MENUQC
+#include "bugrigs.qc"
+#endif
index 4f724cfbf7148af2e51e523eb4ff02d47f99d76b..b25de6125e289f919606522652e0ec1723828f7b 100644 (file)
@@ -54,6 +54,8 @@ REGISTER_MUTATOR(dodging, cvar("g_dodging"))
        return false;
 }
 
+#elif defined(CSQC)
+REGISTER_MUTATOR(dodging, true);
 #endif
 
 // set to 1 to indicate dodging has started.. reset by physics hook after dodge has been done..
@@ -86,13 +88,13 @@ REGISTER_MUTATOR(dodging, cvar("g_dodging"))
 #endif
 
 // returns 1 if the player is close to a wall
-bool check_close_to_wall(float threshold)
-{SELFPARAM();
+bool check_close_to_wall(entity this, float threshold)
+{
        if (PHYS_DODGING_WALL == 0) { return false; }
 
        #define X(OFFSET)                                                                                                                               \
-       tracebox(self.origin, self.mins, self.maxs, self.origin + OFFSET, true, self);  \
-       if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold)                \
+       tracebox(this.origin, this.mins, this.maxs, this.origin + OFFSET, true, this);  \
+       if (trace_fraction < 1 && vlen (this.origin - trace_endpos) < threshold)                \
                return true;
        X(1000*v_right);
        X(-1000*v_right);
@@ -103,41 +105,41 @@ bool check_close_to_wall(float threshold)
        return false;
 }
 
-bool check_close_to_ground(float threshold)
-{SELFPARAM();
-       return IS_ONGROUND(self) ? true : false;
+bool check_close_to_ground(entity this, float threshold)
+{
+       return IS_ONGROUND(this) ? true : false;
 }
 
-float PM_dodging_checkpressedkeys()
-{SELFPARAM();
+float PM_dodging_checkpressedkeys(entity this)
+{
        if(!PHYS_DODGING)
                return false;
 
-       float frozen_dodging = (PHYS_FROZEN(self) && PHYS_DODGING_FROZEN);
+       float frozen_dodging = (PHYS_FROZEN(this) && PHYS_DODGING_FROZEN);
        float frozen_no_doubletap = (frozen_dodging && !PHYS_DODGING_FROZEN_NODOUBLETAP);
 
        // first check if the last dodge is far enough back in time so we can dodge again
-       if ((time - self.last_dodging_time) < PHYS_DODGING_DELAY)
+       if ((time - this.last_dodging_time) < PHYS_DODGING_DELAY)
                return false;
 
-       makevectors(self.angles);
+       makevectors(this.angles);
 
-       if (check_close_to_ground(PHYS_DODGING_HEIGHT_THRESHOLD) != 1
-               && check_close_to_wall(PHYS_DODGING_DISTANCE_THRESHOLD) != 1)
+       if (check_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD) != 1
+               && check_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD) != 1)
                return true;
 
        float tap_direction_x = 0;
        float tap_direction_y = 0;
-       float dodge_detected = 0;
+       bool dodge_detected = false;
 
        #define X(COND,BTN,RESULT)                                                                                                                      \
-       if (self.movement_##COND)                                                                                               \
+       if (this.movement_##COND)                                                                                               \
                /* is this a state change? */                                                                                                   \
-               if(!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_##BTN) || frozen_no_doubletap) {             \
+               if(!(PHYS_DODGING_PRESSED_KEYS(this) & KEY_##BTN) || frozen_no_doubletap) {             \
                                tap_direction_##RESULT;                                                                                                 \
-                               if ((time - self.last_##BTN##_KEY_time) < PHYS_DODGING_TIMEOUT(self))   \
-                                       dodge_detected = 1;                                                                                                     \
-                               self.last_##BTN##_KEY_time = time;                                                                              \
+                               if ((time - this.last_##BTN##_KEY_time) < PHYS_DODGING_TIMEOUT(this))   \
+                                       dodge_detected = true;                                                                                                  \
+                               this.last_##BTN##_KEY_time = time;                                                                              \
                }
        X(x < 0, BACKWARD,      x--);
        X(x > 0, FORWARD,       x++);
@@ -145,49 +147,49 @@ float PM_dodging_checkpressedkeys()
        X(y > 0, RIGHT,         y++);
        #undef X
 
-       if (dodge_detected == 1)
+       if (dodge_detected)
        {
-               self.last_dodging_time = time;
+               this.last_dodging_time = time;
 
-               self.dodging_action = 1;
-               self.dodging_single_action = 1;
+               this.dodging_action = 1;
+               this.dodging_single_action = 1;
 
-               self.dodging_velocity_gain = PHYS_DODGING_HORIZ_SPEED;
+               this.dodging_velocity_gain = PHYS_DODGING_HORIZ_SPEED;
 
-               self.dodging_direction_x = tap_direction_x;
-               self.dodging_direction_y = tap_direction_y;
+               this.dodging_direction_x = tap_direction_x;
+               this.dodging_direction_y = tap_direction_y;
 
                // normalize the dodging_direction vector.. (unlike UT99) XD
-               float length = self.dodging_direction_x * self.dodging_direction_x
-                                       + self.dodging_direction_y * self.dodging_direction_y;
+               float length = this.dodging_direction_x * this.dodging_direction_x
+                                       + this.dodging_direction_y * this.dodging_direction_y;
                length = sqrt(length);
 
-               self.dodging_direction_x = self.dodging_direction_x * 1.0 / length;
-               self.dodging_direction_y = self.dodging_direction_y * 1.0 / length;
+               this.dodging_direction_x = this.dodging_direction_x * 1.0 / length;
+               this.dodging_direction_y = this.dodging_direction_y * 1.0 / length;
                return true;
        }
        return false;
 }
 
-void PM_dodging()
-{SELFPARAM();
+void PM_dodging(entity this)
+{
        if (!PHYS_DODGING)
                return;
 
-    if (PHYS_DEAD(self))
+    if (PHYS_DEAD(this))
         return;
 
        // when swimming, no dodging allowed..
-       if (self.waterlevel >= WATERLEVEL_SWIMMING)
+       if (this.waterlevel >= WATERLEVEL_SWIMMING)
        {
-               self.dodging_action = 0;
-               self.dodging_direction_x = 0;
-               self.dodging_direction_y = 0;
+               this.dodging_action = 0;
+               this.dodging_direction_x = 0;
+               this.dodging_direction_y = 0;
                return;
        }
 
        // make sure v_up, v_right and v_forward are sane
-       makevectors(self.angles);
+       makevectors(this.angles);
 
        // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
        // will be called ramp_time/frametime times = 2 times. so, we need to
@@ -197,74 +199,93 @@ void PM_dodging()
        // if ramp time is smaller than frametime we get problems ;D
        common_factor = min(common_factor, 1);
 
-       float horiz_speed = PHYS_FROZEN(self) ? PHYS_DODGING_HORIZ_SPEED_FROZEN : PHYS_DODGING_HORIZ_SPEED;
-       float new_velocity_gain = self.dodging_velocity_gain - (common_factor * horiz_speed);
+       float horiz_speed = PHYS_FROZEN(this) ? PHYS_DODGING_HORIZ_SPEED_FROZEN : PHYS_DODGING_HORIZ_SPEED;
+       float new_velocity_gain = this.dodging_velocity_gain - (common_factor * horiz_speed);
        new_velocity_gain = max(0, new_velocity_gain);
 
-       float velocity_difference = self.dodging_velocity_gain - new_velocity_gain;
+       float velocity_difference = this.dodging_velocity_gain - new_velocity_gain;
 
        // ramp up dodging speed by adding some velocity each frame.. TODO: do it! :D
-       if (self.dodging_action == 1)
+       if (this.dodging_action == 1)
        {
                //disable jump key during dodge accel phase
-               if(self.movement_z > 0) { self.movement_z = 0; }
+               if(this.movement_z > 0) { this.movement_z = 0; }
 
-               self.velocity += ((self.dodging_direction_y * velocity_difference) * v_right)
-                                       + ((self.dodging_direction_x * velocity_difference) * v_forward);
+               this.velocity += ((this.dodging_direction_y * velocity_difference) * v_right)
+                                       + ((this.dodging_direction_x * velocity_difference) * v_forward);
 
-               self.dodging_velocity_gain = self.dodging_velocity_gain - velocity_difference;
+               this.dodging_velocity_gain = this.dodging_velocity_gain - velocity_difference;
        }
 
        // the up part of the dodge is a single shot action
-       if (self.dodging_single_action == 1)
+       if (this.dodging_single_action == 1)
        {
-               UNSET_ONGROUND(self);
+               UNSET_ONGROUND(this);
 
-               self.velocity += PHYS_DODGING_UP_SPEED * v_up;
+               this.velocity += PHYS_DODGING_UP_SPEED * v_up;
 
 #ifdef SVQC
                if (autocvar_sv_dodging_sound)
                        PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
 
-               animdecide_setaction(self, ANIMACTION_JUMP, true);
+               animdecide_setaction(this, ANIMACTION_JUMP, true);
 #endif
 
-               self.dodging_single_action = 0;
+               this.dodging_single_action = 0;
        }
 
        // are we done with the dodging ramp yet?
-       if((self.dodging_action == 1) && ((time - self.last_dodging_time) > PHYS_DODGING_RAMP_TIME))
+       if((this.dodging_action == 1) && ((time - this.last_dodging_time) > PHYS_DODGING_RAMP_TIME))
        {
                // reset state so next dodge can be done correctly
-               self.dodging_action = 0;
-               self.dodging_direction_x = 0;
-               self.dodging_direction_y = 0;
+               this.dodging_action = 0;
+               this.dodging_direction_x = 0;
+               this.dodging_direction_y = 0;
        }
 }
 
-#ifdef SVQC
-
-MUTATOR_HOOKFUNCTION(dodging, GetCvars)
+void PM_dodging_GetPressedKeys(entity this)
 {
-       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
-       return false;
+#ifdef CSQC
+       if(!PHYS_DODGING) { return; }
+
+       PM_dodging_checkpressedkeys(this);
+
+       int keys = this.pressedkeys;
+       keys = BITSET(keys, KEY_FORWARD,        this.movement.x > 0);
+       keys = BITSET(keys, KEY_BACKWARD,       this.movement.x < 0);
+       keys = BITSET(keys, KEY_RIGHT,          this.movement.y > 0);
+       keys = BITSET(keys, KEY_LEFT,           this.movement.y < 0);
+
+       keys = BITSET(keys, KEY_JUMP,           PHYS_INPUT_BUTTON_JUMP(this));
+       keys = BITSET(keys, KEY_CROUCH,         PHYS_INPUT_BUTTON_CROUCH(this));
+       keys = BITSET(keys, KEY_ATCK,           PHYS_INPUT_BUTTON_ATCK(this));
+       keys = BITSET(keys, KEY_ATCK2,          PHYS_INPUT_BUTTON_ATCK2(this));
+       this.pressedkeys = keys;
+#endif
 }
 
 MUTATOR_HOOKFUNCTION(dodging, PlayerPhysics)
 {
        // print("dodging_PlayerPhysics\n");
-       PM_dodging();
+       PM_dodging_GetPressedKeys(self);
+       PM_dodging(self);
+       return false;
+}
+
+#ifdef SVQC
 
+MUTATOR_HOOKFUNCTION(dodging, GetCvars)
+{
+       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
        return false;
 }
 
 MUTATOR_HOOKFUNCTION(dodging, GetPressedKeys)
 {
-       PM_dodging_checkpressedkeys();
-
+       PM_dodging_checkpressedkeys(self);
        return false;
 }
 
 #endif
-
 #endif
index 6308a2182cd53208000ed5403c37eb5802308bb2..60b193fdf92bdabbdfe0a591da4f4e804d9b8e17 100644 (file)
@@ -1,3 +1,3 @@
 #ifdef SVQC
-#include "dodging.qc"
+       #include "dodging.qc"
 #endif
diff --git a/qcsrc/common/mutators/mutator/doublejump/doublejump.qc b/qcsrc/common/mutators/mutator/doublejump/doublejump.qc
new file mode 100644 (file)
index 0000000..7a09b81
--- /dev/null
@@ -0,0 +1,45 @@
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+       #include "../../../../server/antilag.qh"
+#endif
+#include "../../../physics.qh"
+
+REGISTER_MUTATOR(doublejump, true);
+
+#define PHYS_DOUBLEJUMP(s)                     STAT(DOUBLEJUMP, s)
+
+
+MUTATOR_HOOKFUNCTION(doublejump, PlayerJump)
+{
+       if (PHYS_DOUBLEJUMP(self))
+       {
+               tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
+               if (trace_fraction < 1 && trace_plane_normal_z > 0.7)
+               {
+                       player_multijump = true;
+
+                       // we MUST clip velocity here!
+                       float f = self.velocity * trace_plane_normal;
+                       if (f < 0)
+                               self.velocity -= f * trace_plane_normal;
+               }
+       }
+       return false;
+}
+
+#ifdef SVQC
+
+MUTATOR_HOOKFUNCTION(doublejump, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":doublejump");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(doublejump, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Double jump");
+       return false;
+}
+
+#endif
+#endif
diff --git a/qcsrc/common/mutators/mutator/doublejump/module.inc b/qcsrc/common/mutators/mutator/doublejump/module.inc
new file mode 100644 (file)
index 0000000..f4c695b
--- /dev/null
@@ -0,0 +1,3 @@
+#ifndef MENUQC
+#include "doublejump.qc"
+#endif
index e65e7e8b4b3e844fd89bf26e87829044228f67e9..68ccecaab499e4a1bd02fd68a82abb680f2f1785 100644 (file)
@@ -4,60 +4,63 @@
 #endif
 #include "../../../physics.qh"
 
-.int multijump_count;
-.bool multijump_ready;
-.bool cvar_cl_multijump;
+
+#if defined(SVQC)
+REGISTER_MUTATOR(multijump, cvar("g_multijump"))
+{
+       MUTATOR_ONADD
+       {
+               addstat(STAT_MULTIJUMP_COUNT.m_id, AS_INT, multijump_count);
+       }
+}
+#elif defined(CSQC)
+REGISTER_MUTATOR(multijump, true);
+#endif
 
 #define PHYS_MULTIJUMP                                 STAT(MULTIJUMP, self)
 #define PHYS_MULTIJUMP_SPEED           STAT(MULTIJUMP_SPEED, self)
 #define PHYS_MULTIJUMP_ADD                     STAT(MULTIJUMP_ADD, self)
 #define PHYS_MULTIJUMP_MAXSPEED        STAT(MULTIJUMP_MAXSPEED, self)
 #define PHYS_MULTIJUMP_DODGING                 STAT(MULTIJUMP_DODGING, self)
+#define PHYS_MULTIJUMP_COUNT(s)        STAT(MULTIJUMP_COUNT, s)
 
-void PM_multijump()
-{SELFPARAM();
-       if(!PHYS_MULTIJUMP) { return; }
+.bool multijump_ready;
 
-       if(IS_ONGROUND(self))
-       {
-               self.multijump_count = 0;
-       }
-}
+#ifdef CSQC
+bool autocvar_cl_multijump = false;
 
-bool PM_multijump_checkjump()
-{SELFPARAM();
-       if(!PHYS_MULTIJUMP) { return false; }
+       #define PHYS_MULTIJUMP_CLIENT(s)        autocvar_cl_multijump
+#elif defined(SVQC)
+.bool cvar_cl_multijump;
 
-#ifdef SVQC
-       bool client_multijump = self.cvar_cl_multijump;
-#elif defined(CSQC)
-       bool client_multijump = cvar("cl_multijump");
+       #define PHYS_MULTIJUMP_CLIENT(s)        (s).cvar_cl_multijump
+#endif
+
+bool PM_multijump_checkjump(entity this)
+{
+       if(!PHYS_MULTIJUMP) { return false; }
 
-       if(cvar("cl_multijump") > 1)
+       int client_multijump = PHYS_MULTIJUMP_CLIENT(this);
+       if(client_multijump > 1)
                return false; // nope
-#endif
 
-       if (!IS_JUMP_HELD(self) && !IS_ONGROUND(self) && client_multijump) // jump button pressed this frame and we are in midair
-               self.multijump_ready = true;  // this is necessary to check that we released the jump button and pressed it again
+       if (!IS_JUMP_HELD(this) && !IS_ONGROUND(this) && client_multijump) // jump button pressed this frame and we are in midair
+               this.multijump_ready = true;  // this is necessary to check that we released the jump button and pressed it again
        else
-               self.multijump_ready = false;
+               this.multijump_ready = false;
 
        int phys_multijump = PHYS_MULTIJUMP;
 
-#ifdef CSQC
-       phys_multijump = (PHYS_MULTIJUMP) ? -1 : 0;
-#endif
-
-       if(!player_multijump && self.multijump_ready && (self.multijump_count < phys_multijump || phys_multijump == -1) && self.velocity_z > PHYS_MULTIJUMP_SPEED && (!PHYS_MULTIJUMP_MAXSPEED || vlen(self.velocity) <= PHYS_MULTIJUMP_MAXSPEED))
+       if(!player_multijump && this.multijump_ready && (PHYS_MULTIJUMP_COUNT(this) < phys_multijump || phys_multijump == -1) && this.velocity_z > PHYS_MULTIJUMP_SPEED && (!PHYS_MULTIJUMP_MAXSPEED || vlen(this.velocity) <= PHYS_MULTIJUMP_MAXSPEED))
        {
                if (PHYS_MULTIJUMP)
                {
                        if (!PHYS_MULTIJUMP_ADD) // in this case we make the z velocity == jumpvelocity
                        {
-                               if (self.velocity_z < PHYS_JUMPVELOCITY)
+                               if (this.velocity_z < PHYS_JUMPVELOCITY(this))
                                {
                                        player_multijump = true;
-                                       self.velocity_z = 0;
+                                       this.velocity_z = 0;
                                }
                        }
                        else
@@ -66,55 +69,59 @@ bool PM_multijump_checkjump()
                        if(player_multijump)
                        {
                                if(PHYS_MULTIJUMP_DODGING)
-                               if(self.movement_x != 0 || self.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys
+                               if(this.movement_x != 0 || this.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys
                                {
                                        float curspeed;
                                        vector wishvel, wishdir;
 
 /*#ifdef SVQC
                                        curspeed = max(
-                                               vlen(vec2(self.velocity)), // current xy speed
-                                               vlen(vec2(antilag_takebackavgvelocity(self, max(self.lastteleporttime + sys_frametime, time - 0.25), time))) // average xy topspeed over the last 0.25 secs
+                                               vlen(vec2(this.velocity)), // current xy speed
+                                               vlen(vec2(antilag_takebackavgvelocity(this, max(this.lastteleporttime + sys_frametime, time - 0.25), time))) // average xy topspeed over the last 0.25 secs
                                        );
 #elif defined(CSQC)*/
-                                       curspeed = vlen(vec2(self.velocity));
+                                       curspeed = vlen(vec2(this.velocity));
 //#endif
 
-                                       makevectors(self.v_angle_y * '0 1 0');
-                                       wishvel = v_forward * self.movement_x + v_right * self.movement_y;
+                                       makevectors(this.v_angle_y * '0 1 0');
+                                       wishvel = v_forward * this.movement_x + v_right * this.movement_y;
                                        wishdir = normalize(wishvel);
 
-                                       self.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump
-                                       self.velocity_y = wishdir_y * curspeed;
+                                       this.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump
+                                       this.velocity_y = wishdir_y * curspeed;
                                        // keep velocity_z unchanged!
                                }
                                if (PHYS_MULTIJUMP > 0)
                                {
-                                       self.multijump_count += 1;
+                                       this.multijump_count += 1;
                                }
                        }
                }
-               self.multijump_ready = false; // require releasing and pressing the jump button again for the next jump
+               this.multijump_ready = false; // require releasing and pressing the jump button again for the next jump
        }
 
        return false;
 }
 
-#ifdef SVQC
-REGISTER_MUTATOR(multijump, cvar("g_multijump"));
-
 MUTATOR_HOOKFUNCTION(multijump, PlayerPhysics)
 {
-       PM_multijump();
+#ifdef CSQC
+       self.multijump_count = PHYS_MULTIJUMP_COUNT(self);
+#endif
+       if(!PHYS_MULTIJUMP) { return; }
 
+       if(IS_ONGROUND(self))
+               self.multijump_count = 0;
        return false;
 }
 
 MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
 {
-       return PM_multijump_checkjump();
+       return PM_multijump_checkjump(self);
 }
 
+#ifdef SVQC
+
 MUTATOR_HOOKFUNCTION(multijump, GetCvars)
 {
        GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_multijump, "cl_multijump");
index ec57e94c1e63b63bb2b6f73a3a4ea013d56cd415..c1ab9774dacc7d8a9cfb93d7cd9739a7a60163dc 100644 (file)
@@ -1306,5 +1306,12 @@ MUTATOR_HOOKFUNCTION(nades, BuildMutatorsPrettyString)
        ret_string = strcat(ret_string, ", Nades");
        return false;
 }
+
+MUTATOR_HOOKFUNCTION(nades, BuildGameplayTipsString)
+{
+       ret_string = strcat(ret_string, "\n\n^3nades^8 are enabled, press 'g' to use them\n");
+       return false;
+}
+
 #endif
 #endif
index 0526742b4a56c6c8ceef92c00b4db5e5ac07e959..482135ed6168f9e98296f2cf475890d70ead207b 100644 (file)
@@ -13,11 +13,11 @@ bool Physics_Valid(string thecvar)
        return autocvar_g_physics_clientselect && strhasword(autocvar_g_physics_clientselect_options, thecvar);
 }
 
-float Physics_ClientOption(entity pl, string option)
+float Physics_ClientOption(entity this, string option)
 {
-       if(Physics_Valid(pl.cvar_cl_physics))
+       if(Physics_Valid(this.cvar_cl_physics))
        {
-               string s = sprintf("g_physics_%s_%s", pl.cvar_cl_physics, option);
+               string s = sprintf("g_physics_%s_%s", this.cvar_cl_physics, option);
                if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS)
                        return cvar(s);
        }
@@ -187,9 +187,14 @@ void PM_ClientMovement_UpdateStatus(entity this, bool ground)
                pmove_waterjumptime = 0;
 }
 
-void PM_ClientMovement_Move()
-{SELFPARAM();
+void PM_ClientMovement_Move(entity this)
+{
 #ifdef CSQC
+
+       PM_ClientMovement_UpdateStatus(this, false);
+       if(autocvar_cl_movement == 3)
+               return;
+
        int bump;
        float t;
        float f;
@@ -208,13 +213,11 @@ void PM_ClientMovement_Move()
        vector trace2_plane_normal = '0 0 0';
        vector trace3_plane_normal = '0 0 0';
 
-
-       PM_ClientMovement_UpdateStatus(this, false);
-       primalvelocity = self.velocity;
-       for(bump = 0, t = PHYS_INPUT_TIMELENGTH; bump < 8 && (self.velocity * self.velocity) > 0; bump++)
+       primalvelocity = this.velocity;
+       for(bump = 0, t = PHYS_INPUT_TIMELENGTH; bump < 8 && (this.velocity * this.velocity) > 0; bump++)
        {
-               neworigin = self.origin + t * self.velocity;
-               tracebox(self.origin, self.mins, self.maxs, neworigin, MOVE_NORMAL, self);
+               neworigin = this.origin + t * this.velocity;
+               tracebox(this.origin, this.mins, this.maxs, neworigin, MOVE_NORMAL, this);
                trace1_endpos = trace_endpos;
                trace1_fraction = trace_fraction;
                trace1_plane_normal = trace_plane_normal;
@@ -222,11 +225,11 @@ void PM_ClientMovement_Move()
                {
                        // may be a step or wall, try stepping up
                        // first move forward at a higher level
-                       currentorigin2 = self.origin;
+                       currentorigin2 = this.origin;
                        currentorigin2_z += PHYS_STEPHEIGHT;
                        neworigin2 = neworigin;
                        neworigin2_z += PHYS_STEPHEIGHT;
-                       tracebox(currentorigin2, self.mins, self.maxs, neworigin2, MOVE_NORMAL, self);
+                       tracebox(currentorigin2, this.mins, this.maxs, neworigin2, MOVE_NORMAL, this);
                        trace2_endpos = trace_endpos;
                        trace2_fraction = trace_fraction;
                        trace2_plane_normal = trace_plane_normal;
@@ -235,8 +238,8 @@ void PM_ClientMovement_Move()
                                // then move down from there
                                currentorigin2 = trace2_endpos;
                                neworigin2 = trace2_endpos;
-                               neworigin2_z = self.origin_z;
-                               tracebox(currentorigin2, self.mins, self.maxs, neworigin2, MOVE_NORMAL, self);
+                               neworigin2_z = this.origin_z;
+                               tracebox(currentorigin2, this.mins, this.maxs, neworigin2, MOVE_NORMAL, this);
                                trace3_endpos = trace_endpos;
                                trace3_fraction = trace_fraction;
                                trace3_plane_normal = trace_plane_normal;
@@ -253,7 +256,7 @@ void PM_ClientMovement_Move()
 
                // check if it moved at all
                if(trace1_fraction >= 0.001)
-                       setorigin(self, trace1_endpos);
+                       setorigin(this, trace1_endpos);
 
                // check if it moved all the way
                if(trace1_fraction == 1)
@@ -264,43 +267,43 @@ void PM_ClientMovement_Move()
                // this got commented out in a change that supposedly makes the code match QW better
                // so if this is broken, maybe put it in an if(cls.protocol != PROTOCOL_QUAKEWORLD) block
                if(trace1_plane_normal_z > 0.7)
-                       SET_ONGROUND(self);
+                       SET_ONGROUND(this);
 
                t -= t * trace1_fraction;
 
-               f = (self.velocity * trace1_plane_normal);
-               self.velocity = self.velocity + -f * trace1_plane_normal;
+               f = (this.velocity * trace1_plane_normal);
+               this.velocity = this.velocity + -f * trace1_plane_normal;
        }
        if(pmove_waterjumptime > 0)
-               self.velocity = primalvelocity;
+               this.velocity = primalvelocity;
 #endif
 }
 
-void CPM_PM_Aircontrol(vector wishdir, float wishspeed)
-{SELFPARAM();
-       float k = 32 * (2 * IsMoveInDirection(self.movement, 0) - 1);
+void CPM_PM_Aircontrol(entity this, vector wishdir, float wishspeed)
+{
+       float k = 32 * (2 * IsMoveInDirection(this.movement, 0) - 1);
        if (k <= 0)
                return;
 
-       k *= bound(0, wishspeed / PHYS_MAXAIRSPEED(self), 1);
+       k *= bound(0, wishspeed / PHYS_MAXAIRSPEED(this), 1);
 
-       float zspeed = self.velocity_z;
-       self.velocity_z = 0;
-       float xyspeed = vlen(self.velocity);
-       self.velocity = normalize(self.velocity);
+       float zspeed = this.velocity_z;
+       this.velocity_z = 0;
+       float xyspeed = vlen(this.velocity);
+       this.velocity = normalize(this.velocity);
 
-       float dot = self.velocity * wishdir;
+       float dot = this.velocity * wishdir;
 
        if (dot > 0) // we can't change direction while slowing down
        {
-               k *= pow(dot, PHYS_AIRCONTROL_POWER) * PHYS_INPUT_TIMELENGTH;
-               xyspeed = max(0, xyspeed - PHYS_AIRCONTROL_PENALTY * sqrt(max(0, 1 - dot*dot)) * k/32);
-               k *= PHYS_AIRCONTROL;
-               self.velocity = normalize(self.velocity * xyspeed + wishdir * k);
+               k *= pow(dot, PHYS_AIRCONTROL_POWER(this)) * PHYS_INPUT_TIMELENGTH;
+               xyspeed = max(0, xyspeed - PHYS_AIRCONTROL_PENALTY(this) * sqrt(max(0, 1 - dot*dot)) * k/32);
+               k *= PHYS_AIRCONTROL(this);
+               this.velocity = normalize(this.velocity * xyspeed + wishdir * k);
        }
 
-       self.velocity = self.velocity * xyspeed;
-       self.velocity_z = zspeed;
+       this.velocity = this.velocity * xyspeed;
+       this.velocity_z = zspeed;
 }
 
 float AdjustAirAccelQW(float accelqw, float factor)
@@ -313,8 +316,8 @@ float AdjustAirAccelQW(float accelqw, float factor)
 //   sv_airaccel_sideways_friction 0
 //   prvm_globalset server speedclamp_mode 1
 //     (or 2)
-void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float stretchfactor, float sidefric, float speedlimit)
-{SELFPARAM();
+void PM_Accelerate(entity this, vector wishdir, float wishspeed, float wishspeed0, float accel, float accelqw, float stretchfactor, float sidefric, float speedlimit)
+{
        float speedclamp = stretchfactor > 0 ? stretchfactor
        : accelqw < 0 ? 1 // full clamping, no stretch
        : -1; // no clamping
@@ -324,9 +327,9 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce
        if (GAMEPLAYFIX_Q2AIRACCELERATE)
                wishspeed0 = wishspeed; // don't need to emulate this Q1 bug
 
-       float vel_straight = self.velocity * wishdir;
-       float vel_z = self.velocity_z;
-       vector vel_xy = vec2(self.velocity);
+       float vel_straight = this.velocity * wishdir;
+       float vel_z = this.velocity_z;
+       vector vel_xy = vec2(this.velocity);
        vector vel_perpend = vel_xy - vel_straight * wishdir;
 
        float step = accel * PHYS_INPUT_TIMELENGTH * wishspeed0;
@@ -343,18 +346,18 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce
                // negative: only apply so much sideways friction to stay below the speed you could get by "braking"
        {
                float f = max(0, 1 + PHYS_INPUT_TIMELENGTH * wishspeed * sidefric);
-               float fmin = (vel_xy_backward * vel_xy_backward - vel_straight * vel_straight) / (vel_perpend * vel_perpend);
-               // assume: fmin > 1
+               float themin = (vel_xy_backward * vel_xy_backward - vel_straight * vel_straight) / (vel_perpend * vel_perpend);
+               // assume: themin > 1
                // vel_xy_backward*vel_xy_backward - vel_straight*vel_straight > vel_perpend*vel_perpend
                // vel_xy_backward*vel_xy_backward > vel_straight*vel_straight + vel_perpend*vel_perpend
                // vel_xy_backward*vel_xy_backward > vel_xy * vel_xy
                // obviously, this cannot be
-               if (fmin <= 0)
+               if (themin <= 0)
                        vel_perpend *= f;
                else
                {
-                       fmin = sqrt(fmin);
-                       vel_perpend *= max(fmin, f);
+                       themin = sqrt(themin);
+                       vel_perpend *= max(themin, f);
                }
        }
        else
@@ -374,41 +377,41 @@ void PM_Accelerate(vector wishdir, float wishspeed, float wishspeed0, float acce
                }
        }
 
-       self.velocity = vel_xy + vel_z * '0 0 1';
+       this.velocity = vel_xy + vel_z * '0 0 1';
 }
 
-void PM_AirAccelerate(vector wishdir, float wishspeed)
-{SELFPARAM();
+void PM_AirAccelerate(entity this, vector wishdir, float wishspeed)
+{
        if (wishspeed == 0)
                return;
 
-       vector curvel = self.velocity;
+       vector curvel = this.velocity;
        curvel_z = 0;
        float curspeed = vlen(curvel);
 
        if (wishspeed > curspeed * 1.01)
-               wishspeed = min(wishspeed, curspeed + PHYS_WARSOWBUNNY_AIRFORWARDACCEL * PHYS_MAXSPEED(self) * PHYS_INPUT_TIMELENGTH);
+               wishspeed = min(wishspeed, curspeed + PHYS_WARSOWBUNNY_AIRFORWARDACCEL(this) * PHYS_MAXSPEED(this) * PHYS_INPUT_TIMELENGTH);
        else
        {
-               float f = max(0, (PHYS_WARSOWBUNNY_TOPSPEED - curspeed) / (PHYS_WARSOWBUNNY_TOPSPEED - PHYS_MAXSPEED(self)));
-               wishspeed = max(curspeed, PHYS_MAXSPEED(self)) + PHYS_WARSOWBUNNY_ACCEL * f * PHYS_MAXSPEED(self) * PHYS_INPUT_TIMELENGTH;
+               float f = max(0, (PHYS_WARSOWBUNNY_TOPSPEED(this) - curspeed) / (PHYS_WARSOWBUNNY_TOPSPEED(this) - PHYS_MAXSPEED(this)));
+               wishspeed = max(curspeed, PHYS_MAXSPEED(this)) + PHYS_WARSOWBUNNY_ACCEL(this) * f * PHYS_MAXSPEED(this) * PHYS_INPUT_TIMELENGTH;
        }
        vector wishvel = wishdir * wishspeed;
        vector acceldir = wishvel - curvel;
        float addspeed = vlen(acceldir);
        acceldir = normalize(acceldir);
 
-       float accelspeed = min(addspeed, PHYS_WARSOWBUNNY_TURNACCEL * PHYS_MAXSPEED(self) * PHYS_INPUT_TIMELENGTH);
+       float accelspeed = min(addspeed, PHYS_WARSOWBUNNY_TURNACCEL(this) * PHYS_MAXSPEED(this) * PHYS_INPUT_TIMELENGTH);
 
-       if (PHYS_WARSOWBUNNY_BACKTOSIDERATIO < 1)
+       if (PHYS_WARSOWBUNNY_BACKTOSIDERATIO(this) < 1)
        {
                vector curdir = normalize(curvel);
                float dot = acceldir * curdir;
                if (dot < 0)
-                       acceldir -= (1 - PHYS_WARSOWBUNNY_BACKTOSIDERATIO) * dot * curdir;
+                       acceldir -= (1 - PHYS_WARSOWBUNNY_BACKTOSIDERATIO(this)) * dot * curdir;
        }
 
-       self.velocity += accelspeed * acceldir;
+       this.velocity += accelspeed * acceldir;
 }
 
 
@@ -420,63 +423,41 @@ When you press the jump key
 returns true if handled
 =============
 */
-bool PlayerJump ()
-{SELFPARAM();
-       if (PHYS_FROZEN(self))
+bool PlayerJump(entity this)
+{
+       if (PHYS_FROZEN(this))
                return true; // no jumping in freezetag when frozen
 
 #ifdef SVQC
-       if (self.player_blocked)
+       if (this.player_blocked)
                return true; // no jumping while blocked
 #endif
 
        bool doublejump = false;
-       float mjumpheight = PHYS_JUMPVELOCITY;
-#ifdef CSQC
-       player_multijump = doublejump;
-       player_jumpheight = mjumpheight;
-#endif
+       float mjumpheight = PHYS_JUMPVELOCITY(this);
 
-       if (MUTATOR_CALLHOOK(PlayerJump, doublejump, mjumpheight)
-#ifdef CSQC
-               || PM_multijump_checkjump()
-#endif
-               ) { return true; }
+       if (MUTATOR_CALLHOOK(PlayerJump, this, doublejump, mjumpheight))
+               return true;
 
        doublejump = player_multijump;
        mjumpheight = player_jumpheight;
 
-       if (PHYS_DOUBLEJUMP)
-       {
-               tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
-               if (trace_fraction < 1 && trace_plane_normal_z > 0.7)
-               {
-                       doublejump = true;
-
-                       // we MUST clip velocity here!
-                       float f;
-                       f = self.velocity * trace_plane_normal;
-                       if (f < 0)
-                               self.velocity -= f * trace_plane_normal;
-               }
-       }
-
-       if (self.waterlevel >= WATERLEVEL_SWIMMING)
+       if (this.waterlevel >= WATERLEVEL_SWIMMING)
        {
-               self.velocity_z = PHYS_MAXSPEED(self) * 0.7;
+               this.velocity_z = PHYS_MAXSPEED(this) * 0.7;
                return true;
        }
 
        if (!doublejump)
-               if (!IS_ONGROUND(self))
-                       return IS_JUMP_HELD(self);
+               if (!IS_ONGROUND(this))
+                       return IS_JUMP_HELD(this);
 
-       bool track_jump = PHYS_CL_TRACK_CANJUMP(self);
-       if(PHYS_TRACK_CANJUMP(self))
+       bool track_jump = PHYS_CL_TRACK_CANJUMP(this);
+       if(PHYS_TRACK_CANJUMP(this))
                track_jump = true;
 
        if (track_jump)
-               if (IS_JUMP_HELD(self))
+               if (IS_JUMP_HELD(this))
                        return true;
 
        // sv_jumpspeedcap_min/sv_jumpspeedcap_max act as baseline
@@ -487,82 +468,82 @@ bool PlayerJump ()
        {
                float minjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MIN);
 
-               if (self.velocity_z < minjumpspeed)
-                       mjumpheight += minjumpspeed - self.velocity_z;
+               if (this.velocity_z < minjumpspeed)
+                       mjumpheight += minjumpspeed - this.velocity_z;
        }
 
        if(PHYS_JUMPSPEEDCAP_MAX != "")
        {
                // don't do jump speedcaps on ramps to preserve old xonotic ramjump style
-               tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
+               tracebox(this.origin + '0 0 0.01', this.mins, this.maxs, this.origin - '0 0 0.01', MOVE_NORMAL, this);
 
                if (!(trace_fraction < 1 && trace_plane_normal_z < 0.98 && PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS))
                {
                        float maxjumpspeed = mjumpheight * stof(PHYS_JUMPSPEEDCAP_MAX);
 
-                       if (self.velocity_z > maxjumpspeed)
-                               mjumpheight -= self.velocity_z - maxjumpspeed;
+                       if (this.velocity_z > maxjumpspeed)
+                               mjumpheight -= this.velocity_z - maxjumpspeed;
                }
        }
 
-       if (!WAS_ONGROUND(self))
+       if (!WAS_ONGROUND(this))
        {
 #ifdef SVQC
                if(autocvar_speedmeter)
-                       LOG_TRACE(strcat("landing velocity: ", vtos(self.velocity), " (abs: ", ftos(vlen(self.velocity)), ")\n"));
+                       LOG_TRACE(strcat("landing velocity: ", vtos(this.velocity), " (abs: ", ftos(vlen(this.velocity)), ")\n"));
 #endif
-               if(self.lastground < time - 0.3)
+               if(this.lastground < time - 0.3)
                {
-                       self.velocity_x *= (1 - PHYS_FRICTION_ONLAND);
-                       self.velocity_y *= (1 - PHYS_FRICTION_ONLAND);
+                       this.velocity_x *= (1 - PHYS_FRICTION_ONLAND);
+                       this.velocity_y *= (1 - PHYS_FRICTION_ONLAND);
                }
 #ifdef SVQC
-               if(self.jumppadcount > 1)
-                       LOG_TRACE(strcat(ftos(self.jumppadcount), "x jumppad combo\n"));
-               self.jumppadcount = 0;
+               if(this.jumppadcount > 1)
+                       LOG_TRACE(strcat(ftos(this.jumppadcount), "x jumppad combo\n"));
+               this.jumppadcount = 0;
 #endif
        }
 
-       self.velocity_z += mjumpheight;
+       this.velocity_z += mjumpheight;
 
-       UNSET_ONGROUND(self);
-       SET_JUMP_HELD(self);
+       UNSET_ONGROUND(this);
+       SET_JUMP_HELD(this);
 
 #ifdef SVQC
 
-       self.oldvelocity_z = self.velocity_z;
+       this.oldvelocity_z = this.velocity_z;
 
-       animdecide_setaction(self, ANIMACTION_JUMP, true);
+       animdecide_setaction(this, ANIMACTION_JUMP, true);
 
        if (autocvar_g_jump_grunt)
-               PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+               WITH(entity, this, this, PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND));
 #endif
        return true;
 }
 
-void CheckWaterJump()
-{SELFPARAM();
+void CheckWaterJump(entity this)
+{
 // check for a jump-out-of-water
-       makevectors(self.v_angle);
-       vector start = self.origin;
+       makevectors(this.v_angle);
+       vector start = this.origin;
        start_z += 8;
        v_forward_z = 0;
        normalize(v_forward);
        vector end = start + v_forward*24;
-       traceline (start, end, true, self);
+       traceline (start, end, true, this);
        if (trace_fraction < 1)
        {       // solid at waist
-               start_z = start_z + self.maxs_z - 8;
+               start_z = start_z + this.maxs_z - 8;
                end = start + v_forward*24;
-               self.movedir = trace_plane_normal * -50;
-               traceline(start, end, true, self);
+               this.movedir = trace_plane_normal * -50;
+               traceline(start, end, true, this);
                if (trace_fraction == 1)
                {       // open at eye level
-                       self.velocity_z = 225;
-                       self.flags |= FL_WATERJUMP;
-                       SET_JUMP_HELD(self);
+                       this.velocity_z = 225;
+                       this.flags |= FL_WATERJUMP;
+                       SET_JUMP_HELD(this);
 #ifdef SVQC
-                       self.teleport_time = time + 2;  // safety net
+                       this.teleport_time = time + 2;  // safety net
 #elif defined(CSQC)
                        pmove_waterjumptime = time + 2;
 #endif
@@ -578,48 +559,46 @@ void CheckWaterJump()
        #define JETPACK_JUMP(s) autocvar_cl_jetpack_jump
 #endif
 .float jetpack_stopped;
-// Hack: shouldn't need to know about this
-.float multijump_count;
-void CheckPlayerJump()
-{SELFPARAM();
+void CheckPlayerJump(entity this)
+{
 #ifdef SVQC
-       float was_flying = ITEMS_STAT(self) & IT_USING_JETPACK;
+       float was_flying = ITEMS_STAT(this) & IT_USING_JETPACK;
 #endif
-       if (JETPACK_JUMP(self) < 2)
-               ITEMS_STAT(self) &= ~IT_USING_JETPACK;
+       if (JETPACK_JUMP(this) < 2)
+               ITEMS_STAT(this) &= ~IT_USING_JETPACK;
 
-       if(PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_JETPACK(self))
+       if(PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_JETPACK(this))
        {
-               float air_jump = !PlayerJump() || self.multijump_count > 0; // PlayerJump() has important side effects
-               float activate = JETPACK_JUMP(self) && air_jump && PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_JETPACK(self);
-               float has_fuel = !PHYS_JETPACK_FUEL || PHYS_AMMO_FUEL(self) || ITEMS_STAT(self) & IT_UNLIMITED_WEAPON_AMMO;
+               float air_jump = !PlayerJump(this) || player_multijump; // PlayerJump() has important side effects
+               float activate = JETPACK_JUMP(this) && air_jump && PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_JETPACK(this);
+               float has_fuel = !PHYS_JETPACK_FUEL || PHYS_AMMO_FUEL(this) || ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO;
 
-               if (!(ITEMS_STAT(self) & ITEM_Jetpack.m_itemid)) { }
-               else if (self.jetpack_stopped) { }
+               if (!(ITEMS_STAT(this) & ITEM_Jetpack.m_itemid)) { }
+               else if (this.jetpack_stopped) { }
                else if (!has_fuel)
                {
 #ifdef SVQC
                        if (was_flying) // TODO: ran out of fuel message
-                               Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_JETPACK_NOFUEL);
+                               Send_Notification(NOTIF_ONE, this, MSG_INFO, INFO_JETPACK_NOFUEL);
                        else if (activate)
-                               Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_JETPACK_NOFUEL);
+                               Send_Notification(NOTIF_ONE, this, MSG_INFO, INFO_JETPACK_NOFUEL);
 #endif
-                       self.jetpack_stopped = true;
-                       ITEMS_STAT(self) &= ~IT_USING_JETPACK;
+                       this.jetpack_stopped = true;
+                       ITEMS_STAT(this) &= ~IT_USING_JETPACK;
                }
-               else if (activate && !PHYS_FROZEN(self))
-                       ITEMS_STAT(self) |= IT_USING_JETPACK;
+               else if (activate && !PHYS_FROZEN(this))
+                       ITEMS_STAT(this) |= IT_USING_JETPACK;
        }
        else
        {
-               self.jetpack_stopped = false;
-               ITEMS_STAT(self) &= ~IT_USING_JETPACK;
+               this.jetpack_stopped = false;
+               ITEMS_STAT(this) &= ~IT_USING_JETPACK;
        }
-       if (!PHYS_INPUT_BUTTON_JUMP(self))
-               UNSET_JUMP_HELD(self);
+       if (!PHYS_INPUT_BUTTON_JUMP(this))
+               UNSET_JUMP_HELD(this);
 
-       if (self.waterlevel == WATERLEVEL_SWIMMING)
-               CheckWaterJump();
+       if (this.waterlevel == WATERLEVEL_SWIMMING)
+               CheckWaterJump(this);
 }
 
 float racecar_angle(float forward, float down)
@@ -640,228 +619,18 @@ float racecar_angle(float forward, float down)
                return ret * angle_mult;
 }
 
-void RaceCarPhysics()
-{SELFPARAM();
-#ifdef SVQC
-       // using this move type for "big rigs"
-       // the engine does not push the entity!
-
-       vector rigvel;
-
-       vector angles_save = self.angles;
-       float accel = bound(-1, self.movement.x / PHYS_MAXSPEED(self), 1);
-       float steer = bound(-1, self.movement.y / PHYS_MAXSPEED(self), 1);
-
-       if (g_bugrigs_reverse_speeding)
-       {
-               if (accel < 0)
-               {
-                       // back accel is DIGITAL
-                       // to prevent speedhack
-                       if (accel < -0.5)
-                               accel = -1;
-                       else
-                               accel = 0;
-               }
-       }
-
-       self.angles_x = 0;
-       self.angles_z = 0;
-       makevectors(self.angles); // new forward direction!
-
-       if (IS_ONGROUND(self) || g_bugrigs_air_steering)
-       {
-               float myspeed = self.velocity * v_forward;
-               float upspeed = self.velocity * v_up;
-
-               // responsiveness factor for steering and acceleration
-               float f = 1 / (1 + pow(max(-myspeed, myspeed) / g_bugrigs_speed_ref, g_bugrigs_speed_pow));
-               //MAXIMA: f(v) := 1 / (1 + (v / g_bugrigs_speed_ref) ^ g_bugrigs_speed_pow);
-
-               float steerfactor;
-               if (myspeed < 0 && g_bugrigs_reverse_spinning)
-                       steerfactor = -myspeed * g_bugrigs_steer;
-               else
-                       steerfactor = -myspeed * f * g_bugrigs_steer;
-
-               float accelfactor;
-               if (myspeed < 0 && g_bugrigs_reverse_speeding)
-                       accelfactor = g_bugrigs_accel;
-               else
-                       accelfactor = f * g_bugrigs_accel;
-               //MAXIMA: accel(v) := f(v) * g_bugrigs_accel;
-
-               if (accel < 0)
-               {
-                       if (myspeed > 0)
-                       {
-                               myspeed = max(0, myspeed - PHYS_INPUT_TIMELENGTH * (g_bugrigs_friction_floor - g_bugrigs_friction_brake * accel));
-                       }
-                       else
-                       {
-                               if (!g_bugrigs_reverse_speeding)
-                                       myspeed = min(0, myspeed + PHYS_INPUT_TIMELENGTH * g_bugrigs_friction_floor);
-                       }
-               }
-               else
-               {
-                       if (myspeed >= 0)
-                       {
-                               myspeed = max(0, myspeed - PHYS_INPUT_TIMELENGTH * g_bugrigs_friction_floor);
-                       }
-                       else
-                       {
-                               if (g_bugrigs_reverse_stopping)
-                                       myspeed = 0;
-                               else
-                                       myspeed = min(0, myspeed + PHYS_INPUT_TIMELENGTH * (g_bugrigs_friction_floor + g_bugrigs_friction_brake * accel));
-                       }
-               }
-               // terminal velocity = velocity at which 50 == accelfactor, that is, 1549 units/sec
-               //MAXIMA: friction(v) := g_bugrigs_friction_floor;
-
-               self.angles_y += steer * PHYS_INPUT_TIMELENGTH * steerfactor; // apply steering
-               makevectors(self.angles); // new forward direction!
-
-               myspeed += accel * accelfactor * PHYS_INPUT_TIMELENGTH;
-
-               rigvel = myspeed * v_forward + '0 0 1' * upspeed;
-       }
-       else
-       {
-               float myspeed = vlen(self.velocity);
-
-               // responsiveness factor for steering and acceleration
-               float f = 1 / (1 + pow(max(0, myspeed / g_bugrigs_speed_ref), g_bugrigs_speed_pow));
-               float steerfactor = -myspeed * f;
-               self.angles_y += steer * PHYS_INPUT_TIMELENGTH * steerfactor; // apply steering
-
-               rigvel = self.velocity;
-               makevectors(self.angles); // new forward direction!
-       }
-
-       rigvel *= max(0, 1 - vlen(rigvel) * g_bugrigs_friction_air * PHYS_INPUT_TIMELENGTH);
-       //MAXIMA: airfriction(v) := v * v * g_bugrigs_friction_air;
-       //MAXIMA: total_acceleration(v) := accel(v) - friction(v) - airfriction(v);
-       //MAXIMA: solve(total_acceleration(v) = 0, v);
-
-       if (g_bugrigs_planar_movement)
-       {
-               vector rigvel_xy, neworigin, up;
-               float mt;
-
-               rigvel_z -= PHYS_INPUT_TIMELENGTH * PHYS_GRAVITY(this); // 4x gravity plays better
-               rigvel_xy = vec2(rigvel);
-
-               if (g_bugrigs_planar_movement_car_jumping)
-                       mt = MOVE_NORMAL;
-               else
-                       mt = MOVE_NOMONSTERS;
-
-               tracebox(self.origin, self.mins, self.maxs, self.origin + '0 0 1024', mt, self);
-               up = trace_endpos - self.origin;
-
-               // BUG RIGS: align the move to the surface instead of doing collision testing
-               // can we move?
-               tracebox(trace_endpos, self.mins, self.maxs, trace_endpos + rigvel_xy * PHYS_INPUT_TIMELENGTH, mt, self);
-
-               // align to surface
-               tracebox(trace_endpos, self.mins, self.maxs, trace_endpos - up + '0 0 1' * rigvel_z * PHYS_INPUT_TIMELENGTH, mt, self);
-
-               if (trace_fraction < 0.5)
-               {
-                       trace_fraction = 1;
-                       neworigin = self.origin;
-               }
-               else
-                       neworigin = trace_endpos;
-
-               if (trace_fraction < 1)
-               {
-                       // now set angles_x so that the car points parallel to the surface
-                       self.angles = vectoangles(
-                                       '1 0 0' * v_forward_x * trace_plane_normal_z
-                                       +
-                                       '0 1 0' * v_forward_y * trace_plane_normal_z
-                                       +
-                                       '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y)
-                                       );
-                       SET_ONGROUND(self);
-               }
-               else
-               {
-                       // now set angles_x so that the car points forward, but is tilted in velocity direction
-                       UNSET_ONGROUND(self);
-               }
-
-               self.velocity = (neworigin - self.origin) * (1.0 / PHYS_INPUT_TIMELENGTH);
-               self.movetype = MOVETYPE_NOCLIP;
-       }
-       else
-       {
-               rigvel_z -= PHYS_INPUT_TIMELENGTH * PHYS_GRAVITY(this); // 4x gravity plays better
-               self.velocity = rigvel;
-               self.movetype = MOVETYPE_FLY;
-       }
-
-       trace_fraction = 1;
-       tracebox(self.origin, self.mins, self.maxs, self.origin - '0 0 4', MOVE_NORMAL, self);
-       if (trace_fraction != 1)
-       {
-               self.angles = vectoangles2(
-                               '1 0 0' * v_forward_x * trace_plane_normal_z
-                               +
-                               '0 1 0' * v_forward_y * trace_plane_normal_z
-                               +
-                               '0 0 1' * -(v_forward_x * trace_plane_normal_x + v_forward_y * trace_plane_normal_y),
-                               trace_plane_normal
-                               );
-       }
-       else
-       {
-               vector vel_local;
-
-               vel_local_x = v_forward * self.velocity;
-               vel_local_y = v_right * self.velocity;
-               vel_local_z = v_up * self.velocity;
-
-               self.angles_x = racecar_angle(vel_local_x, vel_local_z);
-               self.angles_z = racecar_angle(-vel_local_y, vel_local_z);
-       }
-
-       // smooth the angles
-       vector vf1, vu1, smoothangles;
-       makevectors(self.angles);
-       float f = bound(0, PHYS_INPUT_TIMELENGTH * g_bugrigs_angle_smoothing, 1);
-       if (f == 0)
-               f = 1;
-       vf1 = v_forward * f;
-       vu1 = v_up * f;
-       makevectors(angles_save);
-       vf1 = vf1 + v_forward * (1 - f);
-       vu1 = vu1 + v_up * (1 - f);
-       smoothangles = vectoangles2(vf1, vu1);
-       self.angles_x = -smoothangles_x;
-       self.angles_z =  smoothangles_z;
-#endif
-}
-
 string specialcommand = "xwxwxsxsxaxdxaxdx1x ";
 .float specialcommand_pos;
 void SpecialCommand()
 {
 #ifdef SVQC
-#ifdef TETRIS
-       TetrisImpulse();
-#else
        if (!CheatImpulse(99))
                LOG_INFO("A hollow voice says \"Plugh\".\n");
 #endif
-#endif
 }
 
-float PM_check_specialcommand(float buttons)
-{SELFPARAM();
+float PM_check_specialcommand(entity this, float buttons)
+{
 #ifdef SVQC
        string c;
        if (!buttons)
@@ -881,109 +650,97 @@ float PM_check_specialcommand(float buttons)
        else
                c = "?";
 
-       if (c == substring(specialcommand, self.specialcommand_pos, 1))
+       if (c == substring(specialcommand, this.specialcommand_pos, 1))
        {
-               self.specialcommand_pos += 1;
-               if (self.specialcommand_pos >= strlen(specialcommand))
+               this.specialcommand_pos += 1;
+               if (this.specialcommand_pos >= strlen(specialcommand))
                {
-                       self.specialcommand_pos = 0;
+                       this.specialcommand_pos = 0;
                        SpecialCommand();
                        return true;
                }
        }
-       else if (self.specialcommand_pos && (c != substring(specialcommand, self.specialcommand_pos - 1, 1)))
-               self.specialcommand_pos = 0;
+       else if (this.specialcommand_pos && (c != substring(specialcommand, this.specialcommand_pos - 1, 1)))
+               this.specialcommand_pos = 0;
 #endif
        return false;
 }
 
-void PM_check_nickspam()
-{SELFPARAM();
+void PM_check_nickspam(entity this)
+{
 #ifdef SVQC
-       if (time >= self.nickspamtime)
+       if (time >= this.nickspamtime)
                return;
-       if (self.nickspamcount >= autocvar_g_nick_flood_penalty_yellow)
+       if (this.nickspamcount >= autocvar_g_nick_flood_penalty_yellow)
        {
                // slight annoyance for nick change scripts
-               self.movement = -1 * self.movement;
-               self.BUTTON_ATCK = self.BUTTON_JUMP = self.BUTTON_ATCK2 = self.BUTTON_ZOOM = self.BUTTON_CROUCH = self.BUTTON_HOOK = self.BUTTON_USE = 0;
+               this.movement = -1 * this.movement;
+               this.BUTTON_ATCK = this.BUTTON_JUMP = this.BUTTON_ATCK2 = this.BUTTON_ZOOM = this.BUTTON_CROUCH = this.BUTTON_HOOK = this.BUTTON_USE = 0;
 
-               if (self.nickspamcount >= autocvar_g_nick_flood_penalty_red) // if you are persistent and the slight annoyance above does not stop you, I'll show you!
+               if (this.nickspamcount >= autocvar_g_nick_flood_penalty_red) // if you are persistent and the slight annoyance above does not stop you, I'll show you!
                {
-                       self.v_angle_x = random() * 360;
-                       self.v_angle_y = random() * 360;
+                       this.v_angle_x = random() * 360;
+                       this.v_angle_y = random() * 360;
                        // at least I'm not forcing retardedview by also assigning to angles_z
-                       self.fixangle = true;
+                       this.fixangle = true;
                }
        }
 #endif
 }
 
-void PM_check_punch()
-{SELFPARAM();
+void PM_check_punch(entity this)
+{
 #ifdef SVQC
-       if (self.punchangle != '0 0 0')
+       if (this.punchangle != '0 0 0')
        {
-               float f = vlen(self.punchangle) - 10 * PHYS_INPUT_TIMELENGTH;
+               float f = vlen(this.punchangle) - 10 * PHYS_INPUT_TIMELENGTH;
                if (f > 0)
-                       self.punchangle = normalize(self.punchangle) * f;
+                       this.punchangle = normalize(this.punchangle) * f;
                else
-                       self.punchangle = '0 0 0';
+                       this.punchangle = '0 0 0';
        }
 
-       if (self.punchvector != '0 0 0')
+       if (this.punchvector != '0 0 0')
        {
-               float f = vlen(self.punchvector) - 30 * PHYS_INPUT_TIMELENGTH;
+               float f = vlen(this.punchvector) - 30 * PHYS_INPUT_TIMELENGTH;
                if (f > 0)
-                       self.punchvector = normalize(self.punchvector) * f;
+                       this.punchvector = normalize(this.punchvector) * f;
                else
-                       self.punchvector = '0 0 0';
+                       this.punchvector = '0 0 0';
        }
 #endif
 }
 
-void PM_check_spider()
-{SELFPARAM();
-#ifdef SVQC
-       if (time >= self.spider_slowness)
-               return;
-       PHYS_MAXSPEED(self) *= 0.5; // half speed while slow from spider
-       PHYS_MAXAIRSPEED(self) *= 0.5;
-       PHYS_AIRSPEEDLIMIT_NONQW(self) *= 0.5;
-       PHYS_AIRSTRAFEACCELERATE(self) *= 0.5;
-#endif
-}
-
 // predict frozen movement, as frozen players CAN move in some cases
-void PM_check_frozen()
-{SELFPARAM();
-       if (!PHYS_FROZEN(self))
+void PM_check_frozen(entity this)
+{
+       if (!PHYS_FROZEN(this))
                return;
        if (PHYS_DODGING_FROZEN
 #ifdef SVQC
-       && IS_REAL_CLIENT(self)
+       && IS_REAL_CLIENT(this)
 #endif
        )
        {
-               self.movement_x = bound(-5, self.movement.x, 5);
-               self.movement_y = bound(-5, self.movement.y, 5);
-               self.movement_z = bound(-5, self.movement.z, 5);
+               this.movement_x = bound(-5, this.movement.x, 5);
+               this.movement_y = bound(-5, this.movement.y, 5);
+               this.movement_z = bound(-5, this.movement.z, 5);
        }
        else
-               self.movement = '0 0 0';
+               this.movement = '0 0 0';
 
-       vector midpoint = ((self.absmin + self.absmax) * 0.5);
+       vector midpoint = ((this.absmin + this.absmax) * 0.5);
        if (pointcontents(midpoint) == CONTENT_WATER)
        {
-               self.velocity = self.velocity * 0.5;
+               this.velocity = this.velocity * 0.5;
 
                if (pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
-                       self.velocity_z = 200;
+                       this.velocity_z = 200;
        }
 }
 
-void PM_check_hitground()
-{SELFPARAM();
+void PM_check_hitground(entity this)
+{
 #ifdef SVQC
        if (!IS_PLAYER(this)) return; // no fall sounds for observers thank you very much
        if (!IS_ONGROUND(this)) return;
@@ -997,207 +754,191 @@ void PM_check_hitground()
     tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
     if ((trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS)) return;
     entity fall = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS) ? GS_FALL_METAL : GS_FALL;
-    GlobalSound(fall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+    WITH(entity, self, this, GlobalSound(fall, CH_PLAYER, VOICETYPE_PLAYERSOUND));
 #endif
 }
 
-void PM_check_blocked()
-{SELFPARAM();
+void PM_check_blocked(entity this)
+{
 #ifdef SVQC
-       if (!self.player_blocked)
+       if (!this.player_blocked)
                return;
-       self.movement = '0 0 0';
-       self.disableclientprediction = 1;
-#endif
-}
-
-void PM_check_vortex()
-{SELFPARAM();
-#ifdef SVQC
-       // WEAPONTODO
-       float xyspeed = vlen(vec2(self.velocity));
-       if (self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed))
-       {
-               // add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed
-               xyspeed = min(xyspeed, WEP_CVAR(vortex, charge_maxspeed));
-               float f = (xyspeed - WEP_CVAR(vortex, charge_minspeed)) / (WEP_CVAR(vortex, charge_maxspeed) - WEP_CVAR(vortex, charge_minspeed));
-               // add the extra charge
-               self.vortex_charge = min(1, self.vortex_charge + WEP_CVAR(vortex, charge_velocity_rate) * f * PHYS_INPUT_TIMELENGTH);
-       }
+       this.movement = '0 0 0';
+       this.disableclientprediction = 1;
 #endif
 }
 
-void PM_fly(float maxspd_mod)
-{SELFPARAM();
+void PM_fly(entity this, float maxspd_mod)
+{
        // noclipping or flying
-       UNSET_ONGROUND(self);
-
-       self.velocity = self.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION);
-       makevectors(self.v_angle);
-       //wishvel = v_forward * self.movement.x + v_right * self.movement.y + v_up * self.movement.z;
-       vector wishvel = v_forward * self.movement.x
-                                       + v_right * self.movement.y
-                                       + '0 0 1' * self.movement.z;
+       UNSET_ONGROUND(this);
+
+       this.velocity = this.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this));
+       makevectors(this.v_angle);
+       //wishvel = v_forward * this.movement.x + v_right * this.movement.y + v_up * this.movement.z;
+       vector wishvel = v_forward * this.movement.x
+                                       + v_right * this.movement.y
+                                       + '0 0 1' * this.movement.z;
        // acceleration
        vector wishdir = normalize(wishvel);
-       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(self) * maxspd_mod);
+       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
 #ifdef SVQC
-       if (time >= self.teleport_time)
+       if (time >= this.teleport_time)
 #endif
-               PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE * maxspd_mod, 1, 0, 0, 0);
-       PM_ClientMovement_Move();
+               PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this) * maxspd_mod, 1, 0, 0, 0);
+       PM_ClientMovement_Move(this);
 }
 
-void PM_swim(float maxspd_mod)
-{SELFPARAM();
+void PM_swim(entity this, float maxspd_mod)
+{
        // swimming
-       UNSET_ONGROUND(self);
+       UNSET_ONGROUND(this);
 
-       float jump = PHYS_INPUT_BUTTON_JUMP(self);
+       float jump = PHYS_INPUT_BUTTON_JUMP(this);
        // water jump only in certain situations
        // this mimics quakeworld code
-       if (jump && self.waterlevel == WATERLEVEL_SWIMMING && self.velocity_z >= -180)
+       if (jump && this.waterlevel == WATERLEVEL_SWIMMING && this.velocity_z >= -180)
        {
-               vector yawangles = '0 1 0' * self.v_angle.y;
+               vector yawangles = '0 1 0' * this.v_angle.y;
                makevectors(yawangles);
                vector forward = v_forward;
-               vector spot = self.origin + 24 * forward;
+               vector spot = this.origin + 24 * forward;
                spot_z += 8;
-               traceline(spot, spot, MOVE_NOMONSTERS, self);
+               traceline(spot, spot, MOVE_NOMONSTERS, this);
                if (trace_startsolid)
                {
                        spot_z += 24;
-                       traceline(spot, spot, MOVE_NOMONSTERS, self);
+                       traceline(spot, spot, MOVE_NOMONSTERS, this);
                        if (!trace_startsolid)
                        {
-                               self.velocity = forward * 50;
-                               self.velocity_z = 310;
+                               this.velocity = forward * 50;
+                               this.velocity_z = 310;
                                pmove_waterjumptime = 2;
-                               UNSET_ONGROUND(self);
-                               SET_JUMP_HELD(self);
+                               UNSET_ONGROUND(this);
+                               SET_JUMP_HELD(this);
                        }
                }
        }
-       makevectors(self.v_angle);
-       //wishvel = v_forward * self.movement.x + v_right * self.movement.y + v_up * self.movement.z;
-       vector wishvel = v_forward * self.movement.x
-                                       + v_right * self.movement.y
-                                       + '0 0 1' * self.movement.z;
+       makevectors(this.v_angle);
+       //wishvel = v_forward * this.movement.x + v_right * this.movement.y + v_up * this.movement.z;
+       vector wishvel = v_forward * this.movement.x
+                                       + v_right * this.movement.y
+                                       + '0 0 1' * this.movement.z;
        if (wishvel == '0 0 0')
                wishvel = '0 0 -60'; // drift towards bottom
 
        vector wishdir = normalize(wishvel);
-       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(self) * maxspd_mod) * 0.7;
+       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod) * 0.7;
 
-       if (IS_DUCKED(self))
+       if (IS_DUCKED(this))
        wishspeed *= 0.5;
 
 //     if (pmove_waterjumptime <= 0) // TODO: use
     {
                // water friction
-               float f = 1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION;
+               float f = 1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this);
                f = min(max(0, f), 1);
-               self.velocity *= f;
+               this.velocity *= f;
 
-               f = wishspeed - self.velocity * wishdir;
+               f = wishspeed - this.velocity * wishdir;
                if (f > 0)
                {
-                       float accelspeed = min(PHYS_ACCELERATE * PHYS_INPUT_TIMELENGTH * wishspeed, f);
-                       self.velocity += accelspeed * wishdir;
+                       float accelspeed = min(PHYS_ACCELERATE(this) * PHYS_INPUT_TIMELENGTH * wishspeed, f);
+                       this.velocity += accelspeed * wishdir;
                }
 
                // holding jump button swims upward slowly
                if (jump)
                {
 #if 0
-                       if (self.watertype & CONTENT_LAVA)
-                               self.velocity_z =  50;
-                       else if (self.watertype & CONTENT_SLIME)
-                               self.velocity_z =  80;
+                       if (this.watertype & CONTENT_LAVA)
+                               this.velocity_z =  50;
+                       else if (this.watertype & CONTENT_SLIME)
+                               this.velocity_z =  80;
                        else
                        {
                                if (IS_NEXUIZ_DERIVED(gamemode))
 #endif
-                                       self.velocity_z = 200;
+                                       this.velocity_z = 200;
 #if 0
                                else
-                                       self.velocity_z = 100;
+                                       this.velocity_z = 100;
                        }
 #endif
                }
        }
        // water acceleration
-       PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE * maxspd_mod, 1, 0, 0, 0);
-       PM_ClientMovement_Move();
+       PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this) * maxspd_mod, 1, 0, 0, 0);
+       PM_ClientMovement_Move(this);
 }
 
-void PM_ladder(float maxspd_mod)
-{SELFPARAM();
+void PM_ladder(entity this, float maxspd_mod)
+{
        // on a spawnfunc_func_ladder or swimming in spawnfunc_func_water
-       UNSET_ONGROUND(self);
+       UNSET_ONGROUND(this);
 
        float g;
        g = PHYS_GRAVITY(this) * PHYS_INPUT_TIMELENGTH;
-       if (PHYS_ENTGRAVITY(self))
-               g *= PHYS_ENTGRAVITY(self);
+       if (PHYS_ENTGRAVITY(this))
+               g *= PHYS_ENTGRAVITY(this);
        if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
        {
                g *= 0.5;
-               self.velocity_z += g;
+               this.velocity_z += g;
        }
 
-       self.velocity = self.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION);
-       makevectors(self.v_angle);
-       //wishvel = v_forward * self.movement.x + v_right * self.movement.y + v_up * self.movement.z;
-       vector wishvel = v_forward * self.movement_x
-                                       + v_right * self.movement_y
-                                       + '0 0 1' * self.movement_z;
-       self.velocity_z += g;
-       if (self.ladder_entity.classname == "func_water")
+       this.velocity = this.velocity * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this));
+       makevectors(this.v_angle);
+       //wishvel = v_forward * this.movement.x + v_right * this.movement.y + v_up * this.movement.z;
+       vector wishvel = v_forward * this.movement_x
+                                       + v_right * this.movement_y
+                                       + '0 0 1' * this.movement_z;
+       this.velocity_z += g;
+       if (this.ladder_entity.classname == "func_water")
        {
                float f = vlen(wishvel);
-               if (f > self.ladder_entity.speed)
-                       wishvel *= (self.ladder_entity.speed / f);
-
-               self.watertype = self.ladder_entity.skin;
-               f = self.ladder_entity.origin_z + self.ladder_entity.maxs_z;
-               if ((self.origin_z + self.view_ofs_z) < f)
-                       self.waterlevel = WATERLEVEL_SUBMERGED;
-               else if ((self.origin_z + (self.mins_z + self.maxs_z) * 0.5) < f)
-                       self.waterlevel = WATERLEVEL_SWIMMING;
-               else if ((self.origin_z + self.mins_z + 1) < f)
-                       self.waterlevel = WATERLEVEL_WETFEET;
+               if (f > this.ladder_entity.speed)
+                       wishvel *= (this.ladder_entity.speed / f);
+
+               this.watertype = this.ladder_entity.skin;
+               f = this.ladder_entity.origin_z + this.ladder_entity.maxs_z;
+               if ((this.origin_z + this.view_ofs_z) < f)
+                       this.waterlevel = WATERLEVEL_SUBMERGED;
+               else if ((this.origin_z + (this.mins_z + this.maxs_z) * 0.5) < f)
+                       this.waterlevel = WATERLEVEL_SWIMMING;
+               else if ((this.origin_z + this.mins_z + 1) < f)
+                       this.waterlevel = WATERLEVEL_WETFEET;
                else
                {
-                       self.waterlevel = WATERLEVEL_NONE;
-                       self.watertype = CONTENT_EMPTY;
+                       this.waterlevel = WATERLEVEL_NONE;
+                       this.watertype = CONTENT_EMPTY;
                }
        }
        // acceleration
        vector wishdir = normalize(wishvel);
-       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(self) * maxspd_mod);
+       float wishspeed = min(vlen(wishvel), PHYS_MAXSPEED(this) * maxspd_mod);
 #ifdef SVQC
-       if (time >= self.teleport_time)
+       if (time >= this.teleport_time)
 #endif
                // water acceleration
-               PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE*maxspd_mod, 1, 0, 0, 0);
-       PM_ClientMovement_Move();
+               PM_Accelerate(this, wishdir, wishspeed, wishspeed, PHYS_ACCELERATE(this)*maxspd_mod, 1, 0, 0, 0);
+       PM_ClientMovement_Move(this);
 }
 
-void PM_jetpack(float maxspd_mod)
-{SELFPARAM();
-       //makevectors(self.v_angle.y * '0 1 0');
-       makevectors(self.v_angle);
-       vector wishvel = v_forward * self.movement_x
-                                       + v_right * self.movement_y;
+void PM_jetpack(entity this, float maxspd_mod)
+{
+       //makevectors(this.v_angle.y * '0 1 0');
+       makevectors(this.v_angle);
+       vector wishvel = v_forward * this.movement_x
+                                       + v_right * this.movement_y;
        // add remaining speed as Z component
-       float maxairspd = PHYS_MAXAIRSPEED(self) * max(1, maxspd_mod);
+       float maxairspd = PHYS_MAXAIRSPEED(this) * max(1, maxspd_mod);
        // fix speedhacks :P
        wishvel = normalize(wishvel) * min(1, vlen(wishvel) / maxairspd);
        // add the unused velocity as up component
        wishvel_z = 0;
 
-       // if (self.BUTTON_JUMP)
+       // if (this.BUTTON_JUMP)
                wishvel_z = sqrt(max(0, 1 - wishvel * wishvel));
 
        // it is now normalized, so...
@@ -1251,11 +992,11 @@ void PM_jetpack(float maxspd_mod)
        //print("best possible acceleration: ", ftos(best), "\n");
 
        float fxy, fz;
-       fxy = bound(0, 1 - (self.velocity * normalize(wishvel_x * '1 0 0' + wishvel_y * '0 1 0')) / PHYS_JETPACK_MAXSPEED_SIDE, 1);
+       fxy = bound(0, 1 - (this.velocity * normalize(wishvel_x * '1 0 0' + wishvel_y * '0 1 0')) / PHYS_JETPACK_MAXSPEED_SIDE, 1);
        if (wishvel_z - PHYS_GRAVITY(this) > 0)
-               fz = bound(0, 1 - self.velocity_z / PHYS_JETPACK_MAXSPEED_UP, 1);
+               fz = bound(0, 1 - this.velocity_z / PHYS_JETPACK_MAXSPEED_UP, 1);
        else
-               fz = bound(0, 1 + self.velocity_z / PHYS_JETPACK_MAXSPEED_UP, 1);
+               fz = bound(0, 1 + this.velocity_z / PHYS_JETPACK_MAXSPEED_UP, 1);
 
        float fvel;
        fvel = vlen(wishvel);
@@ -1264,8 +1005,8 @@ void PM_jetpack(float maxspd_mod)
        wishvel_z = (wishvel_z - PHYS_GRAVITY(this)) * fz + PHYS_GRAVITY(this);
 
        fvel = min(1, vlen(wishvel) / best);
-       if (PHYS_JETPACK_FUEL && !(ITEMS_STAT(self) & IT_UNLIMITED_WEAPON_AMMO))
-               f = min(1, PHYS_AMMO_FUEL(self) / (PHYS_JETPACK_FUEL * PHYS_INPUT_TIMELENGTH * fvel));
+       if (PHYS_JETPACK_FUEL && !(ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO))
+               f = min(1, PHYS_AMMO_FUEL(this) / (PHYS_JETPACK_FUEL * PHYS_INPUT_TIMELENGTH * fvel));
        else
                f = 1;
 
@@ -1273,30 +1014,36 @@ void PM_jetpack(float maxspd_mod)
 
        if (f > 0 && wishvel != '0 0 0')
        {
-               self.velocity = self.velocity + wishvel * f * PHYS_INPUT_TIMELENGTH;
-               UNSET_ONGROUND(self);
+               this.velocity = this.velocity + wishvel * f * PHYS_INPUT_TIMELENGTH;
+               UNSET_ONGROUND(this);
 
 #ifdef SVQC
-               if (!(ITEMS_STAT(self) & IT_UNLIMITED_WEAPON_AMMO))
-                       self.ammo_fuel -= PHYS_JETPACK_FUEL * PHYS_INPUT_TIMELENGTH * fvel * f;
+               if (!(ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO))
+                       this.ammo_fuel -= PHYS_JETPACK_FUEL * PHYS_INPUT_TIMELENGTH * fvel * f;
 
-               ITEMS_STAT(self) |= IT_USING_JETPACK;
+               ITEMS_STAT(this) |= IT_USING_JETPACK;
 
                // jetpack also inhibits health regeneration, but only for 1 second
-               self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
+               this.pauseregen_finished = max(this.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
 #endif
        }
 
 #ifdef CSQC
-       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(self) * PHYS_INPUT_TIMELENGTH;
-       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-               self.velocity_z -= g * 0.5;
-       else
-               self.velocity_z -= g;
-       PM_ClientMovement_Move();
-       if (!IS_ONGROUND(self) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
+       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
+       if(autocvar_cl_movement != 3)
+       {
                if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       self.velocity_z -= g * 0.5;
+                       this.velocity_z -= g * 0.5;
+               else
+                       this.velocity_z -= g;
+       }
+       PM_ClientMovement_Move(this);
+       if(autocvar_cl_movement != 3)
+       {
+               if (!IS_ONGROUND(this) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
+                       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
+                               this.velocity_z -= g * 0.5;
+       }
 #endif
 }
 
@@ -1337,10 +1084,10 @@ void PM_walk(entity this, float maxspd_mod)
                // apply ground friction
                const int realfriction = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
                        ? PHYS_FRICTION_SLICK
-                       : PHYS_FRICTION;
+                       : PHYS_FRICTION(this);
 
                float f = sqrt(f2);
-               f = 1 - PHYS_INPUT_TIMELENGTH * realfriction * ((f < PHYS_STOPSPEED) ? (PHYS_STOPSPEED / f) : 1);
+               f = 1 - PHYS_INPUT_TIMELENGTH * realfriction * ((f < PHYS_STOPSPEED(this)) ? (PHYS_STOPSPEED(this) / f) : 1);
                f = max(0, f);
                this.velocity *= f;
                /*
@@ -1349,72 +1096,80 @@ void PM_walk(entity this, float maxspd_mod)
                   Our goal is to invert this mess.
 
                   For the two cases we get:
-                       v = v0 * (1 - PHYS_INPUT_TIMELENGTH * (PHYS_STOPSPEED / v0) * PHYS_FRICTION)
-                         = v0 - PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED * PHYS_FRICTION
-                       v0 = v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED * PHYS_FRICTION
+                       v = v0 * (1 - PHYS_INPUT_TIMELENGTH * (PHYS_STOPSPEED(this) / v0) * PHYS_FRICTION(this))
+                         = v0 - PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this)
+                       v0 = v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this)
                   and
-                       v = v0 * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION)
-                       v0 = v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION)
+                       v = v0 * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
+                       v0 = v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
 
                   These cases would be chosen ONLY if:
-                       v0 < PHYS_STOPSPEED
-                       v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED * PHYS_FRICTION < PHYS_STOPSPEED
-                       v < PHYS_STOPSPEED * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION)
+                       v0 < PHYS_STOPSPEED(this)
+                       v + PHYS_INPUT_TIMELENGTH * PHYS_STOPSPEED(this) * PHYS_FRICTION(this) < PHYS_STOPSPEED(this)
+                       v < PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
                   and, respectively:
-                       v0 >= PHYS_STOPSPEED
-                       v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION) >= PHYS_STOPSPEED
-                       v >= PHYS_STOPSPEED * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION)
+                       v0 >= PHYS_STOPSPEED(this)
+                       v / (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this)) >= PHYS_STOPSPEED(this)
+                       v >= PHYS_STOPSPEED(this) * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION(this))
                 */
        }
        const float addspeed = wishspeed - this.velocity * wishdir;
        if (addspeed > 0)
        {
-               const float accelspeed = min(PHYS_ACCELERATE * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed);
+               const float accelspeed = min(PHYS_ACCELERATE(this) * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed);
                this.velocity += accelspeed * wishdir;
        }
-       const float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
-       if (!(GAMEPLAYFIX_NOGRAVITYONGROUND))
-               this.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1);
+#ifdef CSQC
+       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
+       if(autocvar_cl_movement != 3)
+       {
+               if (!(GAMEPLAYFIX_NOGRAVITYONGROUND))
+                       this.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1);
+       }
        if (vdist(this.velocity, >, 0))
-               PM_ClientMovement_Move();
-       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-               if (!IS_ONGROUND(this) || !GAMEPLAYFIX_NOGRAVITYONGROUND)
-                       this.velocity_z -= g * 0.5;
+               PM_ClientMovement_Move(this);
+       if(autocvar_cl_movement != 3)
+       {
+               if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
+                       if (!IS_ONGROUND(this) || !GAMEPLAYFIX_NOGRAVITYONGROUND)
+                               this.velocity_z -= g * 0.5;
+       }
+#endif
 }
 
-void PM_air(float buttons_prev, float maxspd_mod)
-{SELFPARAM();
-       makevectors(self.v_angle.y * '0 1 0');
-       vector wishvel = v_forward * self.movement.x
-                                       + v_right * self.movement.y;
+void PM_air(entity this, float buttons_prev, float maxspd_mod)
+{
+       makevectors(this.v_angle.y * '0 1 0');
+       vector wishvel = v_forward * this.movement.x
+                                       + v_right * this.movement.y;
        // acceleration
        vector wishdir = normalize(wishvel);
        float wishspeed = vlen(wishvel);
 
 #ifdef SVQC
-       if (time >= self.teleport_time)
+       if (time >= this.teleport_time)
 #else
        if (pmove_waterjumptime <= 0)
 #endif
        {
-               float maxairspd = PHYS_MAXAIRSPEED(self) * min(maxspd_mod, 1);
+               float maxairspd = PHYS_MAXAIRSPEED(this) * min(maxspd_mod, 1);
 
                // apply air speed limit
-               float airaccelqw = PHYS_AIRACCEL_QW(self);
+               float airaccelqw = PHYS_AIRACCEL_QW(this);
                float wishspeed0 = wishspeed;
                wishspeed = min(wishspeed, maxairspd);
-               if (IS_DUCKED(self))
+               if (IS_DUCKED(this))
                        wishspeed *= 0.5;
-               float airaccel = PHYS_AIRACCELERATE * min(maxspd_mod, 1);
+               float airaccel = PHYS_AIRACCELERATE(this) * min(maxspd_mod, 1);
 
-               float accelerating = (self.velocity * wishdir > 0);
+               float accelerating = (this.velocity * wishdir > 0);
                float wishspeed2 = wishspeed;
 
                // CPM: air control
-               if (PHYS_AIRSTOPACCELERATE)
+               if (PHYS_AIRSTOPACCELERATE(this))
                {
-                       vector curdir = normalize(vec2(self.velocity));
-                       airaccel += (PHYS_AIRSTOPACCELERATE*maxspd_mod - airaccel) * max(0, -(curdir * wishdir));
+                       vector curdir = normalize(vec2(this.velocity));
+                       airaccel += (PHYS_AIRSTOPACCELERATE(this)*maxspd_mod - airaccel) * max(0, -(curdir * wishdir));
                }
                // note that for straight forward jumping:
                // step = accel * PHYS_INPUT_TIMELENGTH * wishspeed0;
@@ -1424,45 +1179,51 @@ void PM_air(float buttons_prev, float maxspd_mod)
                // dv/dt = accel * maxspeed * (1 - accelqw) (when fast)
                // log dv/dt = logaccel + logmaxspeed (when slow)
                // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast)
-               float strafity = IsMoveInDirection(self.movement, -90) + IsMoveInDirection(self.movement, +90); // if one is nonzero, other is always zero
-               if (PHYS_MAXAIRSTRAFESPEED)
-                       wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED(self)*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod));
-               if (PHYS_AIRSTRAFEACCELERATE(self))
-                       airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE(self)*maxspd_mod);
-               if (PHYS_AIRSTRAFEACCEL_QW(self))
+               float strafity = IsMoveInDirection(this.movement, -90) + IsMoveInDirection(this.movement, +90); // if one is nonzero, other is always zero
+               if (PHYS_MAXAIRSTRAFESPEED(this))
+                       wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED(this)*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED(this)*maxspd_mod));
+               if (PHYS_AIRSTRAFEACCELERATE(this))
+                       airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE(this)*maxspd_mod);
+               if (PHYS_AIRSTRAFEACCEL_QW(this))
                        airaccelqw =
-               (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(self) : PHYS_AIRACCEL_QW(self)) >= 0) ? +1 : -1)
+               (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(this) : PHYS_AIRACCEL_QW(this)) >= 0) ? +1 : -1)
                *
-               (1 - GeomLerp(1 - fabs(PHYS_AIRACCEL_QW(self)), strafity, 1 - fabs(PHYS_AIRSTRAFEACCEL_QW(self))));
+               (1 - GeomLerp(1 - fabs(PHYS_AIRACCEL_QW(this)), strafity, 1 - fabs(PHYS_AIRSTRAFEACCEL_QW(this))));
                // !CPM
 
-               if (PHYS_WARSOWBUNNY_TURNACCEL && accelerating && self.movement.y == 0 && self.movement.x != 0)
-                       PM_AirAccelerate(wishdir, wishspeed2);
+               if (PHYS_WARSOWBUNNY_TURNACCEL(this) && accelerating && this.movement.y == 0 && this.movement.x != 0)
+                       PM_AirAccelerate(this, wishdir, wishspeed2);
                else
-                       PM_Accelerate(wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, PHYS_AIRACCEL_QW_STRETCHFACTOR(self), PHYS_AIRACCEL_SIDEWAYS_FRICTION / maxairspd, PHYS_AIRSPEEDLIMIT_NONQW(self));
+                       PM_Accelerate(this, wishdir, wishspeed, wishspeed0, airaccel, airaccelqw, PHYS_AIRACCEL_QW_STRETCHFACTOR(this), PHYS_AIRACCEL_SIDEWAYS_FRICTION(this) / maxairspd, PHYS_AIRSPEEDLIMIT_NONQW(this));
 
-               if (PHYS_AIRCONTROL)
-                       CPM_PM_Aircontrol(wishdir, wishspeed2);
+               if (PHYS_AIRCONTROL(this))
+                       CPM_PM_Aircontrol(this, wishdir, wishspeed2);
        }
-       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(self) * PHYS_INPUT_TIMELENGTH;
+#ifdef CSQC
+       float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH;
+       if(autocvar_cl_movement != 3)
        if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-               self.velocity_z -= g * 0.5;
+               this.velocity_z -= g * 0.5;
        else
-               self.velocity_z -= g;
-       PM_ClientMovement_Move();
-       if (!IS_ONGROUND(self) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
+               this.velocity_z -= g;
+#endif
+       PM_ClientMovement_Move(this);
+#ifdef CSQC
+       if(autocvar_cl_movement != 3)
+       if (!IS_ONGROUND(this) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
                if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       self.velocity_z -= g * 0.5;
+                       this.velocity_z -= g * 0.5;
+#endif
 }
 
 // used for calculating airshots
-bool IsFlying(entity a)
+bool IsFlying(entity this)
 {
-       if(IS_ONGROUND(a))
+       if(IS_ONGROUND(this))
                return false;
-       if(a.waterlevel >= WATERLEVEL_SWIMMING)
+       if(this.waterlevel >= WATERLEVEL_SWIMMING)
                return false;
-       traceline(a.origin, a.origin - '0 0 48', MOVE_NORMAL, a);
+       traceline(this.origin, this.origin - '0 0 48', MOVE_NORMAL, this);
        if(trace_fraction < 1)
                return false;
        return true;
@@ -1505,10 +1266,10 @@ void PM_Main(entity this)
 #endif
 
 #ifdef SVQC
-       anticheat_physics();
+       anticheat_physics(this);
 #endif
 
-       if (PM_check_specialcommand(buttons))
+       if (PM_check_specialcommand(this, buttons))
                return;
 #ifdef SVQC
        if (sv_maxidle > 0)
@@ -1522,15 +1283,15 @@ void PM_Main(entity this)
        this.movement_old = this.movement;
        this.v_angle_old = this.v_angle;
 
-       PM_check_nickspam();
+       PM_check_nickspam(this);
 
-       PM_check_punch();
+       PM_check_punch(this);
 #ifdef SVQC
        if (IS_BOT_CLIENT(this))
        {
-               if (playerdemo_read())
+               if (playerdemo_read(this))
                        return;
-               bot_think();
+               WITH(entity, self, this, bot_think());
        }
 #endif
 
@@ -1561,13 +1322,11 @@ void PM_Main(entity this)
        this.disableclientprediction = 0;
 #endif
 
-       viewloc_PlayerPhysics();
-
-       PM_check_spider();
+       viewloc_PlayerPhysics(this);
 
-       PM_check_frozen();
+       PM_check_frozen(this);
 
-       PM_check_blocked();
+       PM_check_blocked(this);
 
        maxspeed_mod = 1;
 
@@ -1578,22 +1337,7 @@ void PM_Main(entity this)
        if (this.conveyor.state)
                this.velocity -= this.conveyor.movedir;
 
-#ifdef SVQC
-       MUTATOR_CALLHOOK(PlayerPhysics);
-#endif
-#ifdef CSQC
-       PM_multijump();
-#endif
-
-//     float forcedodge = 1;
-//     if(forcedodge) {
-//#ifdef CSQC
-//             PM_dodging_checkpressedkeys();
-//#endif
-//             PM_dodging();
-//             PM_ClientMovement_Move();
-//             return;
-//     }
+       MUTATOR_CALLHOOK(PlayerPhysics, this);
 
 #ifdef SVQC
        if (!IS_PLAYER(this))
@@ -1658,17 +1402,17 @@ void PM_Main(entity this)
        }
 
 #ifdef SVQC
-       if (!this.fixangle && !g_bugrigs)
+       if (!this.fixangle)
                this.angles = '0 1 0' * this.v_angle.y;
 #endif
 
-       PM_check_hitground();
+       PM_check_hitground(this);
 
        if(IsFlying(this))
                this.wasFlying = 1;
 
        if (IS_PLAYER(this))
-               CheckPlayerJump();
+               CheckPlayerJump(this);
 
        if (this.flags & FL_WATERJUMP)
        {
@@ -1681,30 +1425,26 @@ void PM_Main(entity this)
                }
        }
 
-#ifdef SVQC
-       else if (g_bugrigs && IS_PLAYER(this))
-               RaceCarPhysics();
-#endif
+       else if (MUTATOR_CALLHOOK(PM_Physics, this, maxspeed_mod))
+               { }
 
        else if (this.movetype == MOVETYPE_NOCLIP || this.movetype == MOVETYPE_FLY || this.movetype == MOVETYPE_FLY_WORLDONLY || MUTATOR_CALLHOOK(IsFlying, this))
-               PM_fly(maxspeed_mod);
+               PM_fly(this, maxspeed_mod);
 
        else if (this.waterlevel >= WATERLEVEL_SWIMMING)
-               PM_swim(maxspeed_mod);
+               PM_swim(this, maxspeed_mod);
 
        else if (time < this.ladder_time)
-               PM_ladder(maxspeed_mod);
+               PM_ladder(this, maxspeed_mod);
 
        else if (ITEMS_STAT(this) & IT_USING_JETPACK)
-               PM_jetpack(maxspeed_mod);
+               PM_jetpack(this, maxspeed_mod);
 
        else if (IS_ONGROUND(this))
                PM_walk(this, maxspeed_mod);
 
        else
-               PM_air(buttons_prev, maxspeed_mod);
-
-       PM_check_vortex();
+               PM_air(this, buttons_prev, maxspeed_mod);
 
 :end
        if (IS_ONGROUND(this))
index fb396d1596291b1ed51947a2a38093762e0e95bf..b266c3c0f5373b30f60d7f93e311c84003c582fe 100644 (file)
@@ -32,42 +32,24 @@ bool IsFlying(entity a);
 #define GAMEPLAYFIX_STEPMULTIPLETIMES       STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, this)
 #define GAMEPLAYFIX_UNSTICKPLAYERS          STAT(GAMEPLAYFIX_UNSTICKPLAYERS, this)
 
-#define PHYS_ACCELERATE                     STAT(MOVEVARS_ACCELERATE, this)
-#define PHYS_AIRACCELERATE                  STAT(MOVEVARS_AIRACCELERATE, this)
+#define PHYS_ACCELERATE(s)                  STAT(MOVEVARS_ACCELERATE, s)
+#define PHYS_AIRACCELERATE(s)               STAT(MOVEVARS_AIRACCELERATE, s)
 #define PHYS_AIRACCEL_QW(s)                 STAT(MOVEVARS_AIRACCEL_QW, s)
 #define PHYS_AIRACCEL_QW_STRETCHFACTOR(s)   STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, s)
-#define PHYS_AIRACCEL_SIDEWAYS_FRICTION     STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, this)
-#define PHYS_AIRCONTROL                     STAT(MOVEVARS_AIRCONTROL, this)
-#define PHYS_AIRCONTROL_PENALTY             STAT(MOVEVARS_AIRCONTROL_PENALTY, this)
-#define PHYS_AIRCONTROL_POWER               STAT(MOVEVARS_AIRCONTROL_POWER, this)
+#define PHYS_AIRACCEL_SIDEWAYS_FRICTION(s)  STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, s)
+#define PHYS_AIRCONTROL(s)                  STAT(MOVEVARS_AIRCONTROL, s)
+#define PHYS_AIRCONTROL_PENALTY(s)          STAT(MOVEVARS_AIRCONTROL_PENALTY, s)
+#define PHYS_AIRCONTROL_POWER(s)            STAT(MOVEVARS_AIRCONTROL_POWER, s)
 #define PHYS_AIRSPEEDLIMIT_NONQW(s)         STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, s)
-#define PHYS_AIRSTOPACCELERATE              STAT(MOVEVARS_AIRSTOPACCELERATE, this)
-#define PHYS_AIRSTRAFEACCELERATE(s)         STAT(MOVEVARS_AIRSTRAFEACCELERATE, this)
+#define PHYS_AIRSTOPACCELERATE(s)           STAT(MOVEVARS_AIRSTOPACCELERATE, s)
+#define PHYS_AIRSTRAFEACCELERATE(s)         STAT(MOVEVARS_AIRSTRAFEACCELERATE, s)
 #define PHYS_AIRSTRAFEACCEL_QW(s)           STAT(MOVEVARS_AIRSTRAFEACCEL_QW, s)
 
 #define PHYS_AMMO_FUEL(s)                   STAT(FUEL, s)
 
-#define PHYS_BUGRIGS                        STAT(BUGRIGS, this)
-#define PHYS_BUGRIGS_ACCEL                  STAT(BUGRIGS_ACCEL, this)
-#define PHYS_BUGRIGS_AIR_STEERING           STAT(BUGRIGS_AIR_STEERING, this)
-#define PHYS_BUGRIGS_ANGLE_SMOOTHING        STAT(BUGRIGS_ANGLE_SMOOTHING, this)
-#define PHYS_BUGRIGS_CAR_JUMPING            STAT(BUGRIGS_CAR_JUMPING, this)
-#define PHYS_BUGRIGS_FRICTION_AIR           STAT(BUGRIGS_FRICTION_AIR, this)
-#define PHYS_BUGRIGS_FRICTION_BRAKE         STAT(BUGRIGS_FRICTION_BRAKE, this)
-#define PHYS_BUGRIGS_FRICTION_FLOOR         STAT(BUGRIGS_FRICTION_FLOOR, this)
-#define PHYS_BUGRIGS_PLANAR_MOVEMENT        STAT(BUGRIGS_PLANAR_MOVEMENT, this)
-#define PHYS_BUGRIGS_REVERSE_SPEEDING       STAT(BUGRIGS_REVERSE_SPEEDING, this)
-#define PHYS_BUGRIGS_REVERSE_SPINNING       STAT(BUGRIGS_REVERSE_SPINNING, this)
-#define PHYS_BUGRIGS_REVERSE_STOPPING       STAT(BUGRIGS_REVERSE_STOPPING, this)
-#define PHYS_BUGRIGS_SPEED_POW              STAT(BUGRIGS_SPEED_POW, this)
-#define PHYS_BUGRIGS_SPEED_REF              STAT(BUGRIGS_SPEED_REF, this)
-#define PHYS_BUGRIGS_STEER                  STAT(BUGRIGS_STEER, this)
-
 #define PHYS_DODGING_FROZEN                                    STAT(DODGING_FROZEN, this)
 
-#define PHYS_DOUBLEJUMP                     STAT(DOUBLEJUMP, this)
-
-#define PHYS_FRICTION                       STAT(MOVEVARS_FRICTION, this)
+#define PHYS_FRICTION(s)                    STAT(MOVEVARS_FRICTION, s)
 #define PHYS_FRICTION_ONLAND                STAT(MOVEVARS_FRICTION_ONLAND, this)
 #define PHYS_FRICTION_SLICK                 STAT(MOVEVARS_FRICTION_SLICK, this)
 
@@ -86,26 +68,26 @@ bool IsFlying(entity a);
 
 #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS   STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, this)
 #define PHYS_JUMPSTEP                                          STAT(MOVEVARS_JUMPSTEP, this)
-#define PHYS_JUMPVELOCITY                   STAT(MOVEVARS_JUMPVELOCITY, this)
+#define PHYS_JUMPVELOCITY(s)                STAT(MOVEVARS_JUMPVELOCITY, s)
 
 #define PHYS_MAXAIRSPEED(s)                 STAT(MOVEVARS_MAXAIRSPEED, s)
-#define PHYS_MAXAIRSTRAFESPEED              STAT(MOVEVARS_MAXAIRSTRAFESPEED, this)
+#define PHYS_MAXAIRSTRAFESPEED(s)           STAT(MOVEVARS_MAXAIRSTRAFESPEED, s)
 #define PHYS_MAXSPEED(s)                    STAT(MOVEVARS_MAXSPEED, s)
 
 #define PHYS_NOSTEP                                                    STAT(NOSTEP, this)
 #define PHYS_STEPHEIGHT                     STAT(MOVEVARS_STEPHEIGHT, this)
 
-#define PHYS_STOPSPEED                      STAT(MOVEVARS_STOPSPEED, this)
+#define PHYS_STOPSPEED(s)                   STAT(MOVEVARS_STOPSPEED, s)
 
 #define PHYS_TRACK_CANJUMP(s)               STAT(MOVEVARS_TRACK_CANJUMP, s)
 
 #define PHYS_WALLFRICTION                                      STAT(MOVEVARS_WALLFRICTION, this)
 
-#define PHYS_WARSOWBUNNY_ACCEL              STAT(MOVEVARS_WARSOWBUNNY_ACCEL, this)
-#define PHYS_WARSOWBUNNY_AIRFORWARDACCEL    STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, this)
-#define PHYS_WARSOWBUNNY_BACKTOSIDERATIO    STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, this)
-#define PHYS_WARSOWBUNNY_TOPSPEED           STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, this)
-#define PHYS_WARSOWBUNNY_TURNACCEL          STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, this)
+#define PHYS_WARSOWBUNNY_ACCEL(s)           STAT(MOVEVARS_WARSOWBUNNY_ACCEL, s)
+#define PHYS_WARSOWBUNNY_AIRFORWARDACCEL(s) STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, s)
+#define PHYS_WARSOWBUNNY_BACKTOSIDERATIO(s) STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, s)
+#define PHYS_WARSOWBUNNY_TOPSPEED(s)        STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, s)
+#define PHYS_WARSOWBUNNY_TURNACCEL(s)       STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, s)
 
 #define UPWARD_VELOCITY_CLEARS_ONGROUND     STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, this)
 
@@ -114,9 +96,6 @@ bool IsFlying(entity a);
        const int FL_WATERJUMP = 2048;  // player jumping out of water
        const int FL_JUMPRELEASED = 4096;       // for jump debouncing
 
-       float PM_multijump_checkjump();
-       void PM_multijump();
-
        .float watertype;
        .float waterlevel;
        .int items;
index a57555edfa5b7b4f37bdc6a0fd962633e60f587f..d8a211745935001e2bd675fbad0bb500bd609819 100644 (file)
@@ -100,13 +100,14 @@ REGISTER_STAT(MULTIJUMP_DODGING, int, autocvar_g_multijump_dodging)
 REGISTER_STAT(MULTIJUMP_MAXSPEED, float, autocvar_g_multijump_maxspeed)
 REGISTER_STAT(MULTIJUMP_ADD, int, autocvar_g_multijump_add)
 REGISTER_STAT(MULTIJUMP_SPEED, float, autocvar_g_multijump_speed)
+REGISTER_STAT(MULTIJUMP_COUNT, int /*doesn't matter*/)
 REGISTER_STAT(MULTIJUMP, int, autocvar_g_multijump)
 REGISTER_STAT(DOUBLEJUMP, int, autocvar_sv_doublejump)
 
 #ifdef SVQC
-float g_bugrigs;
-float g_bugrigs_planar_movement;
-float g_bugrigs_planar_movement_car_jumping;
+bool g_bugrigs;
+bool g_bugrigs_planar_movement;
+bool g_bugrigs_planar_movement_car_jumping;
 float g_bugrigs_reverse_spinning;
 float g_bugrigs_reverse_speeding;
 float g_bugrigs_reverse_stopping;
index c93ccc488119fee00056e1efe1b9422053766a05..87496b217649b97e07041cb78ab5350f1e9be4aa 100644 (file)
@@ -801,7 +801,7 @@ spawnfunc(func_door)
 
 void door_draw(entity this)
 {
-       Movetype_Physics_NoMatchServer();
+       Movetype_Physics_NoMatchServer(this);
 
        trigger_draw_generic(this);
 }
index a419e62106ab3b7cab2ee2fff3686275594fc323..9e98d12ba25416508e57e06d22c865080fc35594 100644 (file)
@@ -124,7 +124,7 @@ spawnfunc(func_plat)
 #elif defined(CSQC)
 void plat_draw(entity this)
 {
-       Movetype_Physics_NoMatchServer();
+       Movetype_Physics_NoMatchServer(this);
        //Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
 }
 
index 0f827a60e37e4bdef4c8c031a84c5b927f9c11f7..80350e743b94ba07c27abf54cb3eb7c0f0bd47fb 100644 (file)
@@ -244,7 +244,7 @@ spawnfunc(func_train)
 void train_draw(entity this)
 {
        //Movetype_Physics_NoMatchServer();
-       Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
+       Movetype_Physics_MatchServer(this, autocvar_cl_projectiles_sloppy);
 }
 
 NET_HANDLE(ENT_CLIENT_TRAIN, bool isnew)
index e3b9c2e6963c5934506f804dc739f6a37be2e956..fa68533f4afcb594a6d727389fc65e4d23c78482 100644 (file)
@@ -15,7 +15,7 @@
 
 #elif defined(CSQC)
 
-       void _Movetype_LinkEdict(float touch_triggers);
+       void _Movetype_LinkEdict(entity this, float touch_triggers);
 
        #define SUB_ANGLES(s)   (s).move_angles
        #define SUB_VELOCITY    move_velocity
@@ -31,7 +31,7 @@
        void SUB_SETORIGIN(entity s, vector v)
        {SELFPARAM();
                s.move_origin = v;
-               WITH(entity, self, s, _Movetype_LinkEdict(true));
+               _Movetype_LinkEdict(s, true);
        }
 
 #endif
index 07378804f612efce71148c0ff2ac6db67e3f05d7..e05f519f4fb24d6decf4f8964e4a03d1e5dc22b1 100644 (file)
@@ -248,7 +248,7 @@ entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, flo
 void turret_gibboom();
 void turret_gib_draw(entity this)
 {
-       Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
+       Movetype_Physics_MatchTicrate(self, autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
 
        self.drawmask = MASK_NORMAL;
 
index 3875f1bdfc63cb0b7c9db95080feee32e45c3191..1d4647341dce61e0345f5be99240f5f6a167e5fb 100644 (file)
@@ -10,8 +10,8 @@ CLASS(EWheel, Turret)
 /* mins       */ ATTRIB(EWheel, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(EWheel, maxs, vector, '32 32 48');
 /* modelname  */ ATTRIB(EWheel, mdl, string, "ewheel-base2.md3");
-/* model      */ ATTRIB(EWheel, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(EWheel, head_model, string, strzone(strcat("models/turrets/", "ewheel-gun1.md3")));
+/* model      */ ATTRIB_STRZONE(EWheel, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(EWheel, head_model, string, strcat("models/turrets/", "ewheel-gun1.md3"));
 /* netname    */ ATTRIB(EWheel, netname, string, "ewheel");
 /* fullname   */ ATTRIB(EWheel, turret_name, string, _("eWheel Turret"));
     ATTRIB(EWheel, m_weapon, Weapon, WEP_EWHEEL);
index 1c9122f6733670c3841336c03a0693e760ace6d5..faaf89ffc0348ed7816ec11ca6a996c4ad07cfaa 100644 (file)
@@ -8,8 +8,8 @@ CLASS(Flac, Turret)
 /* mins       */ ATTRIB(Flac, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(Flac, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(Flac, mdl, string, "base.md3");
-/* model      */ ATTRIB(Flac, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(Flac, head_model, string, strzone(strcat("models/turrets/", "flac.md3")));
+/* model      */ ATTRIB_STRZONE(Flac, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(Flac, head_model, string, strcat("models/turrets/", "flac.md3"));
 /* netname    */ ATTRIB(Flac, netname, string, "flac");
 /* fullname   */ ATTRIB(Flac, turret_name, string, _("FLAC Cannon"));
     ATTRIB(Flac, m_weapon, Weapon, WEP_FLAC);
index 3f51c06c327bede49d1bc6cc77ec413ce6a0d5cf..889ba79a043563bdc6519718d2f5d86d18e8f6fe 100644 (file)
@@ -6,8 +6,8 @@ CLASS(FusionReactor, Turret)
 /* mins       */ ATTRIB(FusionReactor, mins, vector, '-34 -34 0');
 /* maxs       */ ATTRIB(FusionReactor, maxs, vector, '34 34 90');
 /* modelname  */ ATTRIB(FusionReactor, mdl, string, "base.md3");
-/* model      */ ATTRIB(FusionReactor, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(FusionReactor, head_model, string, strzone(strcat("models/turrets/", "reactor.md3")));
+/* model      */ ATTRIB_STRZONE(FusionReactor, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(FusionReactor, head_model, string, strcat("models/turrets/", "reactor.md3"));
 /* netname    */ ATTRIB(FusionReactor, netname, string, "fusionreactor");
 /* fullname   */ ATTRIB(FusionReactor, turret_name, string, _("Fusion Reactor"));
 ENDCLASS(FusionReactor)
index 203be93dbe20cd86c0c7afc54137f7f958d7bfae..dc256e98722b4ca814f704161d572e61e9c25938 100644 (file)
@@ -8,8 +8,8 @@ CLASS(Hellion, Turret)
 /* mins       */ ATTRIB(Hellion, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(Hellion, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(Hellion, mdl, string, "base.md3");
-/* model      */ ATTRIB(Hellion, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(Hellion, head_model, string, strzone(strcat("models/turrets/", "hellion.md3")));
+/* model      */ ATTRIB_STRZONE(Hellion, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(Hellion, head_model, string, strcat("models/turrets/", "hellion.md3"));
 /* netname    */ ATTRIB(Hellion, netname, string, "hellion");
 /* fullname   */ ATTRIB(Hellion, turret_name, string, _("Hellion Missile Turret"));
     ATTRIB(Hellion, m_weapon, Weapon, WEP_HELLION);
index 61d8318db89eb29a12bb47ee393f01b17af74d19..c5ddc6fc8f208a4a2231e4628410f5fa2dae7c02 100644 (file)
@@ -10,8 +10,8 @@ CLASS(HunterKiller, Turret)
 /* mins       */ ATTRIB(HunterKiller, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(HunterKiller, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(HunterKiller, mdl, string, "base.md3");
-/* model      */ ATTRIB(HunterKiller, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(HunterKiller, head_model, string, strzone(strcat("models/turrets/", "hk.md3")));
+/* model      */ ATTRIB_STRZONE(HunterKiller, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(HunterKiller, head_model, string, strcat("models/turrets/", "hk.md3"));
 /* netname    */ ATTRIB(HunterKiller, netname, string, "hk");
 /* fullname   */ ATTRIB(HunterKiller, turret_name, string, _("Hunter-Killer Turret"));
     ATTRIB(HunterKiller, m_weapon, Weapon, WEP_HK);
index 9911b97c6e21d86311b3e4d416607ec0c0a41630..61f256d7acbb4eb41568dcb8843a16bda569d390 100644 (file)
@@ -8,8 +8,8 @@ CLASS(MachineGunTurret, Turret)
 /* mins       */ ATTRIB(MachineGunTurret, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(MachineGunTurret, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(MachineGunTurret, mdl, string, "base.md3");
-/* model      */ ATTRIB(MachineGunTurret, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(MachineGunTurret, head_model, string, strzone(strcat("models/turrets/", "machinegun.md3")));
+/* model      */ ATTRIB_STRZONE(MachineGunTurret, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(MachineGunTurret, head_model, string, strcat("models/turrets/", "machinegun.md3"));
 /* netname    */ ATTRIB(MachineGunTurret, netname, string, "machinegun");
 /* fullname   */ ATTRIB(MachineGunTurret, turret_name, string, _("Machinegun Turret"));
     ATTRIB(MachineGunTurret, m_weapon, Weapon, WEP_TUR_MACHINEGUN);
index ae2d1d47ccc2a9753b43f260c19c5a6f5e2ef81b..3583af9f01d47d1ccfa762889a3125607dc1f51a 100644 (file)
@@ -8,8 +8,8 @@ CLASS(MLRSTurret, Turret)
 /* mins       */ ATTRIB(MLRSTurret, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(MLRSTurret, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(MLRSTurret, mdl, string, "base.md3");
-/* model      */ ATTRIB(MLRSTurret, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(MLRSTurret, head_model, string, strzone(strcat("models/turrets/", "mlrs.md3")));
+/* model      */ ATTRIB_STRZONE(MLRSTurret, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(MLRSTurret, head_model, string, strcat("models/turrets/", "mlrs.md3"));
 /* netname    */ ATTRIB(MLRSTurret, netname, string, "mlrs");
 /* fullname   */ ATTRIB(MLRSTurret, turret_name, string, _("MLRS Turret"));
     ATTRIB(MLRSTurret, m_weapon, Weapon, WEP_TUR_MLRS);
index 24d4d30c59791f777b8a8421c5d951246c08e7c0..24a476c03223127a6c43a581f727c8fd7bf70fd4 100644 (file)
@@ -8,8 +8,8 @@ CLASS(PhaserTurret, Turret)
 /* mins       */ ATTRIB(PhaserTurret, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(PhaserTurret, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(PhaserTurret, mdl, string, "base.md3");
-/* model      */ ATTRIB(PhaserTurret, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(PhaserTurret, head_model, string, strzone(strcat("models/turrets/", "phaser.md3")));
+/* model      */ ATTRIB_STRZONE(PhaserTurret, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(PhaserTurret, head_model, string, strcat("models/turrets/", "phaser.md3"));
 /* netname    */ ATTRIB(PhaserTurret, netname, string, "phaser");
 /* fullname   */ ATTRIB(PhaserTurret, turret_name, string, _("Phaser Cannon"));
     ATTRIB(PhaserTurret, m_weapon, Weapon, WEP_PHASER);
index 7ed255911b4d57f5ccea0d3c0f58838585446639..c36423381d49bd7940220c2f909bd24e5c99f678 100644 (file)
@@ -8,8 +8,8 @@ CLASS(PlasmaTurret, Turret)
 /* mins       */ ATTRIB(PlasmaTurret, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(PlasmaTurret, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(PlasmaTurret, mdl, string, "base.md3");
-/* model      */ ATTRIB(PlasmaTurret, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(PlasmaTurret, head_model, string, strzone(strcat("models/turrets/", "plasma.md3")));
+/* model      */ ATTRIB_STRZONE(PlasmaTurret, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(PlasmaTurret, head_model, string, strcat("models/turrets/", "plasma.md3"));
 /* netname    */ ATTRIB(PlasmaTurret, netname, string, "plasma");
 /* fullname   */ ATTRIB(PlasmaTurret, turret_name, string, _("Plasma Cannon"));
     ATTRIB(PlasmaTurret, m_weapon, Weapon, WEP_PLASMA);
index cb78547a26cdc9705c53508f01717b4a463bddfc..d391815828dad6ef5b84d15e8dcfce98d94eac1d 100644 (file)
@@ -12,8 +12,8 @@ CLASS(DualPlasmaTurret, PlasmaTurret)
 /* mins       */ ATTRIB(DualPlasmaTurret, mins, vector, '-32 -32 0');
 /* maxs       */ ATTRIB(DualPlasmaTurret, maxs, vector, '32 32 64');
 /* modelname  */ ATTRIB(DualPlasmaTurret, mdl, string, "base.md3");
-/* model      */ ATTRIB(DualPlasmaTurret, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(DualPlasmaTurret, head_model, string, strzone(strcat("models/turrets/", "plasmad.md3")));
+/* model      */ ATTRIB_STRZONE(DualPlasmaTurret, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(DualPlasmaTurret, head_model, string, strcat("models/turrets/", "plasmad.md3"));
 /* netname    */ ATTRIB(DualPlasmaTurret, netname, string, "plasma_dual");
 /* fullname   */ ATTRIB(DualPlasmaTurret, turret_name, string, _("Dual Plasma Cannon"));
     ATTRIB(DualPlasmaTurret, m_weapon, Weapon, WEP_PLASMA_DUAL);
index 16a9e423d3844875bf3f2bca448466f64c912e9d..051137c4f6f153da7d89eb5c6db77a3bdc5f246b 100644 (file)
@@ -8,8 +8,8 @@ CLASS(TeslaCoil, Turret)
 /* mins       */ ATTRIB(TeslaCoil, mins, vector, '-60 -60 0');
 /* maxs       */ ATTRIB(TeslaCoil, maxs, vector, '60 60 128');
 /* modelname  */ ATTRIB(TeslaCoil, mdl, string, "tesla_base.md3");
-/* model      */ ATTRIB(TeslaCoil, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(TeslaCoil, head_model, string, strzone(strcat("models/turrets/", "tesla_head.md3")));
+/* model      */ ATTRIB_STRZONE(TeslaCoil, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(TeslaCoil, head_model, string, strcat("models/turrets/", "tesla_head.md3"));
 /* netname    */ ATTRIB(TeslaCoil, netname, string, "tesla");
 /* fullname   */ ATTRIB(TeslaCoil, turret_name, string, _("Tesla Coil"));
     ATTRIB(TeslaCoil, m_weapon, Weapon, WEP_TESLA);
index f7c5e48f6c45929fb5b144873c1c4de4cc1cb6d9..97167eb3660e70eeb14973811793fe58a5403cb9 100644 (file)
@@ -10,8 +10,8 @@ CLASS(WalkerTurret, Turret)
 /* mins       */ ATTRIB(WalkerTurret, mins, vector, '-70 -70 0');
 /* maxs       */ ATTRIB(WalkerTurret, maxs, vector, '70 70 95');
 /* modelname  */ ATTRIB(WalkerTurret, mdl, string, "walker_body.md3");
-/* model      */ ATTRIB(WalkerTurret, model, string, strzone(strcat("models/turrets/", this.mdl)));
-/* head_model */ ATTRIB(WalkerTurret, head_model, string, strzone(strcat("models/turrets/", "walker_head_minigun.md3")));
+/* model      */ ATTRIB_STRZONE(WalkerTurret, model, string, strcat("models/turrets/", this.mdl));
+/* head_model */ ATTRIB_STRZONE(WalkerTurret, head_model, string, strcat("models/turrets/", "walker_head_minigun.md3"));
 /* netname    */ ATTRIB(WalkerTurret, netname, string, "walker");
 /* fullname   */ ATTRIB(WalkerTurret, turret_name, string, _("Walker Turret"));
     ATTRIB(WalkerTurret, m_weapon, Weapon, WEP_WALKER);
index 3e380ca696d06e0a66b0d3bde2423c997fccaa93..b322741f29d5a6fd60ed670cd8fff51af58452e4 100644 (file)
@@ -609,6 +609,8 @@ float cvar_settemp_restore()
                if(cvar_type(e.netname))
                {
                        cvar_set(e.netname, e.message);
+                       strunzone(e.netname);
+                       strunzone(e.message);
                        remove(e);
                        ++i;
                }
@@ -1340,6 +1342,7 @@ void m_shutdown()
        {
                shutdown_running = 1;
                Shutdown();
+               shutdownhooks();
        }
        cvar_settemp_restore(); // this must be done LAST, but in any case
 }
index 6783a92cc9a4aa1d128ded8cdb73572b3b30e337..b86880dd27df0d7a80f8b4b1f0c04726de86f0e1 100644 (file)
@@ -268,7 +268,7 @@ void RaptorCBShellfragDraw(entity this)
     if(wasfreed(self))
         return;
 
-    Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
+    Movetype_Physics_MatchTicrate(self, autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
     self.move_avelocity += randomvec() * 15;
     self.renderflags = 0;
 
index 9e3e2489128cc60e2fe7db31e2ed6982e642d244..0ad4d338218c07b4779c739a530385caf1b3ec8f 100644 (file)
@@ -9,52 +9,52 @@
 #endif
 
 // client movement
-void viewloc_PlayerPhysics()
-{SELFPARAM();
-       if(self.viewloc)
+void viewloc_PlayerPhysics(entity this)
+{
+       if(this.viewloc)
        {
-               vector oldmovement = self.movement;
-               self.movement_x = oldmovement_y;
-               self.movement_y = 0;
+               vector oldmovement = this.movement;
+               this.movement_x = oldmovement_y;
+               this.movement_y = 0;
 
-               if(self.movement_x < 0)
-                       self.movement_x = -self.movement_x;
+               if(this.movement_x < 0)
+                       this.movement_x = -this.movement_x;
 
                vector level_start, level_end;
-               level_start = self.viewloc.enemy.origin;
-               level_end = self.viewloc.goalentity.origin;
+               level_start = this.viewloc.enemy.origin;
+               level_end = this.viewloc.goalentity.origin;
                vector forward, backward;
                forward = vectoangles(normalize(level_end - level_start));
                backward = vectoangles(normalize(level_start - level_end));
 
-               if(self.movement_x < 0) // left
-                       self.angles_y = backward_y;
-               if(self.movement_x > 0) // right
-                       self.angles_y = forward_y;
+               if(this.movement_x < 0) // left
+                       this.angles_y = backward_y;
+               if(this.movement_x > 0) // right
+                       this.angles_y = forward_y;
 
                if(oldmovement_x > 0)
 #ifdef CSQC
                        input_angles_x =
 #endif
-                       self.v_angle_x = self.angles_x = -50;
+                       this.v_angle_x = this.angles_x = -50;
                else if(oldmovement_x < 0)
 #ifdef CSQC
                        input_angles_x =
 #endif
-                       self.v_angle_x = self.angles_x = 50;
+                       this.v_angle_x = this.angles_x = 50;
 
-               //if(!PHYS_INPUT_BUTTON_CROUCH(self) && !IS_DUCKED(self))
+               //if(!PHYS_INPUT_BUTTON_CROUCH(this) && !IS_DUCKED(this))
 #ifdef SVQC
-                       //self.BUTTON_CROUCH = (oldmovement_x < 0);
+                       //this.BUTTON_CROUCH = (oldmovement_x < 0);
                        if (oldmovement.x < 0)
-                               self.BUTTON_CROUCH = true;
+                               this.BUTTON_CROUCH = true;
 #elif defined(CSQC)
                        if (oldmovement.x < 0)
                        {
                                input_buttons |= BIT(4);
-                               self.flags |= FL_DUCKED;
+                               this.flags |= FL_DUCKED;
                        }
-                       //else { input_buttons &= ~16; self.flags &= ~FL_DUCKED; }
+                       //else { input_buttons &= ~16; this.flags &= ~FL_DUCKED; }
 #endif
        }
 }
@@ -76,7 +76,7 @@ void viewloc_SetTags()
 vector old_camera_angle = '0 0 0';
 void viewloc_SetViewLocation()
 {
-       entity view = CSQCModel_server2csqc(player_localentnum);
+       entity view = CSQCModel_server2csqc(player_localentnum - 1);
        if (!view) return;
        //NOTE: the "cam_" cvars sould probably be changed out with a spawnflag or an entity key. I have it like this for my testing -- Player_2
        if(view.viewloc && !wasfreed(view.viewloc) && view.viewloc.enemy && view.viewloc.goalentity)
index a86d8b4a42e6ef1acd94db79408dc5e2ab47d0e5..ceebe9c02caee4677c813ed3ee4ce74de6d0d232 100644 (file)
@@ -3,7 +3,7 @@
 
 .entity viewloc;
 
-void viewloc_PlayerPhysics();
+void viewloc_PlayerPhysics(entity this);
 
 #ifdef CSQC
 
index b795cb7e9f393559e6d2d02a9226bafecebc4c18..dd1b1b1b9ca0cc93bda906d93bad71aa6486ff95 100644 (file)
@@ -744,7 +744,7 @@ void Draw_Shockwave(entity this)
        if(a < ALPHA_MIN_VISIBLE) { remove(self); }
 
        // WEAPONTODO: save this only once when creating the entity
-       vector sw_color = getcsqcplayercolor(self.sv_entnum); // GetTeamRGB(GetPlayerColor(self.sv_entnum));
+       vector sw_color = getcsqcplayercolor(self.sv_entnum - 1); // GetTeamRGB(GetPlayerColor(self.sv_entnum));
 
        // WEAPONTODO: trace to find what we actually hit
        vector endpos = (self.sw_shotorg + (self.sw_shotdir * self.sw_distance));
index 8059f3272bcfddc8112579e22bc8ccd32f7de7fc..6e7e386e5de48ef6b89101280ea01b3e2c5e79e7 100644 (file)
@@ -103,7 +103,7 @@ void VaporizerBeam_Draw(entity this)
        string tex = "particles/lgbeam";
        if(this.cnt)
                tex = "particles/gauntletbeam";
-       vector rgb = getcsqcplayercolor(this.sv_entnum);
+       vector rgb = getcsqcplayercolor(this.sv_entnum - 1);
        rgb *= (1 + autocvar_cl_vaporizerbeam_colorboost);
 
        float fail = (self.nextthink - time);
index 5e31fbdbeee71536b8dcf7c19dc10b0417a131d6..ad8c6600d8edc11d1526114efa3733a37fe31276 100644 (file)
@@ -104,6 +104,22 @@ NET_HANDLE(TE_CSQC_VORTEXBEAMPARTICLE, bool isNew)
 spawnfunc(weapon_vortex) { weapon_defaultspawnfunc(this, WEP_VORTEX); }
 spawnfunc(weapon_nex) { spawnfunc_weapon_vortex(this); }
 
+REGISTER_MUTATOR(vortex_charge, true);
+
+MUTATOR_HOOKFUNCTION(vortex_charge, GetPressedKeys)
+{SELFPARAM();
+       // WEAPONTODO
+       float xyspeed = vlen(vec2(self.velocity));
+       if (self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge) && WEP_CVAR(vortex, charge_velocity_rate) && xyspeed > WEP_CVAR(vortex, charge_minspeed))
+       {
+               // add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed
+               xyspeed = min(xyspeed, WEP_CVAR(vortex, charge_maxspeed));
+               float f = (xyspeed - WEP_CVAR(vortex, charge_minspeed)) / (WEP_CVAR(vortex, charge_maxspeed) - WEP_CVAR(vortex, charge_minspeed));
+               // add the extra charge
+               self.vortex_charge = min(1, self.vortex_charge + WEP_CVAR(vortex, charge_velocity_rate) * f * PHYS_INPUT_TIMELENGTH);
+       }
+}
+
 void W_Vortex_Attack(Weapon thiswep, float issecondary)
 {SELFPARAM();
        float mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, myammo, charge;
index 97483b518f459c7d96752d7c0b73868def0285db..24d2df747cf1c3dd649189e8b4a77382532b9b7b 100644 (file)
@@ -52,7 +52,6 @@
 #include "noise.qc"
 #include "oo.qh"
 #include "p2mathlib.qc"
-#include "player.qh"
 #include "progname.qh"
 #include "random.qc"
 #include "registry.qh"
index c059149473075de5d68041b927d9df3ae006bf86..c2aae2b7b5476f529eaa977840852bdb5fa55045 100644 (file)
@@ -16,6 +16,7 @@ typedef int ArrayList;
                } \
        } \
        while (0)
+#define AL_delete(this) buf_del(this)
 
 #define _AL_type__s() string
 #define AL_gets(this, idx) bufstr_get(this, idx)
index 24ce56d70cfc9925fc6fe22f356a14c5b8641517..892c692d87319999e717fd5650d9e572dd4c140e 100644 (file)
@@ -7,60 +7,60 @@
 //  Time processing and counting functions/macros
 // ===============================================
 
-#define count_years_decs(time, decs) sprintf(ZCTX(_("CI_DEC^%s years")), ftos_decimals(time, decs))
+#define count_years_decs(time, decs) sprintf(CTX(_("CI_DEC^%s years")), ftos_decimals(time, decs))
 #define count_years(time) \
        count_fill(time, \
-       ZCTX(_("CI_ZER^%d years")), /* zeroth */ \
-       ZCTX(_("CI_FIR^%d year")),  /* first */ \
-       ZCTX(_("CI_SEC^%d years")), /* year */ \
-       ZCTX(_("CI_THI^%d years")), /* third */ \
-       ZCTX(_("CI_MUL^%d years"))) /* multi */
+       CTX(_("CI_ZER^%d years")), /* zeroth */ \
+       CTX(_("CI_FIR^%d year")),  /* first */ \
+       CTX(_("CI_SEC^%d years")), /* year */ \
+       CTX(_("CI_THI^%d years")), /* third */ \
+       CTX(_("CI_MUL^%d years"))) /* multi */
 
-#define count_weeks_decs(time, decs) sprintf(ZCTX(_("CI_DEC^%s weeks")), ftos_decimals(time, decs))
+#define count_weeks_decs(time, decs) sprintf(CTX(_("CI_DEC^%s weeks")), ftos_decimals(time, decs))
 #define count_weeks(time) \
        count_fill(time, \
-       ZCTX(_("CI_ZER^%d weeks")), /* zeroth */ \
-       ZCTX(_("CI_FIR^%d week")),  /* first */ \
-       ZCTX(_("CI_SEC^%d weeks")), /* week */ \
-       ZCTX(_("CI_THI^%d weeks")), /* third */ \
-       ZCTX(_("CI_MUL^%d weeks"))) /* multi */
+       CTX(_("CI_ZER^%d weeks")), /* zeroth */ \
+       CTX(_("CI_FIR^%d week")),  /* first */ \
+       CTX(_("CI_SEC^%d weeks")), /* week */ \
+       CTX(_("CI_THI^%d weeks")), /* third */ \
+       CTX(_("CI_MUL^%d weeks"))) /* multi */
 
-#define count_days_decs(time, decs) sprintf(ZCTX(_("CI_DEC^%s days")), ftos_decimals(time, decs))
+#define count_days_decs(time, decs) sprintf(CTX(_("CI_DEC^%s days")), ftos_decimals(time, decs))
 #define count_days(time) \
        count_fill(time, \
-       ZCTX(_("CI_ZER^%d days")), /* zeroth */ \
-       ZCTX(_("CI_FIR^%d day")),  /* first */ \
-       ZCTX(_("CI_SEC^%d days")), /* day */ \
-       ZCTX(_("CI_THI^%d days")), /* third */ \
-       ZCTX(_("CI_MUL^%d days"))) /* multi */
+       CTX(_("CI_ZER^%d days")), /* zeroth */ \
+       CTX(_("CI_FIR^%d day")),  /* first */ \
+       CTX(_("CI_SEC^%d days")), /* day */ \
+       CTX(_("CI_THI^%d days")), /* third */ \
+       CTX(_("CI_MUL^%d days"))) /* multi */
 
-#define count_hours_decs(time, decs) sprintf(ZCTX(_("CI_DEC^%s hours")), ftos_decimals(time, decs))
+#define count_hours_decs(time, decs) sprintf(CTX(_("CI_DEC^%s hours")), ftos_decimals(time, decs))
 #define count_hours(time) \
        count_fill(time, \
-       ZCTX(_("CI_ZER^%d hours")), /* zeroth */ \
-       ZCTX(_("CI_FIR^%d hour")),  /* first */ \
-       ZCTX(_("CI_SEC^%d hours")), /* hour */ \
-       ZCTX(_("CI_THI^%d hours")), /* third */ \
-       ZCTX(_("CI_MUL^%d hours"))) /* multi */
+       CTX(_("CI_ZER^%d hours")), /* zeroth */ \
+       CTX(_("CI_FIR^%d hour")),  /* first */ \
+       CTX(_("CI_SEC^%d hours")), /* hour */ \
+       CTX(_("CI_THI^%d hours")), /* third */ \
+       CTX(_("CI_MUL^%d hours"))) /* multi */
 
 
-#define count_minutes_decs(time, decs) sprintf(ZCTX(_("CI_DEC^%s minutes")), ftos_decimals(time, decs))
+#define count_minutes_decs(time, decs) sprintf(CTX(_("CI_DEC^%s minutes")), ftos_decimals(time, decs))
 #define count_minutes(time) \
        count_fill(time, \
-       ZCTX(_("CI_ZER^%d minutes")), /* zeroth */ \
-       ZCTX(_("CI_FIR^%d minute")),  /* first */ \
-       ZCTX(_("CI_SEC^%d minutes")), /* minute */ \
-       ZCTX(_("CI_THI^%d minutes")), /* third */ \
-       ZCTX(_("CI_MUL^%d minutes"))) /* multi */
+       CTX(_("CI_ZER^%d minutes")), /* zeroth */ \
+       CTX(_("CI_FIR^%d minute")),  /* first */ \
+       CTX(_("CI_SEC^%d minutes")), /* minute */ \
+       CTX(_("CI_THI^%d minutes")), /* third */ \
+       CTX(_("CI_MUL^%d minutes"))) /* multi */
 
-#define count_seconds_decs(time, decs) sprintf(ZCTX(_("CI_DEC^%s seconds")), ftos_decimals(time, decs))
+#define count_seconds_decs(time, decs) sprintf(CTX(_("CI_DEC^%s seconds")), ftos_decimals(time, decs))
 #define count_seconds(time) \
        count_fill(time, \
-       ZCTX(_("CI_ZER^%d seconds")), /* zeroth */ \
-       ZCTX(_("CI_FIR^%d second")),  /* first */ \
-       ZCTX(_("CI_SEC^%d seconds")), /* second */ \
-       ZCTX(_("CI_THI^%d seconds")), /* third */ \
-       ZCTX(_("CI_MUL^%d seconds"))) /* multi */
+       CTX(_("CI_ZER^%d seconds")), /* zeroth */ \
+       CTX(_("CI_FIR^%d second")),  /* first */ \
+       CTX(_("CI_SEC^%d seconds")), /* second */ \
+       CTX(_("CI_THI^%d seconds")), /* third */ \
+       CTX(_("CI_MUL^%d seconds"))) /* multi */
 
 string count_ordinal(int interval)
 {
index f9c23485e5d8e0206735b9310e965e00f535c68a..e84294522280bbe2a88061abc62991df71dcf027 100644 (file)
@@ -294,9 +294,13 @@ NET_HANDLE(ENT_CLIENT_MODEL, bool isnew)
        return true;
 }
 
-entity CSQCModel_server2csqc(int pl)
+/**
+ * @param i zero indexed player
+ */
+entity CSQCModel_server2csqc(int i)
 {
-       if (pl <= maxclients) return CSQCModel_players[pl - 1];
-       LOG_WARNINGF("player out of bounds: %d\n", pl);
-       return findfloat(NULL, entnum, pl);
+       if (i < maxclients) return CSQCModel_players[i];
+       ++i;
+       LOG_WARNINGF("player out of bounds: %d\n", i);
+       return findfloat(NULL, entnum, i);
 }
index 179350f9500bfa9b3ce5c10bcec0dac1342044dd..1f9d23b4dbec0d60141838685cf5d11b30f1f305 100644 (file)
@@ -35,7 +35,7 @@
 #undef CSQCMODEL_ENDIF
 #undef CSQCMODEL_IF
 
-entity CSQCModel_server2csqc(float pl);
+entity CSQCModel_server2csqc(int i);
 .float csqcmodel_teleported;
 
 // this is exported for custom frame animation code. Use with care.
index 49011fd64a70ab94ce76cade461ad9352107d722..e0eaccae11f957539f2d42f565b911482da16d89 100644 (file)
@@ -35,7 +35,6 @@
 #include "../../common/viewloc.qh"
 
 float autocvar_cl_movement_errorcompensation = 0;
-int autocvar_cl_movement = 1;
 
 // engine stuff
 float pmove_onground; // weird engine flag we shouldn't really use but have to for now
@@ -130,24 +129,35 @@ void CSQCPlayer_SavePrediction(entity this)
 }
 
 void CSQC_ClientMovement_PlayerMove_Frame(entity this);
+void _Movetype_Physics_Frame(entity this, float movedt);
 
-void PM_Movement_Move(entity this)
+void Movetype_Physics_Spam(entity this)  // optimized
 {
-       runstandardplayerphysics(this);
-#ifdef CSQC
-       this.flags =
-                       ((this.pmove_flags & PMF_DUCKED) ? FL_DUCKED : 0) |
-                       (!(this.pmove_flags & PMF_JUMP_HELD) ? FL_JUMPRELEASED : 0) |
-                       ((this.pmove_flags & PMF_ONGROUND) ? FL_ONGROUND : 0);
-#endif
+       _Movetype_Physics_Frame(this, PHYS_INPUT_TIMELENGTH);
+       if(wasfreed(this))
+               return;
+
+       this.avelocity = this.move_avelocity;
+       this.velocity = this.move_velocity;
+       this.angles = this.move_angles;
+       setorigin(this, this.move_origin);
 }
 
 void CSQCPlayer_Physics(entity this)
 {
-       switch (autocvar_cl_movement)
+       if(autocvar_cl_movement)
        {
-               case 1: CSQC_ClientMovement_PlayerMove_Frame(this); break;
-               case 2: PM_Movement_Move(this); break;
+               CSQC_ClientMovement_PlayerMove_Frame(this);
+
+               if(autocvar_cl_movement == 3)
+               {
+                       this.move_origin = this.origin;
+                       this.move_angles = this.angles;
+                       this.move_movetype = MOVETYPE_WALK; // temp
+                       this.move_velocity = this.velocity;
+                       this.move_avelocity = this.avelocity;
+                       Movetype_Physics_Spam(this);
+               }
        }
 }
 
@@ -275,7 +285,7 @@ void CSQCPlayer_SetCamera()
                setorigin(e, e.origin);
        }
 
-       const entity view = CSQCModel_server2csqc(player_localentnum);
+       const entity view = CSQCModel_server2csqc(player_localentnum - 1);
        if (view)
        {
                if (view != csqcplayer)
index 5b12dfa12cf7b60bbb6da8039c9057c58fbcefc2..1c97199c8e29684225649a78f116a9abca857778 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef LIB_CSQCMODEL_CL_PLAYER_H
 #define LIB_CSQCMODEL_CL_PLAYER_H
 
+int autocvar_cl_movement = 1;
+
 entity csqcplayer;
 float csqcplayer_status;
 const int CSQCPLAYERSTATUS_UNPREDICTED = 0;
index a32e9b47c7bed891127f9da79479388d10c89541..e49300c9615799921b7fe3930ca99c1d51769943 100644 (file)
@@ -16,8 +16,8 @@ float mean_evaluate(entity e, .float a, .float c, float mean)
        else return pow(e.(a) / e.(c), 1.0 / mean);
 }
 
-#define MEAN_ACCUMULATE(prefix, v, w) mean_accumulate(self, prefix##_accumulator, prefix##_count, prefix##_mean, v, w)
-#define MEAN_EVALUATE(prefix) mean_evaluate(self, prefix##_accumulator, prefix##_count, prefix##_mean)
+#define MEAN_ACCUMULATE(s, prefix, v, w) mean_accumulate(s, prefix##_accumulator, prefix##_count, prefix##_mean, v, w)
+#define MEAN_EVALUATE(s, prefix) mean_evaluate(s, prefix##_accumulator, prefix##_count, prefix##_mean)
 #define MEAN_DECLARE(prefix, m) float prefix##_mean = m; .float prefix##_count, prefix##_accumulator
 
 /** Returns a random number between -1.0 and 1.0 */
index a0d6f35db34b9ba8e76ba2af2c1aa3457779d1bb..e7d9a13b101b068f370d7eaf71c93550b7a6da83 100644 (file)
@@ -162,9 +162,19 @@ STATIC_INIT(RegisterClasses)
        class(cname).type name;                \
        INIT(cname) \
        { \
+               noref bool strzone; /* Error on strzone() calls. */ \
                this.name = val; \
        }
 
+#define ATTRIB_STRZONE(cname, name, type, val)      \
+       class(cname).type name;                \
+       INIT(cname) \
+       { \
+               if (this.name) \
+                       strunzone(this.name); \
+               this.name = strzone(val); \
+       }
+
 #define ATTRIBARRAY(cname, name, type, cnt) \
        class(cname).type name[cnt];
 
diff --git a/qcsrc/lib/player.qh b/qcsrc/lib/player.qh
deleted file mode 100644 (file)
index 6a8ce03..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifdef CSQC
-#ifndef PLAYER_H
-       #define PLAYER_H
-
-       #include "string.qh"
-
-       #include "../client/main.qh"
-       #include "../common/teams.qh"
-
-       int GetPlayerColorForce(int i)
-       {
-               if (!teamplay) return 0;
-               else return stof(getplayerkeyvalue(i, "colors")) & 15;
-       }
-
-       int GetPlayerColor(int i)
-       {
-               if (!playerslots[i].gotscores)  // unconnected
-                       return NUM_SPECTATOR;
-               else if (stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR) return NUM_SPECTATOR;
-               else return GetPlayerColorForce(i);
-       }
-
-       string GetPlayerName(int i)
-       {
-               return ColorTranslateRGB(getplayerkeyvalue(i, "name"));
-       }
-
-#endif
-#endif
index f2bdd1e26199984910fd35f0384985ac593de4e7..28c32f4432cc2ebf45904f857098f996bcdf24c4 100644 (file)
@@ -7,10 +7,12 @@
        #define _R_MAP(r, max) AL_declare(r); STATIC_INIT(r) { AL_init(r, max, NULL, e); }
        #define _R_GET(r, i) AL_gete(r, i)
        #define _R_SET(r, i, e) AL_sete(r, i, e)
+       #define _R_DEL(r) AL_delete(r)
 #else
        #define _R_MAP(r, max) entity r[max]
        #define _R_GET(r, i) r[i]
        #define _R_SET(r, i, e) r[i] = e
+       #define _R_DEL(r)
 #endif
 
 /**
@@ -24,6 +26,7 @@
        const int id##_MAX = max; \
        noref entity id##_first, id##_last; \
        _R_MAP(_##id, id##_MAX); \
+       SHUTDOWN(id) { _R_DEL(_##id); } \
        int id##_COUNT; \
        entity _##id##_from(int i, entity null) { if (i >= 0 && i < id##_COUNT) { entity e = _R_GET(_##id, i); if (e) return e; } return null; }
 
index 70eafd1b7d16ad89eb06e16d9d7d93bdae1dc983..534c2de02131cc3dc2737db2add776978bc192aa 100644 (file)
@@ -7,6 +7,8 @@ void __static_init_late() {}
 #define static_init_late() CALL_ACCUMULATED_FUNCTION(__static_init_late)
 void __static_init_precache() {}
 #define static_init_precache() CALL_ACCUMULATED_FUNCTION(__static_init_precache)
+void __shutdown() {}
+#define shutdownhooks() CALL_ACCUMULATED_FUNCTION(__shutdown)
 
 #define _STATIC_INIT(where, func) \
        void _static_##func(); \
@@ -16,5 +18,6 @@ void __static_init_precache() {}
 #define STATIC_INIT(func) _STATIC_INIT(__static_init,           func)
 #define STATIC_INIT_LATE(func) _STATIC_INIT(__static_init_late, func##_late)
 #define PRECACHE(func) _STATIC_INIT(__static_init_precache,     func##_precache)
+#define SHUTDOWN(func) _STATIC_INIT(__shutdown,                        func##_shutdown)
 
 #endif
index c5ad21ec19b02adaa7313afced076bd6350a5606..5d58a1b03ebaf927ca1c74a1ce3bddbc3dfcd030 100644 (file)
@@ -220,6 +220,8 @@ void XonoticPlayerModelSelector_resizeNotify(entity me, vector relOrigin, vector
 
 void XonoticPlayerModelSelector_showNotify(entity me)
 {
+       // Reinitialize self.
+       me.destroy(me);
        me.configureXonoticPlayerModelSelector(me);
 }
 #endif
index 6b3cea416de0158dfed3fa2ab2b24783d64ff26d..1450e8ff78e020033032b1dfa59a4d314e2aec8f 100644 (file)
@@ -149,15 +149,15 @@ int category_item[MAX_CATEGORIES];
 int category_draw_count;
 
 #define SLIST_CATEGORIES \
-       SLIST_CATEGORY(CAT_FAVORITED,    "",            "",             ZCTX(_("SLCAT^Favorites"))) \
-       SLIST_CATEGORY(CAT_RECOMMENDED,  "",            "",             ZCTX(_("SLCAT^Recommended"))) \
-       SLIST_CATEGORY(CAT_NORMAL,       "",            "CAT_SERVERS",  ZCTX(_("SLCAT^Normal Servers"))) \
-       SLIST_CATEGORY(CAT_SERVERS,      "CAT_NORMAL",  "CAT_SERVERS",  ZCTX(_("SLCAT^Servers"))) \
-       SLIST_CATEGORY(CAT_XPM,          "CAT_NORMAL",  "CAT_SERVERS",  ZCTX(_("SLCAT^Competitive Mode"))) \
-       SLIST_CATEGORY(CAT_MODIFIED,     "",            "CAT_SERVERS",  ZCTX(_("SLCAT^Modified Servers"))) \
-       SLIST_CATEGORY(CAT_OVERKILL,     "",            "CAT_SERVERS",  ZCTX(_("SLCAT^Overkill Mode"))) \
-       SLIST_CATEGORY(CAT_INSTAGIB,     "",            "CAT_SERVERS",  ZCTX(_("SLCAT^InstaGib Mode"))) \
-       SLIST_CATEGORY(CAT_DEFRAG,       "",            "CAT_SERVERS",  ZCTX(_("SLCAT^Defrag Mode")))
+       SLIST_CATEGORY(CAT_FAVORITED,    "",            "",             CTX(_("SLCAT^Favorites"))) \
+       SLIST_CATEGORY(CAT_RECOMMENDED,  "",            "",             CTX(_("SLCAT^Recommended"))) \
+       SLIST_CATEGORY(CAT_NORMAL,       "",            "CAT_SERVERS",  CTX(_("SLCAT^Normal Servers"))) \
+       SLIST_CATEGORY(CAT_SERVERS,      "CAT_NORMAL",  "CAT_SERVERS",  CTX(_("SLCAT^Servers"))) \
+       SLIST_CATEGORY(CAT_XPM,          "CAT_NORMAL",  "CAT_SERVERS",  CTX(_("SLCAT^Competitive Mode"))) \
+       SLIST_CATEGORY(CAT_MODIFIED,     "",            "CAT_SERVERS",  CTX(_("SLCAT^Modified Servers"))) \
+       SLIST_CATEGORY(CAT_OVERKILL,     "",            "CAT_SERVERS",  CTX(_("SLCAT^Overkill Mode"))) \
+       SLIST_CATEGORY(CAT_INSTAGIB,     "",            "CAT_SERVERS",  CTX(_("SLCAT^InstaGib Mode"))) \
+       SLIST_CATEGORY(CAT_DEFRAG,       "",            "CAT_SERVERS",  CTX(_("SLCAT^Defrag Mode")))
 
 #define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override
 #define SLIST_CATEGORY(name,enoverride,dioverride,str) \
index 61bb611fdc01cda06692cb77e537f35d46a92326..739695e77ea5aa9ff13d7a3887a37fa00762d9a2 100644 (file)
@@ -60,39 +60,39 @@ float movement_oddity(vector m0, vector m1)
                // returns 0 for: -1, -sqrt(0.5), 0 (angles that commonly happen with kbd)
 }
 
-void anticheat_physics()
-{SELFPARAM();
+void anticheat_physics(entity this)
+{
        float f;
 
        // div0_evade -> SPECTATORS
-       makevectors(self.v_angle);
-       if(self.anticheat_div0_evade_offset == 0)
+       makevectors(this.v_angle);
+       if(this.anticheat_div0_evade_offset == 0)
        {
                f = fabs(anticheat_div0_evade_evasion_delta - floor(anticheat_div0_evade_evasion_delta) - 0.5) * 2; // triangle function
-               self.anticheat_div0_evade_offset = servertime + sys_frametime * (3 * f - 1);
-               self.anticheat_div0_evade_v_angle = self.v_angle;
-               self.anticheat_div0_evade_forward_initial = v_forward;
-               MEAN_ACCUMULATE(anticheat_div0_evade, 0, 1);
+               this.anticheat_div0_evade_offset = servertime + sys_frametime * (3 * f - 1);
+               this.anticheat_div0_evade_v_angle = this.v_angle;
+               this.anticheat_div0_evade_forward_initial = v_forward;
+               MEAN_ACCUMULATE(this, anticheat_div0_evade, 0, 1);
        }
        else
        {
-               if(time < self.anticheat_div0_evade_offset)
-                       self.anticheat_div0_evade_v_angle = self.v_angle;
-               MEAN_ACCUMULATE(anticheat_div0_evade, 0.5 - 0.5 * (self.anticheat_div0_evade_forward_initial * v_forward), 1);
+               if(time < this.anticheat_div0_evade_offset)
+                       this.anticheat_div0_evade_v_angle = this.v_angle;
+               MEAN_ACCUMULATE(this, anticheat_div0_evade, 0.5 - 0.5 * (this.anticheat_div0_evade_forward_initial * v_forward), 1);
        }
 
-       MEAN_ACCUMULATE(anticheat_div0_strafebot_old, movement_oddity(self.movement, self.anticheat_div0_strafebot_movement_prev), 1);
-       self.anticheat_div0_strafebot_movement_prev = self.movement;
+       MEAN_ACCUMULATE(this, anticheat_div0_strafebot_old, movement_oddity(this.movement, this.anticheat_div0_strafebot_movement_prev), 1);
+       this.anticheat_div0_strafebot_movement_prev = this.movement;
 
        // Note: this actually tries to detect snap-aim.
-       if(vlen(self.anticheat_div0_strafebot_forward_prev) && time > self.anticheat_fixangle_endtime) {
-               float cosangle = self.anticheat_div0_strafebot_forward_prev * v_forward;
+       if(vlen(this.anticheat_div0_strafebot_forward_prev) && time > this.anticheat_fixangle_endtime) {
+               float cosangle = this.anticheat_div0_strafebot_forward_prev * v_forward;
                float angle = cosangle < -1 ? M_PI : cosangle > 1 ? 0 : acos(cosangle);
                /*
                if (angle >= 10 * M_PI / 180)
-                       printf("SNAP %s: %f for %f, %f since fixangle\n", self.netname, angle * 180 / M_PI, cosangle, time - self.anticheat_fixangle_endtime);
+                       printf("SNAP %s: %f for %f, %f since fixangle\n", this.netname, angle * 180 / M_PI, cosangle, time - this.anticheat_fixangle_endtime);
                */
-               MEAN_ACCUMULATE(anticheat_div0_strafebot_new, angle / M_PI, 1);
+               MEAN_ACCUMULATE(this, anticheat_div0_strafebot_new, angle / M_PI, 1);
 
                if (autocvar_slowmo > 0) {
                        // Technically this is a NOP, as the engine should be ensuring
@@ -101,49 +101,49 @@ void anticheat_physics()
                        float dt = max(0.001, frametime) / autocvar_slowmo;
 
                        float anglespeed = angle / dt;
-                       MEAN_ACCUMULATE(anticheat_idle_snapaim_signal, anglespeed, dt);
-                       MEAN_ACCUMULATE(anticheat_idle_snapaim_noise, anglespeed, dt);
-                       MEAN_ACCUMULATE(anticheat_idle_snapaim_m2, anglespeed, dt);
-                       MEAN_ACCUMULATE(anticheat_idle_snapaim_m3, anglespeed, dt);
-                       MEAN_ACCUMULATE(anticheat_idle_snapaim_m4, anglespeed, dt);
-                       MEAN_ACCUMULATE(anticheat_idle_snapaim_m7, anglespeed, dt);
-                       MEAN_ACCUMULATE(anticheat_idle_snapaim_m10, anglespeed, dt);
+                       MEAN_ACCUMULATE(this, anticheat_idle_snapaim_signal, anglespeed, dt);
+                       MEAN_ACCUMULATE(this, anticheat_idle_snapaim_noise, anglespeed, dt);
+                       MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m2, anglespeed, dt);
+                       MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m3, anglespeed, dt);
+                       MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m4, anglespeed, dt);
+                       MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m7, anglespeed, dt);
+                       MEAN_ACCUMULATE(this, anticheat_idle_snapaim_m10, anglespeed, dt);
                }
        }
-       self.anticheat_div0_strafebot_forward_prev = v_forward;
+       this.anticheat_div0_strafebot_forward_prev = v_forward;
 
        // generic speedhack detection: correlate anticheat_speedhack_movetime (UPDATED BEFORE THIS) and server time
-       self.anticheat_speedhack_movetime_frac += frametime;
-       f = floor(self.anticheat_speedhack_movetime_frac);
-       self.anticheat_speedhack_movetime_frac -= f;
-       self.anticheat_speedhack_movetime_count += f;
-       self.anticheat_speedhack_movetime = self.anticheat_speedhack_movetime_frac + self.anticheat_speedhack_movetime_count;
-       f = self.anticheat_speedhack_movetime - servertime;
-       if(self.anticheat_speedhack_offset == 0)
-               self.anticheat_speedhack_offset = f;
+       this.anticheat_speedhack_movetime_frac += frametime;
+       f = floor(this.anticheat_speedhack_movetime_frac);
+       this.anticheat_speedhack_movetime_frac -= f;
+       this.anticheat_speedhack_movetime_count += f;
+       this.anticheat_speedhack_movetime = this.anticheat_speedhack_movetime_frac + this.anticheat_speedhack_movetime_count;
+       f = this.anticheat_speedhack_movetime - servertime;
+       if(this.anticheat_speedhack_offset == 0)
+               this.anticheat_speedhack_offset = f;
        else
        {
-               MEAN_ACCUMULATE(anticheat_speedhack, max(0, f - self.anticheat_speedhack_offset), 1);
-               self.anticheat_speedhack_offset += (f - self.anticheat_speedhack_offset) * frametime * 0.1;
+               MEAN_ACCUMULATE(this, anticheat_speedhack, max(0, f - this.anticheat_speedhack_offset), 1);
+               this.anticheat_speedhack_offset += (f - this.anticheat_speedhack_offset) * frametime * 0.1;
        }
 
        // new generic speedhack detection
-       if (self.anticheat_speedhack_lasttime > 0) {
-               float dt = servertime - self.anticheat_speedhack_lasttime;
+       if (this.anticheat_speedhack_lasttime > 0) {
+               float dt = servertime - this.anticheat_speedhack_lasttime;
                const float falloff = 0.2;
-               self.anticheat_speedhack_accu *= exp(-dt * falloff);
-               self.anticheat_speedhack_accu += frametime * falloff;
+               this.anticheat_speedhack_accu *= exp(-dt * falloff);
+               this.anticheat_speedhack_accu += frametime * falloff;
                // NOTE: at cl_netfps x, this actually averages not to 1, but to 1/x * falloff / (1 - exp(-1/x * falloff))
                // For 15 netfps (absolute minimum bearable), and 0.2 falloff, this is: 1.0067
-               self.anticheat_speedhack_lasttime = servertime;
-               MEAN_ACCUMULATE(anticheat_speedhack_m1, self.anticheat_speedhack_accu, frametime);
-               MEAN_ACCUMULATE(anticheat_speedhack_m2, self.anticheat_speedhack_accu, frametime);
-               MEAN_ACCUMULATE(anticheat_speedhack_m3, self.anticheat_speedhack_accu, frametime);
-               MEAN_ACCUMULATE(anticheat_speedhack_m4, self.anticheat_speedhack_accu, frametime);
-               MEAN_ACCUMULATE(anticheat_speedhack_m5, self.anticheat_speedhack_accu, frametime);
+               this.anticheat_speedhack_lasttime = servertime;
+               MEAN_ACCUMULATE(this, anticheat_speedhack_m1, this.anticheat_speedhack_accu, frametime);
+               MEAN_ACCUMULATE(this, anticheat_speedhack_m2, this.anticheat_speedhack_accu, frametime);
+               MEAN_ACCUMULATE(this, anticheat_speedhack_m3, this.anticheat_speedhack_accu, frametime);
+               MEAN_ACCUMULATE(this, anticheat_speedhack_m4, this.anticheat_speedhack_accu, frametime);
+               MEAN_ACCUMULATE(this, anticheat_speedhack_m5, this.anticheat_speedhack_accu, frametime);
        } else {
-               self.anticheat_speedhack_accu = 1;
-               self.anticheat_speedhack_lasttime = servertime;
+               this.anticheat_speedhack_accu = 1;
+               this.anticheat_speedhack_lasttime = servertime;
        }
 }
 
@@ -176,46 +176,46 @@ void anticheat_report()
                return;
        // TODO(divVerent): Use xonstat to acquire good thresholds.
        GameLogEcho(strcat(":anticheat:_time:", ftos(self.playerid), ":", ftos(servertime - self.anticheat_jointime)));
-       GameLogEcho(strcat(":anticheat:speedhack:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_speedhack), 240, 0, 9999))); // Actually this one seems broken.
-       GameLogEcho(strcat(":anticheat:speedhack_m1:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_speedhack_m1), 240, 1.01, 1.25)));
-       GameLogEcho(strcat(":anticheat:speedhack_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_speedhack_m2), 240, 1.01, 1.25)));
-       GameLogEcho(strcat(":anticheat:speedhack_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_speedhack_m3), 240, 1.01, 1.25)));
-       GameLogEcho(strcat(":anticheat:speedhack_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_speedhack_m4), 240, 1.01, 1.25)));
-       GameLogEcho(strcat(":anticheat:speedhack_m5:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_speedhack_m5), 240, 1.01, 1.25)));
-       GameLogEcho(strcat(":anticheat:div0_strafebot_old:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_div0_strafebot_old), 120, 0.15, 0.4)));
-       GameLogEcho(strcat(":anticheat:div0_strafebot_new:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_div0_strafebot_new), 120, 0.25, 0.8)));
-       GameLogEcho(strcat(":anticheat:div0_evade:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_div0_evade), 120, 0.2, 0.5)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_signal) - MEAN_EVALUATE(anticheat_idle_snapaim_noise), 120, 0, 9999)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim_signal:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_signal), 120, 0, 9999)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim_noise:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_noise), 120, 0, 9999)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_m2), 120, 0, 9999)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_m3), 120, 0, 9999)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_m4), 120, 0, 9999)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim_m7:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_m7), 120, 0, 9999)));
-       GameLogEcho(strcat(":anticheat:idle_snapaim_m10:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(anticheat_idle_snapaim_m10), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:speedhack:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack), 240, 0, 9999))); // Actually this one seems broken.
+       GameLogEcho(strcat(":anticheat:speedhack_m1:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m1), 240, 1.01, 1.25)));
+       GameLogEcho(strcat(":anticheat:speedhack_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m2), 240, 1.01, 1.25)));
+       GameLogEcho(strcat(":anticheat:speedhack_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m3), 240, 1.01, 1.25)));
+       GameLogEcho(strcat(":anticheat:speedhack_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m4), 240, 1.01, 1.25)));
+       GameLogEcho(strcat(":anticheat:speedhack_m5:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_speedhack_m5), 240, 1.01, 1.25)));
+       GameLogEcho(strcat(":anticheat:div0_strafebot_old:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_div0_strafebot_old), 120, 0.15, 0.4)));
+       GameLogEcho(strcat(":anticheat:div0_strafebot_new:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_div0_strafebot_new), 120, 0.25, 0.8)));
+       GameLogEcho(strcat(":anticheat:div0_evade:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_div0_evade), 120, 0.2, 0.5)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_signal) - MEAN_EVALUATE(self, anticheat_idle_snapaim_noise), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim_signal:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_signal), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim_noise:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_noise), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim_m2:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m2), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim_m3:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m3), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim_m4:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m4), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim_m7:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m7), 120, 0, 9999)));
+       GameLogEcho(strcat(":anticheat:idle_snapaim_m10:", ftos(self.playerid), ":", anticheat_display(MEAN_EVALUATE(self, anticheat_idle_snapaim_m10), 120, 0, 9999)));
 }
 
 float anticheat_getvalue(string id)
 {SELFPARAM();
        switch(id) {
                case "_time": return servertime - self.anticheat_jointime;
-               case "speedhack": return MEAN_EVALUATE(anticheat_speedhack);
-               case "speedhack_m1": return MEAN_EVALUATE(anticheat_speedhack_m1);
-               case "speedhack_m2": return MEAN_EVALUATE(anticheat_speedhack_m2);
-               case "speedhack_m3": return MEAN_EVALUATE(anticheat_speedhack_m3);
-               case "speedhack_m4": return MEAN_EVALUATE(anticheat_speedhack_m4);
-               case "speedhack_m5": return MEAN_EVALUATE(anticheat_speedhack_m5);
-               case "div0_strafebot_old": return MEAN_EVALUATE(anticheat_div0_strafebot_old);
-               case "div0_strafebot_new": return MEAN_EVALUATE(anticheat_div0_strafebot_new);
-               case "div0_evade": return MEAN_EVALUATE(anticheat_div0_evade);
-               case "idle_snapaim": return MEAN_EVALUATE(anticheat_idle_snapaim_signal) - MEAN_EVALUATE(anticheat_idle_snapaim_noise);
-               case "idle_snapaim_signal": return MEAN_EVALUATE(anticheat_idle_snapaim_signal);
-               case "idle_snapaim_noise": return MEAN_EVALUATE(anticheat_idle_snapaim_noise);
-               case "idle_snapaim_m2": return MEAN_EVALUATE(anticheat_idle_snapaim_m2);
-               case "idle_snapaim_m3": return MEAN_EVALUATE(anticheat_idle_snapaim_m3);
-               case "idle_snapaim_m4": return MEAN_EVALUATE(anticheat_idle_snapaim_m4);
-               case "idle_snapaim_m7": return MEAN_EVALUATE(anticheat_idle_snapaim_m7);
-               case "idle_snapaim_m10": return MEAN_EVALUATE(anticheat_idle_snapaim_m10);
+               case "speedhack": return MEAN_EVALUATE(self, anticheat_speedhack);
+               case "speedhack_m1": return MEAN_EVALUATE(self, anticheat_speedhack_m1);
+               case "speedhack_m2": return MEAN_EVALUATE(self, anticheat_speedhack_m2);
+               case "speedhack_m3": return MEAN_EVALUATE(self, anticheat_speedhack_m3);
+               case "speedhack_m4": return MEAN_EVALUATE(self, anticheat_speedhack_m4);
+               case "speedhack_m5": return MEAN_EVALUATE(self, anticheat_speedhack_m5);
+               case "div0_strafebot_old": return MEAN_EVALUATE(self, anticheat_div0_strafebot_old);
+               case "div0_strafebot_new": return MEAN_EVALUATE(self, anticheat_div0_strafebot_new);
+               case "div0_evade": return MEAN_EVALUATE(self, anticheat_div0_evade);
+               case "idle_snapaim": return MEAN_EVALUATE(self, anticheat_idle_snapaim_signal) - MEAN_EVALUATE(self, anticheat_idle_snapaim_noise);
+               case "idle_snapaim_signal": return MEAN_EVALUATE(self, anticheat_idle_snapaim_signal);
+               case "idle_snapaim_noise": return MEAN_EVALUATE(self, anticheat_idle_snapaim_noise);
+               case "idle_snapaim_m2": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m2);
+               case "idle_snapaim_m3": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m3);
+               case "idle_snapaim_m4": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m4);
+               case "idle_snapaim_m7": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m7);
+               case "idle_snapaim_m10": return MEAN_EVALUATE(self, anticheat_idle_snapaim_m10);
        }
        return -1;
 }
index 6b9e4e3858c8ddd8ade6a24a913f6b7c43e8717a..9d2aa94050b0af16e39de8cabbf64493117afe30 100644 (file)
@@ -5,7 +5,7 @@ void anticheat_init();
 void anticheat_report();
 void anticheat_shutdown();
 
-void anticheat_physics();
+void anticheat_physics(entity this);
 void anticheat_spectatecopy(entity spectatee);
 void anticheat_prethink();
 
index 0ca8a0432e392cdac4a8e015f3363178413a252e..623b5f7662e7545f60a1f72f639e87eed99a32c1 100644 (file)
@@ -84,6 +84,8 @@ float autocvar_g_balance_contents_damagerate;
 float autocvar_g_balance_contents_drowndelay;
 int autocvar_g_balance_contents_playerdamage_drowning;
 int autocvar_g_balance_contents_playerdamage_lava;
+int autocvar_g_balance_contents_playerdamage_lava_burn; // 10 is a nice value
+float autocvar_g_balance_contents_playerdamage_lava_burn_time = 2.5; // note: damage is total across this time (not by dps)
 int autocvar_g_balance_contents_playerdamage_slime;
 int autocvar_g_balance_contents_projectiledamage;
 float autocvar_g_balance_damagepush_speedfactor;
@@ -155,7 +157,6 @@ string autocvar_g_ban_sync_uri;
 string autocvar_g_banned_list;
 bool autocvar_g_banned_list_idmode;
 bool autocvar_g_botclip_collisions;
-bool autocvar_g_bugrigs;
 bool autocvar_g_campaign;
 #define autocvar_g_campaign_forceteam cvar("g_campaign_forceteam")
 int autocvar_g_campaign_skill;
index 06df42cde9e149e43c2fb19a5d4869cb79d90236..2731c82445d3d82bffabb5b0017ba2069fd6f2f3 100644 (file)
@@ -570,8 +570,6 @@ void PutClientInServer()
                this.bot_attack = true;
                this.monster_attack = true;
 
-               this.spider_slowness = 0;
-
                this.BUTTON_ATCK = this.BUTTON_JUMP = this.BUTTON_ATCK2 = false;
 
                if (this.killcount == FRAGS_SPECTATOR) {
@@ -1199,7 +1197,7 @@ void ClientConnect ()
                        Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
                }
 
-               if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET(TUBA)))
+               if(g_weaponarena_weapons == WEPSET(TUBA))
                        stuffcmd(self, "cl_cmd settemp chase_active 1\n");
        }
 
index 9c7fb11fbd1c04e67787da0978fb9c077de3c5be..a7036ca4f29b70fa19aeb25756d4cfc701de71af 100644 (file)
@@ -551,6 +551,10 @@ spawnfunc(__init_dedicated_server)
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
 }
 
+void __init_dedicated_server_shutdown() {
+       MapInfo_Shutdown();
+}
+
 void Map_MarkAsRecent(string m);
 float world_already_spawned;
 void Nagger_Init();
@@ -1706,46 +1710,6 @@ float WinningCondition_Scores(float limit, float leadlimit)
        );
 }
 
-float WinningCondition_Race(float fraglimit)
-{
-       float wc;
-       entity p;
-       float n, c;
-
-       n = 0;
-       c = 0;
-       FOR_EACH_PLAYER(p)
-       {
-               ++n;
-               if(p.race_completed)
-                       ++c;
-       }
-       if(n && (n == c))
-               return WINNING_YES;
-       wc = WinningCondition_Scores(fraglimit, 0);
-
-       // ALWAYS initiate overtime, unless EVERYONE has finished the race!
-       if(wc == WINNING_YES || wc == WINNING_STARTSUDDENDEATHOVERTIME)
-       // do NOT support equality when the laps are all raced!
-               return WINNING_STARTSUDDENDEATHOVERTIME;
-       else
-               return WINNING_NEVER;
-}
-
-float WinningCondition_QualifyingThenRace(float limit)
-{
-       float wc;
-       wc = WinningCondition_Scores(limit, 0);
-
-       // NEVER initiate overtime
-       if(wc == WINNING_YES || wc == WINNING_STARTSUDDENDEATHOVERTIME)
-       {
-               return WINNING_YES;
-       }
-
-       return wc;
-}
-
 float WinningCondition_RanOutOfSpawns()
 {
        entity head;
@@ -2137,4 +2101,8 @@ void Shutdown()
        {
                LOG_INFO("NOTE: crashed before even initializing the world, not saving persistent data\n");
        }
+       else
+       {
+               __init_dedicated_server_shutdown();
+       }
 }
index 781ce5695a74c81f3ef8d62d1e62229d057b1ee2..0976e60e581c4751a8701bf293529ca57faad2ec 100644 (file)
@@ -249,22 +249,6 @@ void readlevelcvars()
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
 
-    g_bugrigs = cvar("g_bugrigs");
-    g_bugrigs_planar_movement = cvar("g_bugrigs_planar_movement");
-    g_bugrigs_planar_movement_car_jumping = cvar("g_bugrigs_planar_movement_car_jumping");
-    g_bugrigs_reverse_spinning = cvar("g_bugrigs_reverse_spinning");
-    g_bugrigs_reverse_speeding = cvar("g_bugrigs_reverse_speeding");
-    g_bugrigs_reverse_stopping = cvar("g_bugrigs_reverse_stopping");
-    g_bugrigs_air_steering = cvar("g_bugrigs_air_steering");
-    g_bugrigs_angle_smoothing = cvar("g_bugrigs_angle_smoothing");
-    g_bugrigs_friction_floor = cvar("g_bugrigs_friction_floor");
-    g_bugrigs_friction_brake = cvar("g_bugrigs_friction_brake");
-    g_bugrigs_friction_air = cvar("g_bugrigs_friction_air");
-    g_bugrigs_accel = cvar("g_bugrigs_accel");
-    g_bugrigs_speed_ref = cvar("g_bugrigs_speed_ref");
-    g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
-    g_bugrigs_steer = cvar("g_bugrigs_steer");
-
        g_instagib = cvar("g_instagib");
 
        sv_clones = cvar("sv_clones");
index 5c7c2311b2bfbb3a60bee91274f63c664ac13a3d..be95bd1a49a3d5e35660ffe1e1b14ab96a086ecb 100644 (file)
@@ -93,17 +93,6 @@ string item_model;
 string item_model_output;
 MUTATOR_HOOKABLE(ItemModel, EV_ItemModel);
 
-/** called when a player presses the jump key */
-#define EV_PlayerJump(i, o) \
-    /**/ i(float, player_multijump) \
-    /**/ i(float, player_jumpheight) \
-    /**/ o(float, player_multijump) \
-    /**/ o(float, player_jumpheight) \
-    /**/
-float player_multijump;
-float player_jumpheight;
-MUTATOR_HOOKABLE(PlayerJump, EV_PlayerJump);
-
 /** called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill */
 #define EV_GiveFragsForKill(i, o) \
     /**/ i(entity, __self) \
@@ -219,12 +208,6 @@ MUTATOR_HOOKABLE(PlayerPreThink, EV_NO_ARGS);
 /** TODO change this into a general PlayerPostThink hook? */
 MUTATOR_HOOKABLE(GetPressedKeys, EV_NO_ARGS);
 
-/**
- * called before any player physics, may adjust variables for movement,
- * is run AFTER bot code and idle checking
- */
-MUTATOR_HOOKABLE(PlayerPhysics, EV_NO_ARGS);
-
 /** is meant to call GetCvars_handle*(get_cvars_s, get_cvars_f, cvarfield, "cvarname") for cvars this mutator needs from the client */
 #define EV_GetCvars(i, o) \
     /**/ i(float, get_cvars_f) \
index df5403b595ce638b21351555ae9d70d6a85c5a1b..2e71383d7bb57c79e98de0a47892f1a290139856 100644 (file)
@@ -1240,6 +1240,11 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
                        }
                        else if(CTF_SAMETEAM(toucher, flag) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, flag) && is_not_monster)
                                ctf_Handle_Capture(flag, toucher, CAPTURE_NORMAL); // toucher just captured the enemies flag to his base
+                       else if(CTF_DIFFTEAM(toucher, flag) && (toucher.flagcarried) && CTF_SAMETEAM(toucher.flagcarried, toucher) && (!toucher.ctf_captureshielded) && autocvar_g_ctf_flag_return_carrying && (time > toucher.next_take_time) && is_not_monster)
+                       {
+                               ctf_Handle_Return(toucher.flagcarried, toucher); // return their current flag
+                               ctf_Handle_Pickup(flag, toucher, PICKUP_BASE); // now pickup the flag
+                       }
                        else if(CTF_DIFFTEAM(toucher, flag) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
                                ctf_Handle_Pickup(flag, toucher, PICKUP_BASE); // toucher just stole the enemies flag
                        break;
index 4fbafe03535a21da375d031d38aa3c8f37817021..5b67888485d450dd4a8bdde5f5495cd746188f52 100644 (file)
@@ -107,6 +107,46 @@ void race_EventLog(string mode, entity actor) // use an alias for easy changing
                GameLogEcho(strcat(":race:", mode, ":", ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
 }
 
+float WinningCondition_Race(float fraglimit)
+{
+       float wc;
+       entity p;
+       float n, c;
+
+       n = 0;
+       c = 0;
+       FOR_EACH_PLAYER(p)
+       {
+               ++n;
+               if(p.race_completed)
+                       ++c;
+       }
+       if(n && (n == c))
+               return WINNING_YES;
+       wc = WinningCondition_Scores(fraglimit, 0);
+
+       // ALWAYS initiate overtime, unless EVERYONE has finished the race!
+       if(wc == WINNING_YES || wc == WINNING_STARTSUDDENDEATHOVERTIME)
+       // do NOT support equality when the laps are all raced!
+               return WINNING_STARTSUDDENDEATHOVERTIME;
+       else
+               return WINNING_NEVER;
+}
+
+float WinningCondition_QualifyingThenRace(float limit)
+{
+       float wc;
+       wc = WinningCondition_Scores(limit, 0);
+
+       // NEVER initiate overtime
+       if(wc == WINNING_YES || wc == WINNING_STARTSUDDENDEATHOVERTIME)
+       {
+               return WINNING_YES;
+       }
+
+       return wc;
+}
+
 MUTATOR_HOOKFUNCTION(rc, PlayerPhysics)
 {SELFPARAM();
        self.race_movetime_frac += PHYS_INPUT_TIMELENGTH;
@@ -399,10 +439,18 @@ MUTATOR_HOOKFUNCTION(rc, FixClientCvars)
 
 MUTATOR_HOOKFUNCTION(rc, CheckRules_World)
 {
-       if(g_race_qualifying == 2 && checkrules_timelimit >= 0)
+       if(checkrules_timelimit >= 0)
        {
-               ret_float = WinningCondition_QualifyingThenRace(checkrules_fraglimit);
-               return true;
+               if(!g_race_qualifying)
+               {
+                       ret_float = WinningCondition_QualifyingThenRace(checkrules_fraglimit);
+                       return true;
+               }
+               else if(g_race_qualifying == 2)
+               {
+                       ret_float = WinningCondition_QualifyingThenRace(checkrules_fraglimit);
+                       return true;
+               }
        }
 
        return false;
index 082356ae2d86084f2b8ad8d6ffe624f9e9a43936..f3e03424b18eb4f5f4e7c2eb2b7228aea92784da 100644 (file)
@@ -133,32 +133,32 @@ void playerdemo_read_float(.float f, string name)
 {SELFPARAM();
        self.(f) = stof(fgets(self.playerdemo_fh));
 }
-float playerdemo_read()
-{SELFPARAM();
-       if(self.playerdemo_mode != PLAYERDEMO_MODE_READING)
+float playerdemo_read(entity this)
+{
+       if(this.playerdemo_mode != PLAYERDEMO_MODE_READING)
                return 0;
-       if(self.playerdemo_time < 0)
+       if(this.playerdemo_time < 0)
                return 1;
        float t;
        t = time;
-       while(time >= self.playerdemo_time)
+       while(time >= this.playerdemo_time)
        {
                PLAYERDEMO_FIELDS(playerdemo_read_)
                {
-                       time = self.playerdemo_time;
-                       PlayerPreThink();
+                       time = this.playerdemo_time;
+                       WITH(entity, this, this, PlayerPreThink());
                        // not running physics though... this is just so we can run weapon stuff
-                       PlayerPostThink();
+                       WITH(entity, this, this, PlayerPostThink());
                }
-               self.playerdemo_time = stof(fgets(self.playerdemo_fh));
-               if(self.playerdemo_time == 0)
+               this.playerdemo_time = stof(fgets(this.playerdemo_fh));
+               if(this.playerdemo_time == 0)
                {
-                       self.playerdemo_time = -1;
+                       this.playerdemo_time = -1;
                        return 1;
                }
-               self.playerdemo_time += self.playerdemo_starttime;
+               this.playerdemo_time += this.playerdemo_starttime;
        }
-       self.velocity = '0 0 0';
+       this.velocity = '0 0 0';
        time = t;
        return 1;
 }
index 8aecd483ed0f71057442b001f104fc973e4552c9..05e012aa6e771d2865ea97a64945ff4436b47705 100644 (file)
@@ -4,7 +4,7 @@
 void playerdemo_init();
 void playerdemo_shutdown();
 void playerdemo_write();
-float playerdemo_read();
+float playerdemo_read(entity this);
 
 void playerdemo_open_read(string f);
 void playerdemo_open_write(string f);
index 20a473e357348bf52942f98bf9ceae869e44205f..a7dfb96775d8d272b13a1acf6e4f104b75a3f936 100644 (file)
@@ -94,6 +94,8 @@ void CreatureFrame ()
                                                        sound (self, CH_PLAYER_SINGLE, SND_LAVA, VOL_BASE, ATTEN_NORM);
                                                }
                                                Damage (self, world, world, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_LAVA.m_id, self.origin, '0 0 0');
+                                               if(autocvar_g_balance_contents_playerdamage_lava_burn)
+                                                       Fire_AddDamage(self, world, autocvar_g_balance_contents_playerdamage_lava_burn * self.waterlevel, autocvar_g_balance_contents_playerdamage_lava_burn_time * self.waterlevel, DEATH_LAVA.m_id);
                                        }
                                        else if (self.watertype == CONTENT_SLIME)
                                        {
index 219e483c703af0651f9b53921c62e5ca9067226f..3fb6998e9ce43fd3d1640e2376bf93410591a976 100644 (file)
@@ -33,7 +33,7 @@ void ItemDraw(entity self)
 {
     if(self.gravity)
     {
-        Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
+        Movetype_Physics_MatchServer(self, autocvar_cl_projectiles_sloppy);
         if(self.move_flags & FL_ONGROUND)
         { // For some reason move_avelocity gets set to '0 0 0' here ...
             self.oldorigin = self.origin;
@@ -69,7 +69,7 @@ void ItemDrawSimple(entity this)
 {
     if(self.gravity)
     {
-        Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
+        Movetype_Physics_MatchServer(self, autocvar_cl_projectiles_sloppy);
 
         if(self.move_flags & FL_ONGROUND)
             self.gravity = 0;
@@ -96,6 +96,12 @@ void Item_PreDraw()
                self.drawmask = MASK_NORMAL;
 }
 
+void ItemRemove()
+{SELFPARAM();
+       if (self.mdl)
+               strunzone(self.mdl);
+}
+
 NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
 {
     int sf = ReadByte();
@@ -242,6 +248,9 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
         if(self.ItemStatus & ITS_ANIMATE2)
             self.move_avelocity = '0 -90 0';
     }
+
+    self.entremove = ItemRemove;
+
     return true;
 }
 
index deb6032ce207a32b980a06804608cbd4303ad173..b0f44da6b7e51d5104d3d01b1571b3c149bc874c 100644 (file)
@@ -151,9 +151,6 @@ string getwelcomemessage()
        if(modifications != "")
                s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
 
-       if (cvar("g_nades"))
-               s = strcat(s, "\n\n^3nades^8 are enabled, press 'g' to use them\n");
-
        if(cache_lastmutatormsg != autocvar_g_mutatormsg)
        {
                if(cache_lastmutatormsg)