.float() PlayerPhysplug;
+#ifdef SVQC
+.float stat_dodging_frozen;
+.float stat_sv_airaccel_qw;
+.float stat_sv_airstrafeaccel_qw;
+.float stat_sv_airspeedlimit_nonqw;
+.float stat_sv_maxspeed;
+.float stat_movement_highspeed;
+
+.float stat_jetpack_accel_side;
+.float stat_jetpack_accel_up;
+.float stat_jetpack_antigravity;
+.float stat_jetpack_fuel;
+.float stat_jetpack_maxspeed_up;
+.float stat_jetpack_maxspeed_side;
+
+void Physics_AddStats()
+{
+ // g_movementspeed hack
+ addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
+ addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
+ addstat(STAT_MOVEVARS_AIRACCEL_QW, AS_FLOAT, stat_sv_airaccel_qw);
+ addstat(STAT_MOVEVARS_AIRSTRAFEACCEL_QW, AS_FLOAT, stat_sv_airstrafeaccel_qw);
+ addstat(STAT_MOVEVARS_HIGHSPEED, AS_FLOAT, stat_movement_highspeed);
+
+ // dodging
+ addstat(STAT_DODGING_FROZEN, AS_INT, stat_dodging_frozen);
+
+ // jet pack
+ addstat(STAT_JETPACK_ACCEL_SIDE, AS_FLOAT, stat_jetpack_accel_side);
+ addstat(STAT_JETPACK_ACCEL_UP, AS_FLOAT, stat_jetpack_accel_up);
+ addstat(STAT_JETPACK_ANTIGRAVITY, AS_FLOAT, stat_jetpack_antigravity);
+ addstat(STAT_JETPACK_FUEL, AS_FLOAT, stat_jetpack_fuel);
+ addstat(STAT_JETPACK_MAXSPEED_UP, AS_FLOAT, stat_jetpack_maxspeed_up);
+ addstat(STAT_JETPACK_MAXSPEED_SIDE, AS_FLOAT, stat_jetpack_maxspeed_side);
+}
+#endif
+
// Client/server mappings
#ifdef CSQC
.float watertype;
#define PHYS_BUTTON_HOOK(s) (input_buttons & 32)
+ #define PHYS_DODGING_FROZEN getstati(STAT_DODGING_FROZEN)
+
#elif defined(SVQC)
#define PHYS_INPUT_ANGLES(s) s.v_angle
#define PHYS_BUTTON_HOOK(s) s.BUTTON_HOOK
+ #define PHYS_DODGING_FROZEN autocvar_sv_dodging_frozen
+
#endif
float IsMoveInDirection(vector mv, float angle) // key mix factor
void PlayerJump (void)
{
#ifdef SVQC
- if (self.frozen)
+ if (PHYS_FROZEN(self))
return; // no jumping in freezetag when frozen
if (self.player_blocked)
void CheckWaterJump()
{
-#ifdef SVQC
-
// check for a jump-out-of-water
- makevectors(self.angles);
+ makevectors(PHYS_INPUT_ANGLES(self));
vector start = self.origin;
start_z += 8;
v_forward_z = 0;
traceline(start, end, TRUE, self);
if (trace_fraction == 1)
{ // open at eye level
- self.flags |= FL_WATERJUMP;
self.velocity_z = 225;
+#ifdef SVQC
+ self.flags |= FL_WATERJUMP;
self.flags &= ~FL_JUMPRELEASED;
self.teleport_time = time + 2; // safety net
+#endif
}
}
-#endif
}
void CheckPlayerJump()
else
self.flags |= FL_JUMPRELEASED;
+#endif
if (self.waterlevel == WATERLEVEL_SWIMMING)
CheckWaterJump();
-#endif
}
float racecar_angle(float forward, float down)
#endif
}
+// predict frozen movement, as frozen players CAN move in some cases
void PM_check_frozen(void)
{
-#ifdef SVQC
- if (!self.frozen)
+ if (!PHYS_FROZEN(self))
return;
- if (autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
+ if (PHYS_DODGING_FROZEN
+#ifdef SVQC
+ && IS_REAL_CLIENT(self)
+#endif
+ )
{
PHYS_INPUT_MOVEVALUES(self)_x = bound(-5, PHYS_INPUT_MOVEVALUES(self).x, 5);
PHYS_INPUT_MOVEVALUES(self)_y = bound(-5, PHYS_INPUT_MOVEVALUES(self).y, 5);
}
else
PHYS_INPUT_MOVEVALUES(self) = '0 0 0';
- self.disableclientprediction = 1;
vector midpoint = ((self.absmin + self.absmax) * 0.5);
if (pointcontents(midpoint) == CONTENT_WATER)
if (pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
self.velocity_z = 200;
}
-#endif
}
void PM_check_blocked(void)
if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
if (!IS_ONGROUND(self) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
self.velocity_z -= g * 0.5;
-#else
- if (time >= self.teleport_time)
- PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE * maxspd_mod, 1, 0, 0, 0);
#endif
+#ifdef SVQC
// water acceleration
- //PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE * maxspd_mod, 1, 0, 0, 0);
+ PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE * maxspd_mod, 1, 0, 0, 0);
+#endif
}
void PM_ladder(float maxspd_mod)
wishspeed = min(wishspeed, PHYS_MAXSPEED(self) * maxspd_mod);
if (IS_DUCKED(self))
wishspeed *= 0.5;
+#ifdef SVQC
+ if (time >= self.teleport_time)
+ PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE * maxspd_mod, 1, 0, 0, 0);
+#endif
+
#ifdef CSQC
float addspeed = wishspeed - dotproduct(self.velocity, wishdir);
if (addspeed > 0)
if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
if (!IS_ONGROUND(self) || !(GAMEPLAYFIX_NOGRAVITYONGROUND))
self.velocity_z -= g * 0.5;
-#else
- if (time >= self.teleport_time)
- PM_Accelerate(wishdir, wishspeed, wishspeed, PHYS_ACCELERATE * maxspd_mod, 1, 0, 0, 0);
#endif
}
#endif
}
-// Copied from server/g_damage.qc, why is it even in there?
+// used for calculating airshots
float PM_is_flying()
{
- if (self.flags & FL_ONGROUND)
+ if (IS_ONGROUND(self))
return 0;
if (self.waterlevel >= WATERLEVEL_SWIMMING)
return 0;
self.stat_sv_airstrafeaccel_qw = 0;
self.stat_sv_airspeedlimit_nonqw = autocvar_sv_airspeedlimit_nonqw * maxspeed_mod;
self.stat_sv_maxspeed = autocvar_sv_maxspeed * maxspeed_mod; // also slow walking
- self.stat_movement_highspeed = autocvar_g_movement_highspeed;
+ self.stat_movement_highspeed = autocvar_g_movement_highspeed; // TODO: remove this!
self.stat_jetpack_antigravity = autocvar_g_jetpack_antigravity;
self.stat_jetpack_accel_up = autocvar_g_jetpack_acceleration_up;
#ifdef SVQC
if (IS_PLAYER(self))
- CheckPlayerJump();
#endif
+ CheckPlayerJump();
+
if (self.flags & /* FL_WATERJUMP */ 2048)
{