djcev.com

//

Git Repos / fte_dogmode / commit 7472ec5

Commit: 7472ec54954781085e2524e76329e70a4392791e
Parent: d597d866862bfe0658f62366e11f6a8a6462c7f4
Author: Cameron Vanderzanden, 2023-11-13 16:15
Committer: Cameron Vanderzanden, 2023-11-13 16:15

Commit Message

Clean up timers, more bugs in pmove & prediction

Cleaned up the timers in pmove, reducing them from 4 to 2. Stair
behavior remains unchanged I think. Also fixed a bug that led to
a loss of velocity when looking up or down while traveling
onground or in the air (need to makevectors with only the yaw
input angle). Some refactoring, some function inline-ing (moved
PM_DoTouch into the slidemove, for example).

Various other things I'm for sure forgetting.

Change List

Diff qc/client.qc

diff --git a/qc/client.qc b/qc/client.qc
index 89d90db..208459d 100644
--- a/qc/client.qc
+++ b/qc/client.qc
@@ -238,7 +238,8 @@ float(entity to, float fl) SendPlayer =
WriteShort (MSG_ENTITY, self.velocity_z);
WriteFloat (MSG_ENTITY, self.flags);
WriteFloat (MSG_ENTITY, self.pmove_flags);
- // WriteFloat (MSG_ENTITY, self.movetype);
+ WriteFloat (MSG_ENTITY, self.doublejump_timer);
+ WriteFloat (MSG_ENTITY, self.groundboost_timer);
return TRUE;
};

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_defsbuiltins.qc

diff --git a/qc/csqc/csqc_defsbuiltins.qc b/qc/csqc/csqc_defsbuiltins.qc
index 9997a29..f144c5a 100644
--- a/qc/csqc/csqc_defsbuiltins.qc
+++ b/qc/csqc/csqc_defsbuiltins.qc
@@ -36,6 +36,12 @@ vector(vector) normalize = #9;
void(string e) error = #10;
void(string n) objerror = #11;
float(vector) vlen = #12;
+
+// Given a direction vector, returns the yaw angle in which that direction
+// vector points. If an entity is passed, the yaw angle will be relative to
+// that entity's gravity direction.
+float(vector v, optional entity reference) vectoyaw = #13;
+
entity() spawn = #14;
void(entity e) remove = #15;

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_defsclient.qc

diff --git a/qc/csqc/csqc_defsclient.qc b/qc/csqc/csqc_defsclient.qc
index c889ddf..fd0eeec 100644
--- a/qc/csqc/csqc_defsclient.qc
+++ b/qc/csqc/csqc_defsclient.qc
@@ -65,12 +65,12 @@ vector vieworg; // origin for viewentity -- CEV
vector view_angles; // +x=DOWN

entity player_local; // handle to the local player entity
-float player_localentnum;

vector player_org; // prediction globals; from CSQCTest -- CEV
vector player_vel;
float player_flags;
-// float player_gravity;
+float player_doublejump_timer;
+float player_groundboost_timer;
float player_pmflags;
float player_sequence;
float player_step;

Return to the top of this page or return to the overview of this repo.

Diff qc/csqc/csqc_player.qc

diff --git a/qc/csqc/csqc_player.qc b/qc/csqc/csqc_player.qc
index b16f9c8..e63b5bc 100644
--- a/qc/csqc/csqc_player.qc
+++ b/qc/csqc/csqc_player.qc
@@ -26,6 +26,8 @@ void(entity ent) PlayerResetPrediction =
ent.velocity = player_vel;
ent.flags = player_flags;
ent.pmove_flags = player_pmflags;
+ ent.doublejump_timer = player_doublejump_timer;
+ ent.groundboost_timer = player_groundboost_timer;

// +1 because the received frame has the move already done (server side)
pmove_frame = player_sequence + 1;
@@ -222,7 +224,8 @@ void(float isnew) PlayerUpdate =
self.velocity_z = ReadShort ();
self.flags = ReadFloat ();
self.pmove_flags = ReadFloat ();
- // self.movetype = ReadFloat ();
+ self.doublejump_timer = ReadFloat ();
+ self.groundboost_timer = ReadFloat ();

