From d31cc9f4f71e11042355024617cef550dc6b02b5 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 12 Dec 2014 14:11:12 +1100 Subject: [PATCH] Client side multijump (broken due to physics issues) --- qcsrc/client/progs.src | 1 + qcsrc/common/physics.qc | 16 ++-- qcsrc/common/physics.qh | 2 + qcsrc/common/stats.qh | 6 +- qcsrc/server/mutators/mutator_multijump.qc | 100 ++++++++++++++++----- 5 files changed, 97 insertions(+), 28 deletions(-) diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 4356c7ddb..7898ea270 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -120,6 +120,7 @@ command/cl_cmd.qc ../common/physics.qh ../server/mutators/mutator_dodging.qc +../server/mutators/mutator_multijump.qc ../server/t_halflife.qc ../server/t_jumppads.qc diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index 392c76719..0018cf1e9 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -465,7 +465,7 @@ void PlayerJump (void) return; if (self.cvar_cl_movement_track_canjump) - if (!(self.flags & FL_JUMPRELEASED)) + if (IS_JUMP_HELD(self)) return; // sv_jumpspeedcap_min/sv_jumpspeedcap_max act as baseline @@ -511,7 +511,7 @@ void PlayerJump (void) self.oldvelocity_z = self.velocity_z += mjumpheight; UNSET_ONGROUND(self); - self.flags &= ~FL_JUMPRELEASED; + SET_JUMP_HELD(self); animdecide_setaction(self, ANIMACTION_JUMP, TRUE); @@ -544,7 +544,7 @@ void CheckWaterJump() self.velocity_z = 225; #ifdef SVQC self.flags |= FL_WATERJUMP; - self.flags &= ~FL_JUMPRELEASED; + SET_JUMP_HELD(self); self.teleport_time = time + 2; // safety net #endif } @@ -557,7 +557,7 @@ void CheckPlayerJump() if (self.BUTTON_JUMP) PlayerJump(); else - self.flags |= FL_JUMPRELEASED; + UNSET_JUMP_HELD(self); #endif if (self.waterlevel == WATERLEVEL_SWIMMING) @@ -1614,6 +1614,10 @@ void PM_Main() #ifdef SVQC MUTATOR_CALLHOOK(PlayerPhysics); #endif +#ifdef CSQC + PM_multijump(); +#endif + // float forcedodge = 1; // if(forcedodge) { //#ifdef CSQC @@ -1728,7 +1732,9 @@ void PM_Main() // released at least once since the last jump if (PHYS_INPUT_BUTTON_JUMP(self)) { - if (IS_ONGROUND(self) && (!IS_JUMP_HELD(self) || !cvar("cl_movement_track_canjump"))) + pm_multijump = FALSE; + PM_multijump_checkjump(); + if((IS_ONGROUND(self) || pm_multijump) && (!IS_JUMP_HELD(self) || !cvar("cl_movement_track_canjump"))) { self.velocity_z += PHYS_JUMPVELOCITY; UNSET_ONGROUND(self); diff --git a/qcsrc/common/physics.qh b/qcsrc/common/physics.qh index 26fba894a..0afd9aedd 100644 --- a/qcsrc/common/physics.qh +++ b/qcsrc/common/physics.qh @@ -2,6 +2,8 @@ #ifdef CSQC + float pm_multijump; + #define PHYS_INPUT_ANGLES(s) input_angles // TODO #define PHYS_WORLD_ANGLES(s) input_angles diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index e30ee5919..603de5dd3 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -230,9 +230,9 @@ const float STAT_REVIVE_PROGRESS = 106; // 195 empty? // 196 empty? // 197 empty? -// 198 empty? -// 199 empty? -// 200 empty? +const float STAT_MULTIJUMP_ADD = 198; +const float STAT_MULTIJUMP_SPEED = 199; +const float STAT_MULTIJUMP = 200; const float STAT_DODGING_TIMEOUT = 201; const float STAT_DODGING_WALL = 202; const float STAT_DODGING_UP_SPEED = 203; diff --git a/qcsrc/server/mutators/mutator_multijump.qc b/qcsrc/server/mutators/mutator_multijump.qc index 50741dc20..92d4ef7a2 100644 --- a/qcsrc/server/mutators/mutator_multijump.qc +++ b/qcsrc/server/mutators/mutator_multijump.qc @@ -1,61 +1,102 @@ .float multijump_count; .float multijump_ready; -MUTATOR_HOOKFUNCTION(multijump_PlayerPhysics) +#ifdef CSQC + +#define PHYS_MOVE_MULTIJUMP pm_multijump +#define PHYS_MULTIJUMP getstati(STAT_MULTIJUMP) +#define PHYS_MULTIJUMP_SPEED getstatf(STAT_MULTIJUMP_SPEED) +#define PHYS_MULTIJUMP_ADD getstati(STAT_MULTIJUMP_ADD) + +#elif defined(SVQC) + +#define PHYS_MOVE_MULTIJUMP player_multijump +#define PHYS_MULTIJUMP autocvar_g_multijump +#define PHYS_MULTIJUMP_SPEED autocvar_g_multijump_speed +#define PHYS_MULTIJUMP_ADD autocvar_g_multijump_add + + +.float stat_multijump; +.float stat_multijump_speed; +.float stat_multijump_add; + +void multijump_UpdateStats() +{ + self.stat_multijump = PHYS_MULTIJUMP; + self.stat_multijump_speed = PHYS_MULTIJUMP_SPEED; + self.stat_multijump_add = PHYS_MULTIJUMP_ADD; +} + +void multijump_AddStats() +{ + addstat(STAT_MULTIJUMP, AS_INT, stat_multijump); + addstat(STAT_MULTIJUMP_SPEED, AS_FLOAT, stat_multijump_speed); + addstat(STAT_MULTIJUMP_ADD, AS_INT, stat_multijump_add); +} + +#endif + +void PM_multijump() { - if(self.flags & FL_ONGROUND) + if(!PHYS_MULTIJUMP) { return; } + + if(IS_ONGROUND(self)) { - if (autocvar_g_multijump > 0) + if (PHYS_MULTIJUMP > 0) self.multijump_count = 0; else self.multijump_count = -2; // the cvar value for infinite jumps is -1, so this needs to be smaller } - return FALSE; +#ifdef SVQC + multijump_UpdateStats(); +#endif } -MUTATOR_HOOKFUNCTION(multijump_PlayerJump) +float PM_multijump_checkjump() { - if (self.flags & FL_JUMPRELEASED && !(self.flags & FL_ONGROUND)) // jump button pressed this frame and we are in midair + if(!PHYS_MULTIJUMP) { return FALSE; } + + if (!IS_JUMP_HELD(self) && !IS_ONGROUND(self)) // 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 else self.multijump_ready = FALSE; - if(!player_multijump && self.multijump_ready && self.multijump_count < autocvar_g_multijump && self.velocity_z > autocvar_g_multijump_speed) + if(!PHYS_MOVE_MULTIJUMP && self.multijump_ready && self.multijump_count < PHYS_MULTIJUMP && self.velocity_z > PHYS_MULTIJUMP_SPEED) { - if (autocvar_g_multijump) + if (PHYS_MOVE_MULTIJUMP) { - if (autocvar_g_multijump_add == 0) // in this case we make the z velocity == jumpvelocity + if (!PHYS_MULTIJUMP_ADD) // in this case we make the z velocity == jumpvelocity { - if (self.velocity_z < autocvar_sv_jumpvelocity) + if (self.velocity_z < PHYS_JUMPVELOCITY) { - player_multijump = TRUE; + PHYS_MOVE_MULTIJUMP = TRUE; self.velocity_z = 0; } } else - player_multijump = TRUE; + PHYS_MOVE_MULTIJUMP = TRUE; - if(player_multijump) + if(PHYS_MOVE_MULTIJUMP) { - if(self.movement_x != 0 || self.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys + if(PHYS_INPUT_MOVEVALUES(self)_x != 0 || PHYS_INPUT_MOVEVALUES(self)_y != 0) // don't remove all speed if player isnt pressing any movement keys { - float curspeed; + float curspeed = vlen(vec2(self.velocity)); vector wishvel, wishdir; - curspeed = max( + /*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 - ); - makevectors(self.v_angle_y * '0 1 0'); - wishvel = v_forward * self.movement_x + v_right * self.movement_y; + );*/ + makevectors(PHYS_INPUT_ANGLES(self)_y * '0 1 0'); + wishvel = v_forward * PHYS_INPUT_MOVEVALUES(self)_x + v_right * PHYS_INPUT_MOVEVALUES(self)_y; wishdir = normalize(wishvel); self.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump self.velocity_y = wishdir_y * curspeed; // keep velocity_z unchanged! } - if (autocvar_g_multijump > 0) + if (PHYS_MULTIJUMP > 0) self.multijump_count += 1; } } @@ -65,6 +106,19 @@ MUTATOR_HOOKFUNCTION(multijump_PlayerJump) return FALSE; } +#ifdef SVQC +MUTATOR_HOOKFUNCTION(multijump_PlayerPhysics) +{ + PM_multijump(); + + return FALSE; +} + +MUTATOR_HOOKFUNCTION(multijump_PlayerJump) +{ + return PM_multijump_checkjump(); +} + MUTATOR_HOOKFUNCTION(multijump_BuildMutatorsString) { ret_string = strcat(ret_string, ":multijump"); @@ -84,5 +138,11 @@ MUTATOR_DEFINITION(mutator_multijump) MUTATOR_HOOK(BuildMutatorsString, multijump_BuildMutatorsString, CBC_ORDER_ANY); MUTATOR_HOOK(BuildMutatorsPrettyString, multijump_BuildMutatorsPrettyString, CBC_ORDER_ANY); + MUTATOR_ONADD + { + multijump_AddStats(); + } + return FALSE; } +#endif -- 2.39.2