]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/lib/csqcmodel/cl_player.qc
Remove .move_* fields and MOVETYPE_PUSH logic (doesn't work)
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / csqcmodel / cl_player.qc
index ae4e55ac1cad74e41fa261429444c545ce10f6fc..58c5f71f039d6686141fffc0806567fdf87a70d2 100644 (file)
 #include "cl_model.qh"
 #include "common.qh"
 #include "interpolate.qh"
-#include "../../client/defs.qh"
-#include "../../client/main.qh"
-#include "../../common/constants.qh"
-#include "../../common/stats.qh"
-#include "../../common/triggers/trigger/viewloc.qh"
-#include "../../common/util.qh"
-#include "../../common/viewloc.qh"
+#include <client/defs.qh>
+#include <client/main.qh>
+#include <common/constants.qh>
+#include <common/physics/player.qh>
+#include <common/stats.qh>
+#include <common/triggers/trigger/viewloc.qh>
+#include <common/util.qh>
+#include <common/viewloc.qh>
 
 float autocvar_cl_movement_errorcompensation = 0;
-int autocvar_cl_movement = 1;
+bool autocvar_cl_movement_intermissionrunning = false;
 
 // engine stuff
 float pmove_onground; // weird engine flag we shouldn't really use but have to for now
@@ -50,15 +51,13 @@ float csqcplayer_predictionerrorfactor;
 
 vector CSQCPlayer_GetPredictionErrorO()
 {
-       if(time >= csqcplayer_predictionerrortime)
-               return '0 0 0';
+       if (time >= csqcplayer_predictionerrortime) return '0 0 0';
        return csqcplayer_predictionerroro * (csqcplayer_predictionerrortime - time) * csqcplayer_predictionerrorfactor;
 }
 
 vector CSQCPlayer_GetPredictionErrorV()
 {
-       if(time >= csqcplayer_predictionerrortime)
-               return '0 0 0';
+       if (time >= csqcplayer_predictionerrortime) return '0 0 0';
        return csqcplayer_predictionerrorv * (csqcplayer_predictionerrortime - time) * csqcplayer_predictionerrorfactor;
 }
 
@@ -77,7 +76,7 @@ void CSQCPlayer_SetPredictionError(vector o, vector v, float onground_diff)
                return;
        }
        */
-       if(vlen(o) > 32 || vlen(v) > 192)
+       if(vdist(o, >, 32) || vdist(v, >, 192))
        {
                //printf("TOO BIG: x=%v v=%v\n", o, v);
                return;
@@ -95,81 +94,103 @@ void CSQCPlayer_SetPredictionError(vector o, vector v, float onground_diff)
        csqcplayer_predictionerrortime = time + 1.0 / csqcplayer_predictionerrorfactor;
 }
 
