+}
+
+void PM_dodging()
+{
+ if(!PHYS_DODGING) { return; }
+
+ float common_factor;
+ float new_velocity_gain;
+ float velocity_difference;
+ float clean_up_and_do_nothing;
+ float horiz_speed = PHYS_DODGING_HORIZ_SPEED;
+
+#ifdef SVQC
+ dodging_UpdateStats();
+#endif
+
+ if(PHYS_FROZEN(self))
+ horiz_speed = PHYS_DODGING_HORIZ_SPEED_FROZEN;
+
+#ifdef SVQC
+ if (self.deadflag != DEAD_NO)
+ return;
+#endif
+
+ new_velocity_gain = 0;
+ clean_up_and_do_nothing = 0;
+
+ // when swimming, no dodging allowed..
+ if (self.waterlevel >= WATERLEVEL_SWIMMING)
+ clean_up_and_do_nothing = 1;
+
+ if (clean_up_and_do_nothing != 0)
+ {
+ self.dodging_action = 0;
+ self.dodging_direction_x = 0;
+ self.dodging_direction_y = 0;
+ return;
+ }
+
+ // make sure v_up, v_right and v_forward are sane
+ makevectors(PHYS_INPUT_ANGLES(self));
+
+ // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
+ // will be called ramp_time/frametime times = 2 times. so, we need to
+ // add 0.5 * the total speed each frame until the dodge action is done..
+ common_factor = PHYS_DODGING_FRAMETIME / PHYS_DODGING_RAMP_TIME;
+
+ // if ramp time is smaller than frametime we get problems ;D
+ if (common_factor > 1)
+ common_factor = 1;
+
+ new_velocity_gain = self.dodging_velocity_gain - (common_factor * horiz_speed);
+ if (new_velocity_gain < 0)
+ new_velocity_gain = 0;
+
+ velocity_difference = self.dodging_velocity_gain - new_velocity_gain;
+
+ // ramp up dodging speed by adding some velocity each frame.. TODO: do it! :D
+ if (self.dodging_action == 1)
+ {
+ //disable jump key during dodge accel phase
+#ifdef SVQC
+ if(self.movement_z > 0) self.movement_z = 0;
+#elif defined(CSQC)
+ if(input_movevalues_z > 0) input_movevalues_z = 0;
+ print("DODGE!\n");
+#endif
+
+ self.velocity =
+ self.velocity
+ + ((self.dodging_direction_y * velocity_difference) * v_right)
+ + ((self.dodging_direction_x * velocity_difference) * v_forward);
+
+ self.dodging_velocity_gain = self.dodging_velocity_gain - velocity_difference;
+ }
+
+ // the up part of the dodge is a single shot action
+ if (self.dodging_single_action == 1)
+ {
+ UNSET_ONGROUND(self);
+
+ self.velocity =
+ self.velocity
+ + (PHYS_DODGING_UP_SPEED * v_up);
+
+#ifdef SVQC
+ if (autocvar_sv_dodging_sound == 1)
+ PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+
+ animdecide_setaction(self, ANIMACTION_JUMP, TRUE);
+#endif
+
+ self.dodging_single_action = 0;
+ }
+
+ // are we done with the dodging ramp yet?
+ if((self.dodging_action == 1) && ((time - self.last_dodging_time) > PHYS_DODGING_RAMP_TIME))
+ {
+ // reset state so next dodge can be done correctly
+ self.dodging_action = 0;
+ self.dodging_direction_x = 0;
+ self.dodging_direction_y = 0;
+ }
+}
+
+#ifdef SVQC
+
+MUTATOR_HOOKFUNCTION(dodging_GetCvars)
+{
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
+ return 0;
+}
+
+MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics)
+{
+ // print("dodging_PlayerPhysics\n");
+ PM_dodging();
+
+ return 0;
+}
+
+MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys)
+{
+ PM_dodging_checkpressedkeys();