if (isnew && !(self.predraw))
PlayerNew ();
@@ -237,12 +240,18 @@ void(float isnew) PlayerUpdate =
if (self.entnum == player_localentnum)
{
local vector o, v;
- local float pmflags, tempflags;
+ local float djt, gbt, pmflags, tempflags;

// this is us; save for later
player_local = self;
o = self.origin;
- v = self.velocity;
+ if (intermission)
+ // zero out velocity if in intermission -- CEV
+ o = self.velocity = '0 0 0';
+ else
+ v = self.velocity;
+ djt = self.doublejump_timer;
+ gbt = self.groundboost_timer;
tempflags = self.flags;
pmflags = self.pmove_flags;

@@ -251,6 +260,8 @@ void(float isnew) PlayerUpdate =
PlayerRunMovement (self, servercommandframe + 1);

// TODO CEV ????
+ player_doublejump_timer = djt;
+ player_groundboost_timer = gbt;
player_flags = tempflags;
player_pmflags = pmflags;
player_org = o;

Return to the top of this page or return to the overview of this repo.

Diff qc/pmove.qc

diff --git a/qc/pmove.qc b/qc/pmove.qc
index 1039a5c..2571402 100644
--- a/qc/pmove.qc
+++ b/qc/pmove.qc
@@ -2,25 +2,25 @@
// PMOVE
//==============================================================================

-// TODO: re-implement PM_WallJump
-// TODO: implement PMF_WINDMOVE / wind brush nostick timer
+// TODO CEV: crouching
+// TODO CEV: re-implement PM_WallJump
+// TODO CEV: try again to simplify the makevectors setup?

// globals managed by FTEQW
+float input_buttons;
+float input_impulse;
float input_timelength; // from fteextensions.qc -- CEV
vector input_angles; // +x = DOWN
vector input_movevalues;
-float input_buttons;
-float input_impulse;

// fields
.entity groundentity;
.vector groundnormal;

+// note: timers are expensive, require synch between server and client -- CEV
.float pmove_flags; // custom movement flags -- CEV
.float doublejump_timer; // time in which a player can doublejump
-.float groundboost_timer; // time to simulate low friction -- CEV
-.float nostick_timer; // time to not stick to the floor -- CEV
-.float skim_timer; // time to skim/clip past walls -- CEV
+.float groundboost_timer; // time to apply low friction -- CEV
.void() customphysics;

// pmove constants
@@ -55,7 +55,6 @@ const float PM_WATERSINKSPEED = 60.0f;

const float PM_DOUBLEJUMP_WINDOW = 0.4f;// 2 jumps in this time is a double
const float PM_GROUNDBOOST_WINDOW = 0.4f;// groundboost duration
-const float PM_NOSTICK_WINDOW = 0.35f; // duration to perform onesided clips
const float PM_TELEJUMP_WINDOW = 0.4f; // duration to perform a telejump
const float PM_WALLJUMP_WINDOW = 0.2f; // duration between walljumps
const float PM_WALLCLIP_WINDOW = 0.25f; //
@@ -79,13 +78,10 @@ enumflags
PMF_JUMP_HELD, // player is holding the jump key
PMF_DOUBLEJUMPED, // entity has doublejumped
PMF_WALLJUMP, // entity has walljumped
- PMF_WATERJUMP, // entity has waterjumped
- PMF_WINDMOVE, // entity has been trigger_push'ed
- PMF_NOSTICK // entity won't stick to the floor
+ PMF_WATERJUMP // entity has waterjumped
};

// prototypes
-static void(entity target) PM_DoTouch;
float() PM_Nudge;
void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove;
void(entity ground_e, vector ground_v, int docheck) PM_SetOnground;
@@ -98,31 +94,13 @@ void(vector wishvel, float wishspeed, float accel, float move_time)
void(vector wishdir, float wishspeed, float move_time) PM_AirControl;
void() PM_Jump;
// TODO CEV void(vector checkdir) PM_WallJump;
-void(vector wishvel, float premove, float mt) PM_WalkAccelerate;
-void(vector wishvel, float move_time) PM_SwimAccelerate;
-void(vector wishvel, float scale, float move_time) PM_NoClipAccelerate;
+void(float premove, float move_time) PM_WalkAccelerate;
+void(float move_time) PM_SwimAccelerate;
+void(float scale, float move_time) PM_NoClipAccelerate;
void(float move_time) PM_ManageTimers;
void(entity target) PM_Move;

