X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmutators%2Fmutator_dodging.qc;h=ab70fb217da5829ae99d1df98c8dd7c9e5dfb007;hb=125d619e9ab2a307b15b7ee1a2ededed32c7e84d;hp=45deeab04cff809f580095ff21b40206e4fe6661;hpb=38eec7494f916036a8d0774228064e7efd10e3cd;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/mutators/mutator_dodging.qc b/qcsrc/server/mutators/mutator_dodging.qc index 45deeab04..ab70fb217 100644 --- a/qcsrc/server/mutators/mutator_dodging.qc +++ b/qcsrc/server/mutators/mutator_dodging.qc @@ -1,9 +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; @@ -31,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. @@ -44,7 +78,7 @@ .float dodging_velocity_gain; #ifdef CSQC -.float pressedkeys; +.int pressedkeys; #elif defined(SVQC) @@ -52,7 +86,6 @@ 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; @@ -79,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 FALSE; } - - 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 TRUE; - - 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 TRUE; - - 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 TRUE; - - 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 TRUE; - - return FALSE; + 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 TRUE; - - return FALSE; + 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; - - tap_direction_x = 0; - tap_direction_y = 0; + if(!PHYS_DODGING) + return false; - 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_WORLD_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; - } - } + return true; - 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; - } - } + 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_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; - } - } - - 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) { @@ -273,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; @@ -322,33 +220,30 @@ void PM_dodging() } // make sure v_up, v_right and v_forward are sane - makevectors(PHYS_WORLD_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 - if(PHYS_INPUT_MOVEVALUES(self)_z > 0) { PHYS_INPUT_MOVEVALUES(self)_z = 0; } + 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; } @@ -358,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; @@ -380,10 +273,6 @@ void PM_dodging() self.dodging_direction_x = 0; self.dodging_direction_y = 0; } - -#ifdef CSQC - PM_dodging_checkpressedkeys(); -#endif } #ifdef SVQC @@ -391,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 FALSE; + return false; } MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) @@ -399,14 +288,14 @@ MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) // print("dodging_PlayerPhysics\n"); PM_dodging(); - return FALSE; + return false; } MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) { PM_dodging_checkpressedkeys(); - return FALSE; + return false; } MUTATOR_DEFINITION(mutator_dodging) @@ -434,6 +323,6 @@ MUTATOR_DEFINITION(mutator_dodging) g_dodging = 0; } - return FALSE; + return false; } #endif