-void CSQCPlayer_Unpredict()
-{SELFPARAM();
-       if(csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED)
-               return;
-       if(csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED)
-               error("Cannot unpredict in current status");
-       self.origin = csqcplayer_origin;
-       self.velocity = csqcplayer_velocity;
-       csqcplayer_moveframe = csqcplayer_sequence+1; //+1 because the recieved frame has the move already done (server side)
-       self.flags = player_pmflags;
+void CSQCPlayer_Unpredict(entity this)
+{
+       if (csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED) return;
+       if (csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED) LOG_FATALF("Cannot unpredict in current status (%d)\n", csqcplayer_status);
+       this.origin = csqcplayer_origin;
+       this.velocity = csqcplayer_velocity;
+       csqcplayer_moveframe = csqcplayer_sequence + 1; // + 1 because the recieved frame has the move already done (server side)
+       this.flags = player_pmflags;
 }
 
-void CSQCPlayer_SetMinsMaxs()
-{SELFPARAM();
-       if(self.flags & FL_DUCKED)
+void CSQCPlayer_SetMinsMaxs(entity this)
+{
+       if ((this.flags & FL_DUCKED) || !this.isplayermodel)
        {
-               self.mins = PL_CROUCH_MIN;
-               self.maxs = PL_CROUCH_MAX;
-               self.view_ofs = PL_CROUCH_VIEW_OFS;
+               this.mins = STAT(PL_CROUCH_MIN, NULL);
+               this.maxs = STAT(PL_CROUCH_MAX, NULL);
+               this.view_ofs = STAT(PL_CROUCH_VIEW_OFS, NULL);
        }
        else
        {
-               self.mins = PL_MIN;
-               self.maxs = PL_MAX;
-               self.view_ofs = PL_VIEW_OFS;
+               this.mins = STAT(PL_MIN, NULL);
+               this.maxs = STAT(PL_MAX, NULL);
+               this.view_ofs = STAT(PL_VIEW_OFS, NULL);
        }
 }
 
-void CSQCPlayer_SavePrediction()
-{SELFPARAM();
-       player_pmflags = self.flags;
-       csqcplayer_origin = self.origin;
-       csqcplayer_velocity = self.velocity;
+void CSQCPlayer_SavePrediction(entity this)
+{
+       player_pmflags = this.flags;
+       csqcplayer_origin = this.origin;
+       csqcplayer_velocity = this.velocity;
        csqcplayer_sequence = servercommandframe;
        csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
 }
 
-void CSQC_ClientMovement_PlayerMove_Frame();
+void CSQC_ClientMovement_PlayerMove_Frame(entity this);
+void _Movetype_Physics_ClientFrame(entity this, float movedt);
 
-void PM_Movement_Move()
-{SELFPARAM();
-       runstandardplayerphysics(self);
-#ifdef CSQC
-       self.flags =
-                       ((self.pmove_flags & PMF_DUCKED) ? FL_DUCKED : 0) |
-                       (!(self.pmove_flags & PMF_JUMP_HELD) ? FL_JUMPRELEASED : 0) |
-                       ((self.pmove_flags & PMF_ONGROUND) ? FL_ONGROUND : 0);
-#endif
+void Movetype_Physics_Spam(entity this)  // optimized
+{
+       _Movetype_Physics_ClientFrame(this, PHYS_INPUT_TIMELENGTH);
+       if(wasfreed(this))
+               return;
+
+       setorigin(this, this.origin);
 }
 
-void CSQCPlayer_Physics(void)
+void CSQCPlayer_CheckWater(entity this)
 {
-       switch(autocvar_cl_movement)
+       _Movetype_CheckWater(this);
+}
+
+void CSQCPlayer_Physics(entity this)
+{
+       if(autocvar_cl_movement)
        {
-               case 1: CSQC_ClientMovement_PlayerMove_Frame(); break;
-               case 2: PM_Movement_Move(); break;
+               if(autocvar_cl_movement == 1)
+                       CSQCPlayer_CheckWater(this); // we apparently need to check water *before* physics so it can use this for water jump
+
+               vector oldv_angle = this.v_angle;
+               vector oldangles = this.angles; // we need to save these, as they're abused by other code
+               this.v_angle = PHYS_INPUT_ANGLES(this);
+               this.angles = PHYS_WORLD_ANGLES(this);
+
+               CSQC_ClientMovement_PlayerMove_Frame(this);
+
+               if(autocvar_cl_movement == 1)
+                       Movetype_Physics_Spam(this);
+
+               view_angles = this.v_angle;
+               input_angles = this.angles;
+               this.v_angle = oldv_angle;
+               this.angles = oldangles;
+
+               this.pmove_flags =
+                               ((this.flags & FL_DUCKED) ? PMF_DUCKED : 0) |
+                               (!(this.flags & FL_JUMPRELEASED) ? PMF_JUMP_HELD : 0) |
+                               ((IS_ONGROUND(this)) ? PMF_ONGROUND : 0);
        }
 }
 
-void CSQCPlayer_PredictTo(float endframe, float apply_error)
-{SELFPARAM();
-       CSQCPlayer_Unpredict();
-       if(apply_error)
+void CSQCPlayer_PredictTo(entity this, float endframe, bool apply_error)
+{
+       CSQCPlayer_Unpredict(this);
+       if (apply_error)
        {
-               self.origin += CSQCPlayer_GetPredictionErrorO();
-               self.velocity += CSQCPlayer_GetPredictionErrorV();
+               this.origin += CSQCPlayer_GetPredictionErrorO();
+               this.velocity += CSQCPlayer_GetPredictionErrorV();
        }
-       CSQCPlayer_SetMinsMaxs();
+       CSQCPlayer_SetMinsMaxs(this);
 
        csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
 
 #if 0
        // we don't need this
        // darkplaces makes servercommandframe == 0 in these cases anyway
-       if (getstatf(STAT_HEALTH) <= 0)
+       if (STAT(HEALTH) <= 0)
        {
                csqcplayer_moveframe = clientcommandframe;
                getinputstate(csqcplayer_moveframe-1);
@@ -178,7 +199,7 @@ void CSQCPlayer_PredictTo(float endframe, float apply_error)
        }
 #endif
 
-       if(csqcplayer_moveframe >= endframe)
+       if (csqcplayer_moveframe >= endframe)
        {
                getinputstate(csqcplayer_moveframe - 1);
        }
@@ -186,22 +207,21 @@ void CSQCPlayer_PredictTo(float endframe, float apply_error)
        {
                do
                {
-                       if (!getinputstate(csqcplayer_moveframe))
-                               break;
-                       CSQCPlayer_Physics();
-                       CSQCPlayer_SetMinsMaxs();
-                       csqcplayer_moveframe++;
+                       if (!getinputstate(csqcplayer_moveframe)) break;
+                       CSQCPlayer_Physics(this);
+                       CSQCPlayer_SetMinsMaxs(this);
+                       ++csqcplayer_moveframe;
                }
-               while(csqcplayer_moveframe < endframe);
+               while (csqcplayer_moveframe < endframe);
        }
 
-       //add in anything that was applied after (for low packet rate protocols)
+       // add in anything that was applied after (for low packet rate protocols)
        input_angles = view_angles;
 }
 
-bool CSQCPlayer_IsLocalPlayer()
-{SELFPARAM();
-       return (self == csqcplayer);
+bool CSQCPlayer_IsLocalPlayer(entity this)
+{
+       return (this == csqcplayer);
 }
 
 void CSQCPlayer_SetViewLocation()
@@ -209,118 +229,90 @@ void CSQCPlayer_SetViewLocation()
        viewloc_SetViewLocation();
 }
 
+/** Called once per CSQC_UpdateView() */
 void CSQCPlayer_SetCamera()
-{SELFPARAM();
-       vector v0;
-       v0 = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
-
-       if(csqcplayer)
+{
+       const vector v0 = ((intermission && !autocvar_cl_movement_intermissionrunning) ? '0 0 0' : pmove_vel); // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
+       const float vh = STAT(VIEWHEIGHT);
+       const vector pl_viewofs = STAT(PL_VIEW_OFS, NULL);
+       const vector pl_viewofs_crouch = STAT(PL_CROUCH_VIEW_OFS, NULL);
+       const entity e = csqcplayer;
+       if (e)
        {
-               setself(csqcplayer);
-
-               if(servercommandframe == 0 || clientcommandframe == 0)
+               if (servercommandframe == 0 || clientcommandframe == 0)
                {
-                       InterpolateOrigin_Do();
-                       self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+                       InterpolateOrigin_Do(e);
+                       e.view_ofs = '0 0 1' * vh;
 
                        // get crouch state from the server
-                       if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
-                               self.flags &= ~FL_DUCKED;
-                       else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
-                               self.flags |= FL_DUCKED;
+                       if (vh == pl_viewofs.z) e.flags &= ~FL_DUCKED;
+                       else if (vh == pl_viewofs_crouch.z) e.flags |= FL_DUCKED;
 
                        // get onground state from the server
-                       if(pmove_onground)
-                               self.flags |= FL_ONGROUND;
-                       else
-                               self.flags &= ~FL_ONGROUND;
+                       e.flags = BITSET(e.flags, FL_ONGROUND, pmove_onground);
 
-                       CSQCPlayer_SetMinsMaxs();
+                       CSQCPlayer_SetMinsMaxs(e);
 
                        // override it back just in case
-                       self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+                       e.view_ofs = '0 0 1' * vh;
 
                        // set velocity
-                       self.velocity = v0;
+                       e.velocity = v0;
                }
                else
                {
-                       float flg = self.iflags;
-                       self.iflags &= ~(IFLAG_ORIGIN | IFLAG_ANGLES);
-                       InterpolateOrigin_Do();
-                       self.iflags = flg;
+                       const int flg = e.iflags; e.iflags &= ~(IFLAG_ORIGIN | IFLAG_ANGLES);
+                       InterpolateOrigin_Do(e);
+                       e.iflags = flg;
 
-                       if(csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER)
+                       if (csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER)
                        {
-                               vector o, v;
-                               o = self.origin;
-                               v = v0;
+                               const vector o = e.origin;
                                csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
-                               CSQCPlayer_PredictTo(servercommandframe + 1, false);
-                               CSQCPlayer_SetPredictionError(self.origin - o, self.velocity - v, pmove_onground - !!(self.flags & FL_ONGROUND));
-                               self.origin = o;
-                               self.velocity = v;
+                               CSQCPlayer_PredictTo(e, servercommandframe + 1, false);
+                               CSQCPlayer_SetPredictionError(e.origin - o, e.velocity - v0, pmove_onground - IS_ONGROUND(e));
+                               e.origin = o;
+                               e.velocity = v0;
 
                                // get crouch state from the server
-                               if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
-                                       self.flags &= ~FL_DUCKED;
-                               else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
-                                       self.flags |= FL_DUCKED;
+                               if (vh == pl_viewofs.z) e.flags &= ~FL_DUCKED;
+                               else if(vh == pl_viewofs_crouch.z) e.flags |= FL_DUCKED;
 
                                // get onground state from the server
-                               if(pmove_onground)
-                                       self.flags |= FL_ONGROUND;
-                               else
-                                       self.flags &= ~FL_ONGROUND;
+                               e.flags = BITSET(e.flags, FL_ONGROUND, pmove_onground);
 
-                               CSQCPlayer_SavePrediction();
+                               CSQCPlayer_SavePrediction(e);
                        }
-                       CSQCPlayer_PredictTo(clientcommandframe + 1, true);
+                       CSQCPlayer_PredictTo(e, clientcommandframe + 1, true);
 
 #ifdef CSQCMODEL_SERVERSIDE_CROUCH
                        // get crouch state from the server (LAG)
-                       if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS.z)
-                               self.flags &= ~FL_DUCKED;
-                       else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS.z)
-                               self.flags |= FL_DUCKED;
+                       if (vh == pl_viewofs.z) e.flags &= ~FL_DUCKED;
+                       else if (vh == pl_viewofs_crouch.z) e.flags |= FL_DUCKED;
 #endif
+                       CSQCPlayer_SetMinsMaxs(e);
 
-                       CSQCPlayer_SetMinsMaxs();
-
-                       self.angles_y = input_angles.y;
+                       e.angles_y = input_angles.y;
                }
 
                // relink
-               setorigin(self, self.origin);
-
-               setself(this);
+               setorigin(e, e.origin);
        }
 
-       entity view = CSQCModel_server2csqc(player_localentnum);
-
-       if(view && view != csqcplayer)
-       {
-               WITH(entity, self, view, InterpolateOrigin_Do());
-               view.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
-       }
-
-       if(view)
+       const entity view = CSQCModel_server2csqc(player_localentnum - 1);
+       if (view)
        {
+               if (view != csqcplayer)
+               {
+                       InterpolateOrigin_Do(view);
+                       view.view_ofs = '0 0 1' * vh;
+               }
                int refdefflags = 0;
-
-               if(view.csqcmodel_teleported)
-                       refdefflags |= REFDEFFLAG_TELEPORTED;
-
-               if(input_buttons & 4)
-                       refdefflags |= REFDEFFLAG_JUMPING;
-
+               if (view.csqcmodel_teleported) refdefflags |= REFDEFFLAG_TELEPORTED;
+               if (input_buttons & BIT(1)) refdefflags |= REFDEFFLAG_JUMPING;
                // note: these two only work in WIP2, but are harmless in WIP1
-               if(getstati(STAT_HEALTH) <= 0)
-                       refdefflags |= REFDEFFLAG_DEAD;
-
-               if(intermission)
-                       refdefflags |= REFDEFFLAG_INTERMISSION;
-
+               if (STAT(HEALTH) <= 0 && STAT(HEALTH) != -666 && STAT(HEALTH) != -2342) refdefflags |= REFDEFFLAG_DEAD;
+               if (intermission) refdefflags |= REFDEFFLAG_INTERMISSION;
                V_CalcRefdef(view, refdefflags);
        }
        else
@@ -328,36 +320,32 @@ void CSQCPlayer_SetCamera()
                // FIXME by CSQC spec we have to do this:
                // but it breaks chase cam
                /*
-               setproperty(VF_ORIGIN, pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT));
+               setproperty(VF_ORIGIN, pmove_org + '0 0 1' * vh);
                setproperty(VF_ANGLES, view_angles);
                */
        }
-
-       { CSQCPLAYER_HOOK_POSTCAMERASETUP }
+       CSQCPLAYER_HOOK_POSTCAMERASETUP();
 }
 
-void CSQCPlayer_Remove()
+void CSQCPlayer_Remove(entity this)
 {
-       csqcplayer = world;
+       csqcplayer = NULL;
        cvar_settemp("cl_movement_replay", "1");
 }
 
-float CSQCPlayer_PreUpdate()
-{SELFPARAM();
-       if(self != csqcplayer)
-               return 0;
-       if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER)
-               CSQCPlayer_Unpredict();
-       return 1;
+bool CSQCPlayer_PreUpdate(entity this)
+{
+       if (this != csqcplayer) return false;
+       if (csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER) CSQCPlayer_Unpredict(this);
+       return true;
 }
 
-float CSQCPlayer_PostUpdate()
-{SELFPARAM();
-       if(self.entnum != player_localnum + 1)
-               return 0;
-       csqcplayer = self;
+bool CSQCPlayer_PostUpdate(entity this)
+{
+       if (this.entnum != player_localnum + 1) return false;
+       csqcplayer = this;
        csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER;
        cvar_settemp("cl_movement_replay", "0");
-       self.entremove = CSQCPlayer_Remove;
-       return 1;
+       this.entremove = CSQCPlayer_Remove;
+       return true;
 }