//======================================================================
-// PM_DoTouch
-// call when self has touched target (to run target's touch function)
-//----------------------------------------------------------------------
-static void(entity target) PM_DoTouch =
-{
- if (target.touch == __NULL__)
- return;
-
- entity orig_self;
-
- orig_self = self;
- other = self;
- self = target;
- self.touch();
- self = orig_self;
-};
-
-//======================================================================
// PM_Nudge
//
// from the GPL2 CSQCTest code that comes with FTEQW
@@ -172,10 +150,11 @@ float() PM_Nudge =
//======================================================================
// PM_DanceMove
//
-// Updates origin, moves the player through the world. Similar to Q3
-// SlideMove and Q1 FlyMove. This version handles steps, applies gravity,
-// and restores velocity based on a timer check (those latter two are
-// features of Q3's SlideMove).
+// Updates origin according to velocity, moves the player through the world.
+// Same as Q3 SlideMove and Q1 FlyMove. This version handles steps, applies
+// gravity, and restores velocity based on a timer check (those latter two
+// are features of Q3's SlideMove). I've inlined a number of functions
+// (ClipVelocity, DoTouch) to hopefully improve performance.
//
// Based on code from the Nuclide SDK (presumably by Eukara), specifically
// the function PMoveCustom_Move found in the file pmove_custom.qc. This
@@ -195,7 +174,8 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
grav = self.gravity;
else
grav = 1.0;
- grav = grav * autocvar (sv_gravity, 800) * input_timelength;
+ grav = grav * autocvar (sv_gravity, PM_GRAVITY) *
+ input_timelength;
// Half now, half later. Apparently affects framerate
// dependence. -- CEV
self.velocity_z -= grav * 0.5;
@@ -327,7 +307,7 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
}

// clip velocity to the saved plane
- // integrated PM_Rebound aka PM_ClipVelocity -- CEV
+ // inline PM_Rebound aka PM_ClipVelocity -- CEV
backoff = self.velocity * plane;

if (backoff < 0)
@@ -360,8 +340,17 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
self.pmove_flags &= ~PMF_ONGROUND;
}

- // touch the saved entity -- CEV
- PM_DoTouch (touched_ent);
+ // touch the saved entity; inline PM_DoTouch -- CEV
+ if (touched_ent && touched_ent.touch != __NULL__)
+ {
+ local entity orig_self;
+
+ orig_self = self;
+ other = self;
+ self = touched_ent;
+ self.touch ();
+ self = orig_self;
+ }

// if velocity interacts with prev_plane then clip to it.
// I'm duplicating a little code here (ClipVelocity),
@@ -702,8 +691,8 @@ void() PM_Jump =
dprint (sprintf("PM_Jump: telejump %g, ",
self.velocity_z));
#endif
- // additive jump, though it shouldn't matter -- CEV
- self.velocity_z += PM_TELEJUMPSPEED;
+ // non-additive jump, though it shouldn't matter -- CEV
+ self.velocity_z = PM_TELEJUMPSPEED;
}
else if (self.groundnormal && self.groundnormal_z == 1 &&
self.groundboost_timer > 0)
@@ -721,17 +710,14 @@ void() PM_Jump =
dprint (sprintf("PM_Jump: doublejump %g, ",
self.velocity_z));
#endif
- // we want an additive doublejump here -- CEV
+ // the groundnormal is weird - some kind of ramp -
+ // so we want an additive doublejump here -- CEV
self.velocity_z += PM_DOUBLEJUMPSPEED;
}

// set the doublejump countdown timer -- CEV
self.doublejump_timer = PM_DOUBLEJUMP_WINDOW;
self.pmove_flags |= PMF_DOUBLEJUMPED;
-
- // re-set the nostick timer whenever we doublejump -- CEV
- if (self.nostick_timer <= 0)
- self.nostick_timer = PM_NOSTICK_WINDOW;
}
else
{
@@ -742,7 +728,7 @@ void() PM_Jump =

self.velocity_z += PM_JUMPSPEED;

- // set the doublejump countdown timer -- CEV
+ // timers for normal jumps -- CEV
self.doublejump_timer = PM_DOUBLEJUMP_WINDOW;
}

@@ -751,13 +737,12 @@ void() PM_Jump =
dprint (sprintf("%g\n", self.velocity_z));
#endif

- // clear flags
+ // manage flags -- CEV
PM_SetOnground (__NULL__, __NULL__, FALSE);
self.pmove_flags |= PMF_JUMP_HELD;

