+void dodging_Initialize()
+{
+ addstat(STAT_DODGING, AS_INT, stat_dodging);
+ addstat(STAT_DODGING_DELAY, AS_FLOAT, stat_dodging_delay);
+ addstat(STAT_DODGING_TIMEOUT, AS_FLOAT, cvar_cl_dodging_timeout); // we stat this, so it is updated on the client when updated on server (otherwise, chaos)
+ addstat(STAT_DODGING_FROZEN_NO_DOUBLETAP, AS_INT, stat_dodging_frozen_nodoubletap);
+ addstat(STAT_DODGING_HORIZ_SPEED_FROZEN, AS_FLOAT, stat_dodging_horiz_speed_frozen);
+ addstat(STAT_DODGING_FROZEN, AS_INT, stat_dodging_frozen);
+ addstat(STAT_DODGING_HORIZ_SPEED, AS_FLOAT, stat_dodging_horiz_speed);
+ addstat(STAT_DODGING_HEIGHT_THRESHOLD, AS_FLOAT, stat_dodging_height_threshold);
+ addstat(STAT_DODGING_DISTANCE_THRESHOLD, AS_FLOAT, stat_dodging_distance_threshold);
+ addstat(STAT_DODGING_RAMP_TIME, AS_FLOAT, stat_dodging_ramp_time);
+ addstat(STAT_DODGING_UP_SPEED, AS_FLOAT, stat_dodging_up_speed);
+ addstat(STAT_DODGING_WALL, AS_FLOAT, stat_dodging_wall);
+}
+
+#endif
+
+// returns 1 if the player is close to a wall
+bool check_close_to_wall(float threshold)
+{
+ if (PHYS_DODGING_WALL == 0) { return false; }
+
+ #define X(OFFSET) \
+ tracebox(self.origin, self.mins, self.maxs, self.origin + OFFSET, true, self); \
+ if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold) \
+ return true;
+ X(1000*v_right);
+ X(-1000*v_right);
+ X(1000*v_forward);
+ X(-1000*v_forward);
+ #undef X
+
+ return false;
+}
+
+bool check_close_to_ground(float threshold)
+{
+ return IS_ONGROUND(self) ? true : false;
+}
+
+float PM_dodging_checkpressedkeys()
+{
+ if(!PHYS_DODGING)
+ return false;
+
+ float frozen_dodging = (PHYS_FROZEN(self) && PHYS_DODGING_FROZEN);
+ float frozen_no_doubletap = (frozen_dodging && !PHYS_DODGING_FROZEN_NODOUBLETAP);
+
+ // first check if the last dodge is far enough back in time so we can dodge again
+ if ((time - self.last_dodging_time) < PHYS_DODGING_DELAY)
+ return false;
+
+ makevectors(self.angles);