From b3b0f3da9fc059ff3560a2e677465acffa806968 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 19 Apr 2009 01:15:18 +0000 Subject: [PATCH] Map triggers are more sane. Really buggy example custom prediction code in this commit. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3180 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- quakec/csqctest/src/common/pmove.qc | 308 +++++++++++++++++++++--- quakec/csqctest/src/common/pmovedefs.qc | 12 - quakec/csqctest/src/cs/csbuiltins.qc | 2 +- quakec/csqctest/src/cs/defs.qc | 4 +- quakec/csqctest/src/cs/entrypoints.qc | 1 - quakec/csqctest/src/cs/map.qc | 62 +---- quakec/csqctest/src/cs/player.qc | 13 +- quakec/csqctest/src/cs/prediction.qc | 79 +++--- quakec/csqctest/src/csprogs.src | 2 +- quakec/csqctest/src/ss/client.qc | 44 +--- 10 files changed, 350 insertions(+), 177 deletions(-) diff --git a/quakec/csqctest/src/common/pmove.qc b/quakec/csqctest/src/common/pmove.qc index 33749ba2..c7783e4c 100644 --- a/quakec/csqctest/src/common/pmove.qc +++ b/quakec/csqctest/src/common/pmove.qc @@ -1,48 +1,294 @@ +/* + +WARNING: This entire file is pretty much GPLed. +If you want to release your csqc mod free from the GPL, do not define OWNPLAYERPHYSICS, and remove this file from your progs.src + +*/ + #ifdef OWNPLAYERPHYSICS -void PMove_Move(vector dest) //move forwards (preferably on the level) (does step ups) +/* +be very careful about the fields/globals that are read/written in this code. +Using any that are changed elsewhere can and will result in prediction errors. +Any fields that are expected to persist need to be added to csqc code to revert them. +Any fields that are read need to be the same between csqc and ssqc code somehow. Changing such fields will result in brief errors. +*/ + + +#define movevars_stepheight 22 +#define movevars_friction 4 +#define movevars_gravity 800 +#define movevars_accelerate 10 +#define movevars_stopspeed 100 +#define movevars_maxspeed 320 +#define movevars_jumpheight 270 + +.float pmove_flags; + +#ifdef HAVE_DOTGRAVITY +.float gravity; +#endif + +enumflags { - vector src; - float stepped; - tracebox(pmove_org, pmove_mins, pmove_maxs, dest, false, self); //try going straight there - - if (trace_fraction < 1) - { //step up - src = trace_endpos; - trace_endpos_z += movevars_stepheight; - tracebox(src, pmove_mins, pmove_maxs, dest, false, self); - stepped = trace_endpos_z - src_z; - dest_z += stepped; - - //move forwards - tracebox(trace_endpos, pmove_mins, pmove_maxs, dest, false, self); - - //move down - dest_z -= stepped; - tracebox(trace_endpos, pmove_mins, pmove_maxs, dest, false, self); - } - pmove_org = trace_endpos; + PMF_JUMP_HELD, + PMF_RESERVED, + PMF_ONGROUND }; -void PMove(void) +static void(entity tother) dotouch = { + entity oself; + //if (tother.touch == __NULL__) + return; + + oself = self; + + other = self; + self = tother; + + self.touch(); + + self = oself; +}; + +//this function 'bounces' off any surfaces that were hit +void(vector surfnorm) PMove_Rebound = +{ + float v; + v = self.velocity*surfnorm; + self.velocity = self.velocity - surfnorm*(v); +}; + +void(void) PMove_Move = //move forwards (preferably on the level) (does step ups) +{ + vector dest; + vector saved_plane_normal; + float stepped; + float movetime; + float attempts; + + //we need to bounce off surfaces (in order to slide along them), so we need at 2 attempts + for (attempts = 3, movetime = input_timelength; movetime>0 && attempts; attempts--) + { + dest = self.origin + self.velocity*movetime; + tracebox(self.origin, self.mins, self.maxs, dest, false, self); //try going straight there + self.origin = trace_endpos; + + if (trace_fraction < 1) + { + saved_plane_normal = trace_plane_normal; + + movetime -= movetime * trace_fraction; + + if (movetime) + { + //step up if we can + trace_endpos = self.origin; + trace_endpos_z += movevars_stepheight; + tracebox(self.origin, self.mins, self.maxs, trace_endpos, false, self); + stepped = trace_endpos_z - self.origin_z; + + dest = trace_endpos + self.velocity*movetime; + dest_z = trace_endpos_z; + //move forwards + tracebox(trace_endpos, self.mins, self.maxs, dest, false, self); + + //if we got anywhere, make this raised-step move count + if (trace_fraction != 0) + { + if (trace_fraction < 1) + PMove_Rebound(trace_plane_normal); + + //move down + dest = trace_endpos; + dest_z -= stepped+1; + tracebox(trace_endpos, self.mins, self.maxs, dest, false, self); + if (trace_fraction < 1) + PMove_Rebound(trace_plane_normal); + + self.origin = trace_endpos; + + movetime -= movetime * input_timelength; + + continue; + } + } + + //stepping failed, just bounce off + PMove_Rebound(saved_plane_normal); + + dotouch(trace_ent); + } + else + break; + } +}; +/* +void(vector dest) PMove_StepMove = +{ + //we hit something... + + //step up + src = trace_endpos; + trace_endpos_z += movevars_stepheight; + tracebox(src, self.mins, self.maxs, dest, false, self); + stepped = trace_endpos_z - src_z; + dest_z += stepped; + + //move forwards + tracebox(trace_endpos, self.mins, self.maxs, dest, false, self); + + //move down + dest_z -= stepped; + tracebox(trace_endpos, self.mins, self.maxs, dest, false, self); +} +*/ +void() PMove_ApplyFriction = +{ + float newspeed, oldspeed; + oldspeed = vlen(self.velocity); + if (oldspeed < 1) + { + self.velocity = '0 0 0'; + return; + } + + //calculate what their new speed should be + newspeed = oldspeed - oldspeed*movevars_friction*input_timelength; + + //and slow them + if (newspeed < 0) + newspeed = 0; + self.velocity = self.velocity * (newspeed/oldspeed); +}; + +void(vector wishdir, float wishspeed, float accel) PMove_Accelerate = +{ + float addspeed, accelspeed; + float d; + d = self.velocity*wishdir; + addspeed = wishspeed - (d); + if (addspeed <= 0) + return; + accelspeed = accel*input_timelength*wishspeed; + if (accelspeed > addspeed) + accelspeed = addspeed; + + self.velocity = self.velocity + accelspeed*wishdir; +}; + +void() PMove_InAirAccelerate = +{ + vector hforward; + vector hright; + vector desireddir; + float desiredspeed; + + hforward = v_forward; + hforward_z = 0; + hforward = normalize(hforward); + hright = v_right; + hright_z = 0; + hright = normalize(hright); + + desireddir = hforward*input_movevalues_x + hright*input_movevalues_y; + desiredspeed = vlen(desireddir); + desireddir = normalize(desireddir); + + if (desiredspeed > movevars_maxspeed) + desiredspeed = movevars_maxspeed; + + if (self.pmove_flags & PMF_ONGROUND) + { + if (input_buttons & 2) + { + if (!(self.pmove_flags & PMF_JUMP_HELD)) + { + self.velocity_z += movevars_jumpheight; + self.pmove_flags (+) PMF_ONGROUND; + } + } + } + + if (self.pmove_flags & PMF_ONGROUND) + { + PMove_ApplyFriction(); + PMove_Accelerate(desireddir, desiredspeed, movevars_accelerate); + } + else + { + //there's no friction in air... + if (desiredspeed > 30) + desiredspeed = 30; + PMove_Accelerate(desireddir, desiredspeed, movevars_accelerate); + +#ifdef HAVE_DOTGRAVITY + if (self.gravity) + self.velocity_z -= self.gravity * movevars_gravity * input_timelength; + else +#endif + self.velocity_z -= movevars_gravity * input_timelength; + } +}; + +void() PMove_NoclipAccelerate = +{ + vector desireddir; + float desiredspeed; + + desireddir = v_forward*input_movevalues_x + v_right*input_movevalues_y+v_up*input_movevalues_z; + desiredspeed = vlen(desireddir); + desireddir = normalize(desireddir); + + PMove_ApplyFriction(); + PMove_Accelerate(desireddir, desiredspeed, movevars_accelerate); +}; + +void() PMove_Categorise = +{ + //if we're moving up, we're not on the ground + if (self.velocity_z > 0) + self.pmove_flags (-) PMF_ONGROUND; + else + { + //don't know, maybe we are, maybe we're not + tracebox(self.origin, self.mins, self.maxs, self.origin-'0 0 1', false, self); + if (trace_fraction == 1 || trace_plane_normal_z < 0.7) + { + self.pmove_flags (-) PMF_ONGROUND; +// self.groundentity = trace_ent; + } + else + self.pmove_flags (+) PMF_ONGROUND; + } +}; + +void(entity ent) PMove = +{ + self = ent; makevectors(input_angles); + if (!(input_buttons & PMF_JUMP_HELD)) + self.pmove_flags (-) PMF_JUMP_HELD; - pmove_vel *= movevars_friction*input_timelength; - pmove_vel += input_timelength*( - v_forward * input_movevalues_x + - v_right * input_movevalues_y + - v_up * input_movevalues_z); + PMove_Categorise(); - switch(pmove_type) + self.movetype = MOVETYPE_WALK; + + switch(self.movetype) { case MOVETYPE_WALK: - pmove_vel_z += movevars_gravity*input_timelength; - PMove_Move(pmove_org + pmove_vel*input_timelength); + PMove_InAirAccelerate(); + PMove_Move(); + break; + case MOVETYPE_FLY: + PMove_NoclipAccelerate(); + PMove_Move(); break; case MOVETYPE_NOCLIP: - pmove_org += pmove_vel*input_timelength; + PMove_NoclipAccelerate(); + self.origin += self.velocity*input_timelength; break; case MOVETYPE_NONE: break; diff --git a/quakec/csqctest/src/common/pmovedefs.qc b/quakec/csqctest/src/common/pmovedefs.qc index 1691cf59..7abbaa00 100644 --- a/quakec/csqctest/src/common/pmovedefs.qc +++ b/quakec/csqctest/src/common/pmovedefs.qc @@ -9,15 +9,3 @@ noref float input_impulse; //float input_weapon; //float input_servertime; -float pmove_type; -vector pmove_org; -vector pmove_vel; -vector pmove_mins; -vector pmove_maxs; -float pmove_jump_held; -float pmove_waterjumptime; - -float movevars_friction; -float movevars_gravity; - -const float movevars_stepheight = 22; \ No newline at end of file diff --git a/quakec/csqctest/src/cs/csbuiltins.qc b/quakec/csqctest/src/cs/csbuiltins.qc index 93c3eb21..4b8dbf8b 100644 --- a/quakec/csqctest/src/cs/csbuiltins.qc +++ b/quakec/csqctest/src/cs/csbuiltins.qc @@ -62,7 +62,7 @@ string(float keynum) getkeybind = #342; // (EXT_CSQC) float(float framenum) getinputstate = #345; // (EXT_CSQC) void(float sens) setsensitivityscaler = #346; // (EXT_CSQC) -void() runstandardplayerphysics = #347; // (EXT_CSQC) +void(entity ent) runstandardplayerphysics = #347; // (EXT_CSQC_1) string(float playernum, string keyname) getplayerkeyvalue = #348; // (EXT_CSQC) diff --git a/quakec/csqctest/src/cs/defs.qc b/quakec/csqctest/src/cs/defs.qc index 589ea94f..d2de4095 100644 --- a/quakec/csqctest/src/cs/defs.qc +++ b/quakec/csqctest/src/cs/defs.qc @@ -57,8 +57,8 @@ float(string skinname) Anim_GetHeadSkinNumber; vector(string skinname) Anim_GetHeadOffset; //prediction -void() Pred_PlayerUpdated; -void() Pred_UpdateLocalMovement; +void(entity ent) Pred_PlayerUpdated; +void(entity ent) Pred_UpdateLocalMovement; vector vieworg; //menu diff --git a/quakec/csqctest/src/cs/entrypoints.qc b/quakec/csqctest/src/cs/entrypoints.qc index 4adc2a8e..545cca28 100644 --- a/quakec/csqctest/src/cs/entrypoints.qc +++ b/quakec/csqctest/src/cs/entrypoints.qc @@ -245,7 +245,6 @@ void() CSQC_Init = drawloadingscreen (); - Pred_ResetPlayerPrediction(); regcommands(); #ifndef FTEDEPENDANT diff --git a/quakec/csqctest/src/cs/map.qc b/quakec/csqctest/src/cs/map.qc index 3a1312e4..ff9e4bce 100644 --- a/quakec/csqctest/src/cs/map.qc +++ b/quakec/csqctest/src/cs/map.qc @@ -5,62 +5,24 @@ string() getentitytoken = #355; -//fixme: I want an engine solution -entity triggerchain; -.entity nexttrigger; -void() pmovetouchtriggers = +void() cs_teleport_touch = { - vector amin = pmove_org+pmove_mins; - vector amax = pmove_org+pmove_maxs; - vector emin; - vector emax; - entity t; - entity oself = self; - for (self = triggerchain; self; self = self.nexttrigger) + local entity t; + t = find(world, targetname, self.target); + if (t) { - emin = self.origin+self.mins; - if (emin_x > amax_x) - continue; - if (emin_y > amax_y) - continue; - if (emin_z > amax_z) - continue; - - emax = self.origin+self.maxs; - if (emax_x < amin_x) - continue; - if (emax_y < amin_y) - continue; - if (emax_z < amin_z) - continue; - - if (self.classname == "trigger_teleport") - { - t = find(world, targetname, self.target); - if (t) - { - makevectors(t.angles); - Pred_Predict_Teleport(t.origin + '0 0 27', v_forward*300, t.angles); - } - //maybe they use a mod that uses some other choice pattern - } - if (self.classname == "trigger_push") - { - //fixme: add support for trigger_push - } + makevectors(t.angles); + Pred_Predict_Teleport(t.origin + '0 0 27', v_forward*300, t.angles); } - - self = oself; -} +}; void() spawn_trigger_teleport = { - self.solid = SOLID_NOT;//SOLID_TRIGGER; + self.solid = SOLID_TRIGGER; setmodel(self, self.model); self.model = ""; - self.nexttrigger = triggerchain; - triggerchain = self; + self.touch = cs_teleport_touch; }; void() spawn_info_teleport_destination = @@ -69,18 +31,16 @@ void() spawn_info_teleport_destination = void() spawn_trigger_push = { - self.solid = SOLID_NOT;//SOLID_TRIGGER; + self.solid = SOLID_TRIGGER; setmodel(self, self.model); self.model = ""; - self.nexttrigger = triggerchain; - triggerchain = self; +// self.touch = cs_teleport_touch; }; void() spawn_worldspawn = { levelname = self.message; - mapname = "that was the mapname, dumbass"; remove(self); }; diff --git a/quakec/csqctest/src/cs/player.qc b/quakec/csqctest/src/cs/player.qc index ed5a3102..550d433c 100644 --- a/quakec/csqctest/src/cs/player.qc +++ b/quakec/csqctest/src/cs/player.qc @@ -30,10 +30,7 @@ static void() Player_Interpolate = { //do some frame interpolation. if (self.entnum == player_localentnum) { - Pred_UpdateLocalMovement(); - self.origin = pmove_org; - self.angles = input_angles; - self.angles_x = self.angles_x * -0.3333; + Pred_UpdateLocalMovement(self); } switch(self.modelstyle) @@ -99,6 +96,10 @@ static void(float g) Player_SetLocalInfoGender = { if (player_local == self) { + //if it was forced, don't lie to everyone else. + if (cvar_string("cg_forceskin") != "") + return; + switch(g) { case GENDER_FEMALE: @@ -299,10 +300,12 @@ void(float isnew) RefreshPlayer = JustRessed(); self.haddied = false; } + self.solid = SOLID_BBOX; } else { self.haddied = true; + self.solid = SOLID_NOT; } self.lastorg = self.origin; @@ -372,7 +375,7 @@ void(float isnew) RefreshPlayer = return; } - Pred_PlayerUpdated(); + Pred_PlayerUpdated(self); }; //this is sent after the server has run our movement command. diff --git a/quakec/csqctest/src/cs/prediction.qc b/quakec/csqctest/src/cs/prediction.qc index ba3b18a5..b6c6381d 100644 --- a/quakec/csqctest/src/cs/prediction.qc +++ b/quakec/csqctest/src/cs/prediction.qc @@ -1,7 +1,7 @@ /* UpdateLocalMovement: runs the local prediction (called from player.qc - local players are drawn for mirrors etc) out: vieworg (view origin, with chasecam/viewheight added) - out: pmove_org (raw player ent origin) + out: ` (raw player ent origin) PlayerUpdated: updates internal state, called from player.qc any time we got an update from the server. in: self (the player ent origin/velocity/mins/maxs) @@ -14,8 +14,9 @@ ResetPlayerPrediction: call if you broke the special pmove globals vector player_org; vector player_vel; -float player_jump_held; +float player_pmflags; float player_sequence; + float player_steptime; float player_step; @@ -26,16 +27,16 @@ float pmove_step; float pmove_steptime; float pmove_step_oldz; -void() pmovetouchtriggers; +.float pmove_flags; float pmoveframe; -nonstatic void() Pred_ResetPlayerPrediction = +nonstatic void(entity ent) Pred_ResetPlayerPrediction = { //reset the pmove to lerp from the new position - pmove_org = player_org; - pmove_vel = player_vel; + ent.origin = player_org; + ent.velocity = player_vel; pmoveframe = player_sequence+1; //+1 because the recieved frame has the move already done (server side) - pmove_jump_held = player_jump_held; + ent.pmove_flags = player_pmflags; if (pmoveframe < clientcommandframe-128) pmoveframe = clientcommandframe-128; //avoid an infinate loop @@ -54,32 +55,37 @@ void(vector newteleorg, vector newtelevel, vector newteleang) Pred_Predict_Telep setviewprop(33, newteleang); view_angles = newteleang; } - pmove_org = newteleorg; - pmove_vel = newtelevel; + other.origin = newteleorg; + other.velocity = newtelevel; input_angles = newteleang; }; -void(float endframe) Pred_RunMovement; +void(entity ent, float endframe) Pred_RunMovement; -nonstatic void() Pred_PlayerUpdated = +nonstatic void(entity ent) Pred_PlayerUpdated = { local float noerror; local vector o; + local vector v; + local float pmf; + + o = ent.origin; + v = ent.velocity; + pmf = ent.pmove_flags; noerror = cvar("cg_noerror"); //reset the prediction to last-known-good state - Pred_ResetPlayerPrediction(); - Pred_RunMovement(servercommandframe+1); - player_jump_held = pmove_jump_held; + Pred_ResetPlayerPrediction(ent); + Pred_RunMovement(ent, servercommandframe+1); + player_pmflags = ent.pmove_flags; + player_step = pmove_step; player_steptime = pmove_steptime; //pull out the new values - player_org = self.origin; - player_vel = self.velocity; - pmove_mins = self.mins; - pmove_maxs = self.maxs; + player_org = o; + player_vel = v; player_sequence = servercommandframe; if (noerror) @@ -87,25 +93,25 @@ nonstatic void() Pred_PlayerUpdated = pmove_error = '0 0 0'; pmove_errortime = time; - Pred_ResetPlayerPrediction(); + Pred_ResetPlayerPrediction(ent); } else { - Pred_RunMovement(clientcommandframe); //make sure we're up to date - o = pmove_org; //save off the old for the teleport check below. + Pred_RunMovement(ent, clientcommandframe); //make sure we're up to date + o = ent.origin; //save off the old for the teleport check below. //reset it, then update to now to guage how much our previous prediction was incorrect by - Pred_ResetPlayerPrediction(); - Pred_RunMovement(clientcommandframe); + Pred_ResetPlayerPrediction(ent); + Pred_RunMovement(ent, clientcommandframe); - if (vlen(o - pmove_org) > 64) + if (vlen(o - ent.origin) > 64) {//teleport pmove_error = '0 0 0'; pmove_errortime = time; } else { //figure out the error ammount, and lerp back to it, without forgetting about any current inaccuracies. - pmove_error = (pmove_errortime - time)*ERRORTIME * pmove_error + (o - pmove_org); + pmove_error = (pmove_errortime - time)*ERRORTIME * pmove_error + (o - ent.origin); if (vlen(pmove_error) < 1) pmove_error = '0 0 0'; pmove_errortime = time + 1/ERRORTIME; @@ -113,7 +119,7 @@ nonstatic void() Pred_PlayerUpdated = } }; -void(float endframe) Pred_RunMovement = +void(entity ent, float endframe) Pred_RunMovement = { if (servercommandframe >= player_sequence+63) { @@ -160,9 +166,7 @@ void(float endframe) Pred_RunMovement = { break; } - runstandardplayerphysics(); - - pmovetouchtriggers(); + runstandardplayerphysics(ent); pmoveframe++; } @@ -171,13 +175,13 @@ void(float endframe) Pred_RunMovement = input_angles = view_angles; }; -nonstatic void() Pred_UpdateLocalMovement = +nonstatic void(entity ent) Pred_UpdateLocalMovement = { local float viewheight; - Pred_RunMovement(clientcommandframe); + Pred_RunMovement(ent, clientcommandframe); - if (pmove_org_z > pmove_step_oldz+8 && pmove_org_z < pmove_step_oldz+24 && pmove_vel_z == 0) + if (ent.origin_z > pmove_step_oldz+8 && ent.origin_z < pmove_step_oldz+24 && pmove_vel_z == 0) { //evaluate out the remaining old step if (pmove_steptime - time > 0) @@ -186,10 +190,10 @@ nonstatic void() Pred_UpdateLocalMovement = pmove_step = 0; //work out the new step - pmove_step += (pmove_step_oldz-pmove_org_z); + pmove_step += (pmove_step_oldz-self.origin_z); pmove_steptime = time + 1/STEPTIME; } - pmove_step_oldz = pmove_org_z; + pmove_step_oldz = ent.origin_z; //allow the user to move the viewheight down 6 units so it's at +16, where projectiles come from. viewheight = cvar("v_viewheight"); @@ -198,7 +202,7 @@ nonstatic void() Pred_UpdateLocalMovement = else if (viewheight > 7) viewheight = 7; - vieworg = pmove_org; //the default view height + vieworg = ent.origin; //the default view height vieworg_z += getstati(STAT_VIEWHEIGHT) + viewheight; //correct the view position to compensate for any errors, slowly over time, 0.1 seconds. @@ -211,9 +215,10 @@ nonstatic void() Pred_UpdateLocalMovement = if (chasecam) { - view_angles_y += 180; + view_angles_y += cvar("cg_thirdPersonAngle"); + makevectors(view_angles); - traceline(pmove_org, vieworg - v_forward * 72+v_up*32, TRUE, self); + traceline(self.origin, vieworg - v_forward * cvar("cg_thirdPersonRange")+v_up*cvar("cg_thirdPersonHeight"), TRUE, self); vieworg = trace_endpos + v_forward*8; } }; diff --git a/quakec/csqctest/src/csprogs.src b/quakec/csqctest/src/csprogs.src index 0acbc5c0..860aafd4 100644 --- a/quakec/csqctest/src/csprogs.src +++ b/quakec/csqctest/src/csprogs.src @@ -17,12 +17,12 @@ common/econstants.qc cs/constants.qc common/pmovedefs.qc +common/pmove.qc cs/keys.qc common/makeallstatic.qc -common/pmove.qc cs/prediction.qc cs/q3playerm.qc cs/hlpm.qc diff --git a/quakec/csqctest/src/ss/client.qc b/quakec/csqctest/src/ss/client.qc index f61d7889..72037b7c 100644 --- a/quakec/csqctest/src/ss/client.qc +++ b/quakec/csqctest/src/ss/client.qc @@ -781,12 +781,15 @@ void() PlayerJump = if (self.waterlevel >= 2) { +//pmove code predicts this +/* if (self.watertype == CONTENT_WATER) self.velocity_z = 100; else if (self.watertype == CONTENT_SLIME) self.velocity_z = 80; else self.velocity_z = 50; +*/ // play swiming sound if (self.swim_flag < time) @@ -814,7 +817,9 @@ void() PlayerJump = self.button2 = 0; // player jumping sound sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); - self.velocity_z = self.velocity_z + 270; + +//pmove code predicts this +// self.velocity_z = self.velocity_z + 270; }; @@ -1547,44 +1552,11 @@ void(entity targ, entity attacker) ClientObituary = void() DefaultPlayerPhysics = #347; void() SV_RunClientCommand = { - pmove_org = self.origin; - pmove_vel = self.velocity; - pmove_mins = self.mins; - pmove_maxs = self.maxs; -// pmove_jump_held = self.jump_held; - pmove_waterjumptime = self.teleport_time; - //should match the one used by csqc. #ifdef OWNPLAYERPHYSICS - PMove(); + PMove(self); #else - DefaultPlayerPhysics(); + DefaultPlayerPhysics(self); #endif - - self.origin = pmove_org; - self.velocity = pmove_vel; -// self.jump_held = pmove_jump_held; - self.teleport_time = pmove_waterjumptime; - - self.waterlevel = 0;//FIXME - self.watertype = 0;//FIXME - - self.button0 = (input_buttons & 1); - self.button2 = !!(input_buttons & 2); -/* - self.button3 = !!(input_buttons & 4); - self.button4 = !!(input_buttons & 8); - self.button5 = !!(input_buttons & 16); - self.button6 = !!(input_buttons & 32); - self.button7 = !!(input_buttons & 64); - self.button8 = !!(input_buttons & 128); -*/ - self.v_angle = input_angles; - self.angles = input_angles; - self.angles_x *= -1/3; - self.impulse = input_impulse; - -//we don't need this DP extension -// self.movement = input_movevalues; };