- // timers
+ // timers for all jumps -- CEV
self.groundboost_timer = PM_GROUNDBOOST_WINDOW;
- self.skim_timer = PM_WALLCLIP_WINDOW;
};

//----------------------------------------------------------------------
@@ -834,33 +819,60 @@ void(vector checkdir) PM_WallJump =
// Handle acceleration for MOVETYPE_WALK entities (players).
// Modifies velocity. -- CEV
//----------------------------------------------------------------------
-void(vector wishvel, float premove, float mt) PM_WalkAccelerate =
+void(float premove, float move_time) PM_WalkAccelerate =
{
- vector wishdir, wishang;
- float wishspeed;
+ vector wishvel, wishdir;
+ float accel, friction, wishspeed, wishyaw;

- wishspeed = vlen ([wishvel_x, wishvel_y, 0]);
- wishdir = normalize ([wishvel_x, wishvel_y, 0]);
+ accel = friction = wishyaw = 0;
+
+ // only yaw matters here -- CEV
+ makevectors ([0, input_angles_y, 0]);
+
+ wishvel = v_forward * input_movevalues_x;
+ wishvel += v_right * input_movevalues_y;
+ wishvel += v_up * input_movevalues_z;
+ wishspeed = vlen (wishvel);
+ wishdir = normalize (wishvel);

if (wishspeed > PM_MAXSPEED)
wishspeed = PM_MAXSPEED;

+ // calculate the difference between the yaw angle the user
+ // is requesting to move and the yaw angle we're currently
+ // moving in. inspired by Slide mod; might be slow -- CEV
+ wishyaw = vectoyaw (wishvel) - vectoyaw (self.velocity);
+
+ // limit wishyaw to a range of 0-180 (roughly) -- CEV
+ if (wishyaw < 0)
+ wishyaw = wishyaw + 360;
+ if (wishyaw >= 180)
+ wishyaw = fabs (wishyaw - 360);
+
if (premove)
{
if (self.pmove_flags & PMF_ONLADDER)
{
// ladder physics
- if (input_buttons & 2)
+ // these currently stutter in high ping (or low netfps)
+ // situations because we rely on touch()ing the ladder
+ // trigger to set PMF_ONLADDER -- TODO CEV
+ self.velocity = 0.75 * self.velocity;
+
+ if (input_buttons & 2 || input_movevalues_z > 0)
+ {
+ // PlayerClimb -- johnfitz
+ self.velocity_z = 160;
+ }
+ else if (input_movevalues_z < 0)
{
- // PlayerClimb
- // johnfitz
- self.velocity = '0 0 160';
+ // PlayerClimbDown -- CEV
+ self.velocity_z = -160;
}
else
{
self.flags |= FL_JUMPRELEASED;
self.pmove_flags &= ~PMF_JUMP_HELD;
- self.velocity = 0.9 * self.velocity;
self.velocity_z = 0;
}

@@ -868,12 +880,13 @@ void(vector wishvel, float premove, float mt) PM_WalkAccelerate =
}
else
{
- if (input_buttons & 2)
+ if (input_buttons & 2 || self.button2)
{
// +jump was pressed
if (self.pmove_flags & PMF_ONGROUND)
// normal jump
PM_Jump ();
+ // TODO CEV
// else
// PM_WallJump (right);
}
@@ -890,74 +903,76 @@ void(vector wishvel, float premove, float mt) PM_WalkAccelerate =
// Probably has unintended consequences. -- CEV
if (self.pmove_flags & PMF_STARTGROUND)
{
- // we're on ground so apply friction and pick an
- // acceleration value -- CEV
+ // we're on ground so pick accel and friction values -- CEV
if (self.groundboost_timer > 0)
{
- PM_Friction (PM_BOOSTFRICTION, mt);
- PM_Accelerate (wishdir, wishspeed, PM_BOOSTACCEL, mt);
+ accel = PM_BOOSTACCEL;
+ friction = PM_BOOSTFRICTION;
}
else
{
- PM_Friction (PM_GROUNDFRICTION, mt);
- PM_Accelerate (wishdir, wishspeed, PM_GROUNDACCEL, mt);
+ accel = PM_GROUNDACCEL;
+ friction = PM_GROUNDFRICTION;
+ }
+
+ /* testing something out here -- TODO CEV
+ if (!input_movevalues_x && self.teleport_time <= (time - 0.1) &&
+ self.groundboost_timer > 0 &&
+ (wishyaw > 75 && wishyaw < 105))
+ {
+ // if we're onground, haven't just exited a teleporter,
+ // are within the boost timer, and are holding left
+ // or right then redirect left/right velocity into
+ // forward velocity to prevent sudden changes of
+ // direction while jumping up stairs -- CEV
+ wishvel = v_forward * fabs(input_movevalues_y * 1.2f);
+ wishvel += v_right * (input_movevalues_y * 0.05f);
+ wishvel += v_up * input_movevalues_z;
+ #ifdef SSQC
+ dprint ("PM_WalkAccelerate: altering wishvel\n");
+ #endif
+ wishspeed = vlen (wishvel);
+ wishdir = normalize (wishvel);
}
+ */
+ }
+ else if (input_movevalues_x && input_movevalues_y)
+ {
+ // we're in the air and the player is requesting both
+ // forward/back and sideways movement, so pick the Q3
+ // air accel value -- CEV
+ accel = PM_AIRACCELQ3;
+ }
+ else if ((wishyaw > 45 && wishyaw < 135) ||
+ vlen ([self.velocity_x, self.velocity_y, 0]) <
+ (PM_MAXAIRSPEED - 1))
+ {
+ // Q1 air control when requesting movement within 45 to
+ // 135 degrees of current movement -- CEV
+ PM_AirAccelerate (wishvel, wishspeed, PM_AIRACCEL, move_time);
}
else
{
- if (input_movevalues_x && input_movevalues_y)
- {
- // we're in the air and the player is requesting both
- // forward/back and sideways movement, so pick the Q3
- // air accel value -- CEV
- PM_Accelerate (wishdir, wishspeed, PM_AIRACCELQ3, mt);
- }
+ if (wishyaw >= 135)
+ // we're slowing down
+ accel = PM_AIRACCELBACK;
else
- {
- // I'm a little afraid doing this is expensive
- // CPU-wise but it seems to be the right way.
- // this is inspired by the old Slide mod -- CEV
-
- // calculate the difference between the angle
- // we're currently moving and the angle the
- // user is requesting to move -- CEV
- // there's probably a way to do this with input_angles
- wishang = vectoangles (wishdir) -
- vectoangles (self.velocity);
-
- // limit wishang_y to a range of 0-180 (roughly)
- if (wishang_y < 0)
- wishang_y = wishang_y + 360;
- if (wishang_y >= 180)
- wishang_y = fabs (wishang_y - 360);
-
- if ((wishang_y > 45) && (wishang_y < 135) &&
- vlen ([self.velocity_x, self.velocity_y, 0])
- >= 90)
- {
- // Q1 air control when requesting movement
- // within 45 to 135 degrees of current
- // movement -- CEV
- PM_AirAccelerate (wishvel, wishspeed,
- PM_AIRACCEL, mt);
- }
- else
- {
- // +direction style air control -- CEV
- if (wishang_y >= 135)
- // we're slowing down
- PM_Accelerate (wishdir, wishspeed,
- PM_AIRACCELBACK, mt);
- else
- // we're gaining speed
- PM_Accelerate (wishdir, wishspeed,
- PM_AIRACCELFWD, mt);
+ // we're gaining speed
+ accel = PM_AIRACCELFWD;

- PM_AirControl (wishdir, wishspeed, mt);
- }
- }
+ // borrow the local friction var to flag a conditional below
+ friction = -1;
}

+ if (friction > 0)
+ PM_Friction (friction, move_time);
+
+ if (accel > 0)
+ PM_Accelerate (wishdir, wishspeed, accel, move_time);
+
+ if (friction < 0)
+ PM_AirControl (wishdir, wishspeed, move_time);
+
if (!premove)
self.pmove_flags &= ~PMF_STARTGROUND;
};
@@ -966,10 +981,17 @@ void(vector wishvel, float premove, float mt) PM_WalkAccelerate =
// PM_SwimAccelerate
// Largely copied from id Software's WaterMove. Works like NoClipAccelerate.
//----------------------------------------------------------------------
-void(vector wishvel, float move_time) PM_SwimAccelerate =
+void(float move_time) PM_SwimAccelerate =
{
+ vector wishvel;
float wishspeed;

+ makevectors (input_angles);
+
+ wishvel = v_forward * input_movevalues_x;
+ wishvel += v_right * input_movevalues_y;
+ wishvel += v_up * input_movevalues_z;
+
// CheckWaterJump
if (self.waterlevel == WATERLEVEL_WAIST)
{
@@ -1000,10 +1022,6 @@ void(vector wishvel, float move_time) PM_SwimAccelerate =
self.velocity_z = PM_JUMPSPEED;
// safety net
self.teleport_time = time + 2;
- // don't stick to the floor
- self.nostick_timer = PM_NOSTICK_WINDOW;
- // don't skim/clip past walls
- self.skim_timer = 0;
}
}
}
@@ -1034,10 +1052,17 @@ void(vector wishvel, float move_time) PM_SwimAccelerate =
// Basic acceleration for flying / noclipping players. Not suitable for
// swimming. -- CEV
//----------------------------------------------------------------------
-void(vector wishvel, float scale, float move_time) PM_NoClipAccelerate =
+void(float scale, float move_time) PM_NoClipAccelerate =
{
+ vector wishvel;
float wishspeed;

+ makevectors (input_angles);
+
+ wishvel = v_forward * input_movevalues_x;
+ wishvel += v_right * input_movevalues_y;
+ wishvel += v_up * input_movevalues_z;
+
// smartjump
if (input_buttons & 2)
wishvel_z = max (PM_MAXSPEED, wishvel_z);
@@ -1066,16 +1091,6 @@ void(float move_time) PM_ManageTimers =
self.groundboost_timer -= move_time;
else if (self.groundboost_timer < 0)
self.groundboost_timer = 0;
-
- if (self.nostick_timer > 0 && move_time > 0)
- self.nostick_timer -= move_time;
- else if (self.nostick_timer < 0)
- self.nostick_timer = 0;
-
- if (self.skim_timer > 0 && move_time > 0)
- self.skim_timer -= move_time;
- else if (self.skim_timer < 0)
- self.skim_timer = 0;
};

//======================================================================
@@ -1083,35 +1098,27 @@ void(float move_time) PM_ManageTimers =
//----------------------------------------------------------------------
void(entity target) PM_Move =
{
- vector wishvel;
entity oldself;

+ if (input_timelength <= 0)
+ // don't process partial frames -- CEV
+ /*
+ dprint (sprintf("PM_Move: returning, input_timelength: %g\n",
+ input_timelength));
+ */
+ return;
+
oldself = self;
self = target;

PM_Nudge ();

+ // TODO CEV this is the wrong place to clear PMF_JUMP_HELD
if (!(input_buttons & 2))
self.pmove_flags &= ~PMF_JUMP_HELD;

PM_CategorizePosition ();

- if (input_timelength < 0)
- {
- dprint (sprintf("PM_Move: returning, input_timelength: %g\n",
- input_timelength));
- self = oldself;
- return;
- }
-
- // make vectors & prepare wishvel here, once, instead of in the
- // individual accelerate functions -- CEV
- makevectors (input_angles);
-
- wishvel = v_forward * input_movevalues_x;
- wishvel += v_right * input_movevalues_y;
- wishvel += v_up * input_movevalues_z;
-
switch (self.movetype)
{
case MOVETYPE_WALK:
@@ -1132,29 +1139,40 @@ void(entity target) PM_Move =
dostep = TRUE;
sticky = FALSE;
// swim acceleration
- PM_SwimAccelerate (wishvel,
- input_timelength * 0.5f);
+ PM_SwimAccelerate (input_timelength * 0.5f);
}
else
{
- PM_WalkAccelerate (wishvel, TRUE,
+ PM_WalkAccelerate (TRUE,
input_timelength * 0.5f);

// WalkAccelerate calls Jump which might
- // alter pmove_flags -- CEV
- if (self.nostick_timer > 0)
- sticky = FALSE;
- else
+ // alter pmove_flags, so do our feature
+ // checks afterwards -- CEV
+ if (self.doublejump_timer > 0 &&
+ !(self.pmove_flags & PMF_DOUBLEJUMPED))
+ // we've jumped & haven't doublejumped,
+ // so do sticky steps -- CEV
sticky = TRUE;
+ else
+ // otherwise nostick -- CEV
+ sticky = FALSE;

- // gravity checks
- dogravity = !(self.pmove_flags & PMF_ONGROUND);
- if (self.groundnormal && self.groundnormal_z <1)
- // apply gravity when we're on a ramp
+ // apply gravity only when in the air or on
+ // a ramp -- CEV
+ if (self.groundnormal &&
+ self.groundnormal_z < 1.0f)
dogravity = TRUE;
+ else if (!(self.pmove_flags & PMF_ONGROUND))
+ dogravity = TRUE;
+ else
+ dogravity = FALSE;

// skim / wallclipping checks -- CEV
- if (self.skim_timer > 0)
+ if (self.doublejump_timer >
+ (PM_DOUBLEJUMP_WINDOW -
+ PM_WALLCLIP_WINDOW) &&
+ self.teleport_time <= (time - 0.1))
doskim = TRUE;

if (self.pmove_flags & PMF_ONLADDER)
@@ -1170,15 +1188,14 @@ void(entity target) PM_Move =
// timers (part 1) -- CEV
PM_ManageTimers (input_timelength * 0.5f);

- // do the move
+ // Do the move. Bounce, Rock, Skate, Roll -- CEV
PM_DanceMove (dogravity, sticky, dostep, doskim);

// second pass at acceleration
if (self.waterlevel >= WATERLEVEL_WAIST)
- PM_SwimAccelerate (wishvel,
- input_timelength * 0.5f);
+ PM_SwimAccelerate (input_timelength * 0.5f);
else
- PM_WalkAccelerate (wishvel, FALSE,
+ PM_WalkAccelerate (FALSE,
input_timelength * 0.5f);

// timers (part 2) -- CEV
@@ -1193,17 +1210,16 @@ void(entity target) PM_Move =
case MOVETYPE_FLY:
// split the acceleration in two to reduce
// framerate dependence. -- CEV
- PM_NoClipAccelerate (wishvel, 1.0f,
- input_timelength * 0.5f);
+ PM_NoClipAccelerate (1.0f, input_timelength * 0.5f);
PM_DanceMove (FALSE, TRUE, TRUE, FALSE);
- PM_NoClipAccelerate (wishvel, 1.0f,
- input_timelength * 0.5f);
+ PM_NoClipAccelerate (1.0f, input_timelength * 0.5f);
break;

case MOVETYPE_NOCLIP:
// noclip is a debugging feature, no need to
- // worry about consistency. -- CEV
- PM_NoClipAccelerate (wishvel, 1.0f, input_timelength);
+ // worry about acceleration consistency. -- CEV
+ PM_NoClipAccelerate (1.0f, input_timelength);
+ // we're noclipping so update origin directly -- CEV
self.origin += self.velocity * input_timelength;
break;

@@ -1212,9 +1228,7 @@ void(entity target) PM_Move =
}

PM_SetOnground (self.groundentity, self.groundnormal, TRUE);
- #ifdef SSQC
touchtriggers (self);
- #endif
self = oldself;
};

Return to the top of this page or return to the overview of this repo.

Diff qc/triggers_push.qc

diff --git a/qc/triggers_push.qc b/qc/triggers_push.qc
index 091c016..1c20db0 100644
--- a/qc/triggers_push.qc
+++ b/qc/triggers_push.qc
@@ -103,7 +103,7 @@ vector(vector org, entity tgt, float ht) trigger_push_calculatevelocity =

torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;

- grav = cvar ("sv_gravity");
+ grav = autocvar (sv_gravity, PM_GRAVITY);

zdist = torg_z - org_z;
sdist = vlen (torg - org - zdist * '0 0 1');
@@ -253,15 +253,6 @@ void() trigger_push_touch =

if (other.classname == "player")
{
- /*
- // for debugging -- CEV
- dprint ("trigger_push_touch: target ");
- dprint (self.target);
- dprint (" movedir ");
- dprint (vtos(self.movedir));
- dprint ("\n");
- */
-
if (!(self.spawnflags & DT_SILENT))
{
if (other.fly_sound < time)

Return to the top of this page or return to the overview of this repo.

Diff qc/triggers_teleport.qc

diff --git a/qc/triggers_teleport.qc b/qc/triggers_teleport.qc
index eb656b2..4b4365c 100644
--- a/qc/triggers_teleport.qc
+++ b/qc/triggers_teleport.qc
@@ -278,8 +278,6 @@ void() teleport_touch =
// turn this way immediately
other.fixangle = 1;
other.teleport_time = time + 0.7;
- // don't restore velocity on exiting teleporter -- CEV
- other.skim_timer = 0;
// push player out at PM_TELEEXITSPEED -- CEV
other.velocity = v_forward * PM_TELEEXITSPEED;
}

Return to the top of this page or return to the overview of this repo.