X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fmutator_dodging.qc;h=ab70fb217da5829ae99d1df98c8dd7c9e5dfb007;hb=fd8a3cfbe15df4e9854dbb288157fe863276a696;hp=625768f7cced279ce4f231804f0002df08056d6f;hpb=061ec0638ce3f35e60624332b3a3ae0e89c1a3d2;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/mutators/mutator_dodging.qc b/qcsrc/server/mutators/mutator_dodging.qc index 625768f7c..ab70fb217 100644 --- a/qcsrc/server/mutators/mutator_dodging.qc +++ b/qcsrc/server/mutators/mutator_dodging.qc @@ -1,10 +1,44 @@ +#ifdef CSQC + #define PHYS_DODGING_FRAMETIME (1 / (frametime <= 0 ? 60 : frametime)) + #define PHYS_DODGING getstati(STAT_DODGING) + #define PHYS_DODGING_DELAY getstatf(STAT_DODGING_DELAY) + #define PHYS_DODGING_TIMEOUT(s) getstatf(STAT_DODGING_TIMEOUT) + #define PHYS_DODGING_HORIZ_SPEED_FROZEN getstatf(STAT_DODGING_HORIZ_SPEED_FROZEN) + #define PHYS_DODGING_FROZEN_NODOUBLETAP getstati(STAT_DODGING_FROZEN_NO_DOUBLETAP) + #define PHYS_DODGING_HORIZ_SPEED getstatf(STAT_DODGING_HORIZ_SPEED) + #define PHYS_DODGING_PRESSED_KEYS(s) s.pressedkeys + #define PHYS_DODGING_HEIGHT_THRESHOLD getstatf(STAT_DODGING_HEIGHT_THRESHOLD) + #define PHYS_DODGING_DISTANCE_THRESHOLD getstatf(STAT_DODGING_DISTANCE_THRESHOLD) + #define PHYS_DODGING_RAMP_TIME getstatf(STAT_DODGING_RAMP_TIME) + #define PHYS_DODGING_UP_SPEED getstatf(STAT_DODGING_UP_SPEED) + #define PHYS_DODGING_WALL getstatf(STAT_DODGING_WALL) +#elif defined(SVQC) + #define PHYS_DODGING_FRAMETIME sys_frametime + #define PHYS_DODGING g_dodging + #define PHYS_DODGING_DELAY autocvar_sv_dodging_delay + #define PHYS_DODGING_TIMEOUT(s) s.cvar_cl_dodging_timeout + #define PHYS_DODGING_HORIZ_SPEED_FROZEN autocvar_sv_dodging_horiz_speed_frozen + #define PHYS_DODGING_FROZEN_NODOUBLETAP autocvar_sv_dodging_frozen_doubletap + #define PHYS_DODGING_HORIZ_SPEED autocvar_sv_dodging_horiz_speed + #define PHYS_DODGING_PRESSED_KEYS(s) s.pressedkeys + #define PHYS_DODGING_HEIGHT_THRESHOLD autocvar_sv_dodging_height_threshold + #define PHYS_DODGING_DISTANCE_THRESHOLD autocvar_sv_dodging_wall_distance_threshold + #define PHYS_DODGING_RAMP_TIME autocvar_sv_dodging_ramp_time + #define PHYS_DODGING_UP_SPEED autocvar_sv_dodging_up_speed + #define PHYS_DODGING_WALL autocvar_sv_dodging_wall_dodging +#endif #ifdef SVQC +#include "mutator_dodging.qh" +#include "../_all.qh" + +#include "mutator.qh" + +#include "../../common/animdecide.qh" .float cvar_cl_dodging_timeout; .float stat_dodging; -.float stat_dodging_timeout; .float stat_dodging_delay; .float stat_dodging_horiz_speed_frozen; .float stat_dodging_frozen_nodoubletap; @@ -32,8 +66,7 @@ .float last_RIGHT_KEY_time; // these store the movement direction at the time of the dodge action happening. -.float dodging_direction_x; -.float dodging_direction_y; +.vector dodging_direction; // this indicates the last time a dodge was executed. used to check if another one is allowed // and to ramp up the dodge acceleration in the physics hook. @@ -45,65 +78,14 @@ .float dodging_velocity_gain; #ifdef CSQC -.float pressedkeys; - -#define PHYS_INPUT_MOVEVALUES(s) input_movevalues -#define PHYS_INPUT_BUTTONS(s) input_buttons -#define PHYS_INPUT_ANGLES(s) input_angles - -#define UNSET_ONGROUND(s) s.pmove_flags &= ~PMF_ONGROUND -#define PHYS_FROZEN(s) getstati(STAT_FROZEN) -#define IS_ONGROUND(s) (s.pmove_flags & PMF_ONGROUND) - -#define PHYS_DEAD(s) s.csqcmodel_isdead - -#define PHYS_DODGING_FRAMETIME frametime -#define PHYS_DODGING getstati(STAT_DODGING) -#define PHYS_DODGING_DELAY getstatf(STAT_DODGING_DELAY) -#define PHYS_DODGING_TIMEOUT(s) getstatf(STAT_DODGING_TIMEOUT) -#define PHYS_DODGING_HORIZ_SPEED_FROZEN getstatf(STAT_DODGING_HORIZ_SPEED_FROZEN) -#define PHYS_DODGING_FROZEN getstati(STAT_DODGING_FROZEN) -#define PHYS_DODGING_FROZEN_NODOUBLETAP getstati(STAT_DODGING_FROZEN_NO_DOUBLETAP) -#define PHYS_DODGING_HORIZ_SPEED getstatf(STAT_DODGING_HORIZ_SPEED) -#define PHYS_DODGING_PRESSED_KEYS(s) s.pressedkeys -#define PHYS_DODGING_HEIGHT_THRESHOLD getstatf(STAT_DODGING_HEIGHT_THRESHOLD) -#define PHYS_DODGING_DISTANCE_THRESHOLD getstatf(STAT_DODGING_DISTANCE_THRESHOLD) -#define PHYS_DODGING_RAMP_TIME getstatf(STAT_DODGING_RAMP_TIME) -#define PHYS_DODGING_UP_SPEED getstatf(STAT_DODGING_UP_SPEED) -#define PHYS_DODGING_WALL getstatf(STAT_DODGING_WALL) +.int pressedkeys; #elif defined(SVQC) -#define PHYS_INPUT_ANGLES(s) s.angles -#define PHYS_INPUT_MOVEVALUES(s) s.movement -#define PHYS_INPUT_BUTTONS(s) (s.BUTTON_ATCK + 2 * s.BUTTON_JUMP + 4 * s.BUTTON_ATCK2 + 8 * s.BUTTON_ZOOM + 16 * s.BUTTON_CROUCH + 32 * s.BUTTON_HOOK + 64 * s.BUTTON_USE + 128 * (s.movement_x < 0) + 256 * (s.movement_x > 0) + 512 * (s.movement_y < 0) + 1024 * (s.movement_y > 0)) -#define UNSET_ONGROUND(s) s.flags &= ~FL_ONGROUND -#define PHYS_FROZEN(s) s.frozen -#define IS_ONGROUND(s) (s.flags & FL_ONGROUND) - -#define PHYS_DEAD(s) s.deadflag != DEAD_NO - -#define PHYS_DODGING_FRAMETIME sys_frametime -#define PHYS_DODGING g_dodging -#define PHYS_DODGING_DELAY autocvar_sv_dodging_delay -#define PHYS_DODGING_TIMEOUT(s) s.cvar_cl_dodging_timeout -#define PHYS_DODGING_HORIZ_SPEED_FROZEN autocvar_sv_dodging_horiz_speed_frozen -#define PHYS_DODGING_FROZEN autocvar_sv_dodging_frozen -#define PHYS_DODGING_FROZEN_NODOUBLETAP autocvar_sv_dodging_frozen_doubletap -#define PHYS_DODGING_HORIZ_SPEED autocvar_sv_dodging_horiz_speed -#define PHYS_DODGING_PRESSED_KEYS(s) s.pressedkeys -#define PHYS_DODGING_HEIGHT_THRESHOLD autocvar_sv_dodging_height_threshold -#define PHYS_DODGING_DISTANCE_THRESHOLD autocvar_sv_dodging_wall_distance_threshold -#define PHYS_DODGING_RAMP_TIME autocvar_sv_dodging_ramp_time -#define PHYS_DODGING_UP_SPEED autocvar_sv_dodging_up_speed -#define PHYS_DODGING_WALL autocvar_sv_dodging_wall_dodging - - void dodging_UpdateStats() { self.stat_dodging = PHYS_DODGING; self.stat_dodging_delay = PHYS_DODGING_DELAY; - self.stat_dodging_timeout = PHYS_DODGING_TIMEOUT(self); self.stat_dodging_horiz_speed_frozen = PHYS_DODGING_HORIZ_SPEED_FROZEN; self.stat_dodging_frozen = PHYS_DODGING_FROZEN; self.stat_dodging_frozen_nodoubletap = PHYS_DODGING_FROZEN_NODOUBLETAP; @@ -130,186 +112,67 @@ void dodging_Initialize() addstat(STAT_DODGING_WALL, AS_FLOAT, stat_dodging_wall); } -#endif -#ifdef CSQC -// instantly updates pressed keys, for use with dodging (may be out of date, but we can't care) -void PM_dodging_updatepressedkeys() -{ - if (PHYS_INPUT_MOVEVALUES(self)_x > 0) // get if movement keys are pressed - { // forward key pressed - self.pressedkeys |= KEY_FORWARD; - self.pressedkeys &= ~KEY_BACKWARD; - } - else if (PHYS_INPUT_MOVEVALUES(self)_x < 0) - { // backward key pressed - self.pressedkeys |= KEY_BACKWARD; - self.pressedkeys &= ~KEY_FORWARD; - } - else - { // no x input - self.pressedkeys &= ~KEY_FORWARD; - self.pressedkeys &= ~KEY_BACKWARD; - } - - if (PHYS_INPUT_MOVEVALUES(self)_y > 0) - { // right key pressed - self.pressedkeys |= KEY_RIGHT; - self.pressedkeys &= ~KEY_LEFT; - } - else if (PHYS_INPUT_MOVEVALUES(self)_y < 0) - { // left key pressed - self.pressedkeys |= KEY_LEFT; - self.pressedkeys &= ~KEY_RIGHT; - } - else - { // no y input - self.pressedkeys &= ~KEY_RIGHT; - self.pressedkeys &= ~KEY_LEFT; - } - - if (PHYS_INPUT_BUTTONS(self) & 2) // get if jump and crouch keys are pressed - self.pressedkeys |= KEY_JUMP; - else - self.pressedkeys &= ~KEY_JUMP; - if (PHYS_INPUT_BUTTONS(self) & 16) - self.pressedkeys |= KEY_CROUCH; - else - self.pressedkeys &= ~KEY_CROUCH; - - if (PHYS_INPUT_BUTTONS(self) & 1) - self.pressedkeys |= KEY_ATCK; - else - self.pressedkeys &= ~KEY_ATCK; - if (PHYS_INPUT_BUTTONS(self) & 4) - self.pressedkeys |= KEY_ATCK2; - else - self.pressedkeys &= ~KEY_ATCK2; -} #endif // returns 1 if the player is close to a wall -float check_close_to_wall(float threshold) +bool check_close_to_wall(float threshold) { - if (PHYS_DODGING_WALL == 0) { return 0; } - - vector trace_start; - vector trace_end; - - trace_start = self.origin; - - trace_end = self.origin + (1000*v_right); - tracebox(trace_start, self.mins, self.maxs, trace_end, TRUE, self); - if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold) - return 1; - - trace_end = self.origin - (1000*v_right); - tracebox(trace_start, self.mins, self.maxs, trace_end, TRUE, self); - if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold) - return 1; - - trace_end = self.origin + (1000*v_forward); - tracebox(trace_start, self.mins, self.maxs, trace_end, TRUE, self); - if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold) - return 1; - - trace_end = self.origin - (1000*v_forward); - tracebox(trace_start, self.mins, self.maxs, trace_end, TRUE, self); - if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold) - return 1; - - return 0; + 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; } -float check_close_to_ground(float threshold) +bool check_close_to_ground(float threshold) { - if (IS_ONGROUND(self)) - return 1; - - return 0; + return IS_ONGROUND(self) ? true : false; } -void PM_dodging_checkpressedkeys() +float PM_dodging_checkpressedkeys() { - if(!PHYS_DODGING) { return; } - - float length; - float tap_direction_x; - float tap_direction_y; + if(!PHYS_DODGING) + return false; - tap_direction_x = 0; - tap_direction_y = 0; - - float frozen_dodging, frozen_no_doubletap; - frozen_dodging = (PHYS_FROZEN(self) && PHYS_DODGING_FROZEN); - frozen_no_doubletap = (frozen_dodging && !PHYS_DODGING_FROZEN_NODOUBLETAP); - - float dodge_detected = 0; + 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; + return false; - makevectors(PHYS_INPUT_ANGLES(self)); + makevectors(self.angles); if (check_close_to_ground(PHYS_DODGING_HEIGHT_THRESHOLD) != 1 && check_close_to_wall(PHYS_DODGING_DISTANCE_THRESHOLD) != 1) - return; - - if (PHYS_INPUT_MOVEVALUES(self)_x > 0) - { - // is this a state change? - if (!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_FORWARD) || frozen_no_doubletap) - { - if ((time - self.last_FORWARD_KEY_time) < PHYS_DODGING_TIMEOUT(self)) - { - tap_direction_x = 1.0; - dodge_detected = 1; - } - self.last_FORWARD_KEY_time = time; - } - } - - if (PHYS_INPUT_MOVEVALUES(self)_x < 0) - { - // is this a state change? - if (!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_BACKWARD) || frozen_no_doubletap) - { - tap_direction_x = -1.0; - if ((time - self.last_BACKWARD_KEY_time) < PHYS_DODGING_TIMEOUT(self)) - { - dodge_detected = 1; - } - self.last_BACKWARD_KEY_time = time; - } - } + return true; - if (PHYS_INPUT_MOVEVALUES(self)_y > 0) - { - // is this a state change? - if (!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_RIGHT) || frozen_no_doubletap) - { - tap_direction_y = 1.0; - if ((time - self.last_RIGHT_KEY_time) < PHYS_DODGING_TIMEOUT(self)) - { - dodge_detected = 1; - } - self.last_RIGHT_KEY_time = time; - } - } + float tap_direction_x = 0; + float tap_direction_y = 0; + float dodge_detected = 0; - if (PHYS_INPUT_MOVEVALUES(self)_y < 0) - { - // is this a state change? - if (!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_LEFT) || frozen_no_doubletap) - { - tap_direction_y = -1.0; - if ((time - self.last_LEFT_KEY_time) < PHYS_DODGING_TIMEOUT(self)) - { - dodge_detected = 1; - } - self.last_LEFT_KEY_time = time; - } - } + #define X(COND,BTN,RESULT) \ + if (self.movement_##COND) \ + /* is this a state change? */ \ + if(!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_##BTN) || frozen_no_doubletap) { \ + tap_direction_##RESULT; \ + if ((time - self.last_##BTN##_KEY_time) < PHYS_DODGING_TIMEOUT(self)) \ + dodge_detected = 1; \ + self.last_##BTN##_KEY_time = time; \ + } + X(x < 0, BACKWARD, x--); + X(x > 0, FORWARD, x++); + X(y < 0, LEFT, y--); + X(y > 0, RIGHT, y++); + #undef X if (dodge_detected == 1) { @@ -324,47 +187,31 @@ void PM_dodging_checkpressedkeys() self.dodging_direction_y = tap_direction_y; // normalize the dodging_direction vector.. (unlike UT99) XD - length = self.dodging_direction_x * self.dodging_direction_x; - length = length + self.dodging_direction_y * self.dodging_direction_y; + float length = self.dodging_direction_x * self.dodging_direction_x + + self.dodging_direction_y * self.dodging_direction_y; length = sqrt(length); - self.dodging_direction_x = self.dodging_direction_x * 1.0/length; - self.dodging_direction_y = self.dodging_direction_y * 1.0/length; + self.dodging_direction_x = self.dodging_direction_x * 1.0 / length; + self.dodging_direction_y = self.dodging_direction_y * 1.0 / length; + return true; } - -#ifdef CSQC - PM_dodging_updatepressedkeys(); -#endif + return false; } 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; + if (!PHYS_DODGING) + return; #ifdef SVQC dodging_UpdateStats(); #endif - if(PHYS_FROZEN(self)) - horiz_speed = PHYS_DODGING_HORIZ_SPEED_FROZEN; - - if(PHYS_DEAD(self)) + if (PHYS_DEAD(self)) return; - 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; @@ -373,37 +220,30 @@ void PM_dodging() } // make sure v_up, v_right and v_forward are sane - makevectors(PHYS_INPUT_ANGLES(self)); + makevectors(self.angles); // 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; + float 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; + common_factor = min(common_factor, 1); - new_velocity_gain = self.dodging_velocity_gain - (common_factor * horiz_speed); - if (new_velocity_gain < 0) - new_velocity_gain = 0; + float horiz_speed = PHYS_FROZEN(self) ? PHYS_DODGING_HORIZ_SPEED_FROZEN : PHYS_DODGING_HORIZ_SPEED; + float new_velocity_gain = self.dodging_velocity_gain - (common_factor * horiz_speed); + new_velocity_gain = max(0, new_velocity_gain); - velocity_difference = self.dodging_velocity_gain - new_velocity_gain; + float 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; -#endif + if(self.movement_z > 0) { self.movement_z = 0; } - self.velocity = - self.velocity - + ((self.dodging_direction_y * velocity_difference) * v_right) - + ((self.dodging_direction_x * velocity_difference) * v_forward); + 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; } @@ -413,15 +253,13 @@ void PM_dodging() { UNSET_ONGROUND(self); - self.velocity = - self.velocity - + (PHYS_DODGING_UP_SPEED * v_up); + self.velocity += PHYS_DODGING_UP_SPEED * v_up; #ifdef SVQC - if (autocvar_sv_dodging_sound == 1) + if (autocvar_sv_dodging_sound) PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND); - animdecide_setaction(self, ANIMACTION_JUMP, TRUE); + animdecide_setaction(self, ANIMACTION_JUMP, true); #endif self.dodging_single_action = 0; @@ -435,10 +273,6 @@ void PM_dodging() self.dodging_direction_x = 0; self.dodging_direction_y = 0; } - -#ifdef CSQC - PM_dodging_checkpressedkeys(); -#endif } #ifdef SVQC @@ -446,7 +280,7 @@ void PM_dodging() MUTATOR_HOOKFUNCTION(dodging_GetCvars) { GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout"); - return 0; + return false; } MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) @@ -454,14 +288,14 @@ MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) // print("dodging_PlayerPhysics\n"); PM_dodging(); - return 0; + return false; } MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) { PM_dodging_checkpressedkeys(); - return 0; + return false; } MUTATOR_DEFINITION(mutator_dodging) @@ -489,19 +323,6 @@ MUTATOR_DEFINITION(mutator_dodging) g_dodging = 0; } - MUTATOR_ONREMOVE - { - } - - return 0; + return false; } #endif - -// we use this elsewhere, but let's undefine it anyway -#undef PHYS_DODGING_FROZEN -#undef PHYS_INPUT_MOVEVALUES -#undef PHYS_INPUT_ANGLES -#undef PHYS_INPUT_BUTTONS -#undef UNSET_ONGROUND -#undef PHYS_FROZEN -#undef IS_ONGROUND