X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fphysics.qc;h=60ca3b101a7c7c7c09b6f303786875d8137f340f;hp=84b327c2284490bd4fc97f485d9654eb18e399b2;hb=777dc5e23d7512c3e33576884d8d200f244d3006;hpb=464305bd2132971e2d24a19989baa94789ad9e68 diff --git a/qcsrc/common/physics.qc b/qcsrc/common/physics.qc index 84b327c228..60ca3b101a 100644 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@ -6,6 +6,36 @@ #include "../server/miscfunctions.qh" +// client side physics +bool Physics_Valid(string thecvar) +{ + if(!autocvar_g_physics_clientselect) { return false; } + + string l = strcat(" ", autocvar_g_physics_clientselect_options, " "); + + if(strstrofs(l, strcat(" ", thecvar, " "), 0) >= 0) + return true; + + return false; +} + +float Physics_ClientOption(entity pl, string option) +{ + if(Physics_Valid(pl.cvar_cl_physics)) + { + string var = sprintf("g_physics_%s_%s", pl.cvar_cl_physics, option); + if(cvar_type(var) & CVAR_TYPEFLAG_EXISTS) + return cvar(var); + } + if(autocvar_g_physics_clientselect && autocvar_g_physics_clientselect_default) + { + string var = sprintf("g_physics_%s_%s", autocvar_g_physics_clientselect_default, option); + if(cvar_type(var) & CVAR_TYPEFLAG_EXISTS) + return cvar(var); + } + return cvar(strcat("sv_", option)); +} + void Physics_AddStats() { // static view offset and hitbox vectors @@ -61,6 +91,27 @@ void Physics_AddStats() addstat(STAT_MOVEVARS_FRICTION_SLICK, AS_FLOAT, stat_sv_friction_slick); addstat(STAT_GAMEPLAYFIX_EASIERWATERJUMP, AS_INT, stat_gameplayfix_easierwaterjump); + // new properties + addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_sv_jumpvelocity); + addstat(STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, AS_FLOAT, stat_sv_airaccel_qw_stretchfactor); + addstat(STAT_MOVEVARS_MAXAIRSTRAFESPEED, AS_FLOAT, stat_sv_maxairstrafespeed); + addstat(STAT_MOVEVARS_MAXAIRSPEED, AS_FLOAT, stat_sv_maxairspeed); + addstat(STAT_MOVEVARS_AIRSTRAFEACCELERATE, AS_FLOAT, stat_sv_airstrafeaccelerate); + addstat(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL, AS_FLOAT, stat_sv_warsowbunny_turnaccel); + addstat(STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, AS_FLOAT, stat_sv_airaccel_sideways_friction); + addstat(STAT_MOVEVARS_AIRCONTROL, AS_FLOAT, stat_sv_aircontrol); + addstat(STAT_MOVEVARS_AIRCONTROL_POWER, AS_FLOAT, stat_sv_aircontrol_power); + addstat(STAT_MOVEVARS_AIRCONTROL_PENALTY, AS_FLOAT, stat_sv_aircontrol_penalty); + addstat(STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, AS_FLOAT, stat_sv_warsowbunny_airforwardaccel); + addstat(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED, AS_FLOAT, stat_sv_warsowbunny_topspeed); + addstat(STAT_MOVEVARS_WARSOWBUNNY_ACCEL, AS_FLOAT, stat_sv_warsowbunny_accel); + addstat(STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, AS_FLOAT, stat_sv_warsowbunny_backtosideratio); + addstat(STAT_MOVEVARS_FRICTION, AS_FLOAT, stat_sv_friction); + addstat(STAT_MOVEVARS_ACCELERATE, AS_FLOAT, stat_sv_accelerate); + addstat(STAT_MOVEVARS_STOPSPEED, AS_FLOAT, stat_sv_stopspeed); + addstat(STAT_MOVEVARS_AIRACCELERATE, AS_FLOAT, stat_sv_airaccelerate); + addstat(STAT_MOVEVARS_AIRSTOPACCELERATE, AS_FLOAT, stat_sv_airstopaccelerate); + addstat(STAT_GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, AS_INT, stat_gameplayfix_upvelocityclearsonground); } @@ -75,13 +126,14 @@ void Physics_UpdateStats(float maxspd_mod) self.stat_pl_crouch_min = PL_CROUCH_MIN; self.stat_pl_crouch_max = PL_CROUCH_MAX; - self.stat_sv_airaccel_qw = AdjustAirAccelQW(autocvar_sv_airaccel_qw, maxspd_mod); - if (autocvar_sv_airstrafeaccel_qw) - self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(autocvar_sv_airstrafeaccel_qw, maxspd_mod); + + self.stat_sv_airaccel_qw = AdjustAirAccelQW(Physics_ClientOption(self, "airaccel_qw"), maxspd_mod); + if(Physics_ClientOption(self, "airstrafeaccel_qw")) + self.stat_sv_airstrafeaccel_qw = AdjustAirAccelQW(Physics_ClientOption(self, "airstrafeaccel_qw"), maxspd_mod); else self.stat_sv_airstrafeaccel_qw = 0; - self.stat_sv_airspeedlimit_nonqw = autocvar_sv_airspeedlimit_nonqw * maxspd_mod; - self.stat_sv_maxspeed = autocvar_sv_maxspeed * maxspd_mod; // also slow walking + self.stat_sv_airspeedlimit_nonqw = Physics_ClientOption(self, "airspeedlimit_nonqw") * maxspd_mod; + self.stat_sv_maxspeed = Physics_ClientOption(self, "maxspeed") * maxspd_mod; // also slow walking self.stat_movement_highspeed = PHYS_HIGHSPEED; // TODO: remove this! self.stat_doublejump = PHYS_DOUBLEJUMP; @@ -102,6 +154,29 @@ void Physics_UpdateStats(float maxspd_mod) self.stat_gameplayfix_easierwaterjump = GAMEPLAYFIX_EASIERWATERJUMP; + + // old stats + // fix some new settings + self.stat_sv_airaccel_qw_stretchfactor = Physics_ClientOption(self, "airaccel_qw_stretchfactor"); + self.stat_sv_maxairstrafespeed = Physics_ClientOption(self, "maxairstrafespeed"); + self.stat_sv_maxairspeed = Physics_ClientOption(self, "maxairspeed"); + self.stat_sv_airstrafeaccelerate = Physics_ClientOption(self, "airstrafeaccelerate"); + self.stat_sv_warsowbunny_turnaccel = Physics_ClientOption(self, "warsowbunny_turnaccel"); + self.stat_sv_airaccel_sideways_friction = Physics_ClientOption(self, "airaccel_sideways_friction"); + self.stat_sv_aircontrol = Physics_ClientOption(self, "aircontrol"); + self.stat_sv_aircontrol_power = Physics_ClientOption(self, "aircontrol_power"); + self.stat_sv_aircontrol_penalty = Physics_ClientOption(self, "aircontrol_penalty"); + self.stat_sv_warsowbunny_airforwardaccel = Physics_ClientOption(self, "warsowbunny_airforwardaccel"); + self.stat_sv_warsowbunny_topspeed = Physics_ClientOption(self, "warsowbunny_topspeed"); + self.stat_sv_warsowbunny_accel = Physics_ClientOption(self, "warsowbunny_accel"); + self.stat_sv_warsowbunny_backtosideratio = Physics_ClientOption(self, "warsowbunny_backtosideratio"); + self.stat_sv_friction = Physics_ClientOption(self, "friction"); + self.stat_sv_accelerate = Physics_ClientOption(self, "accelerate"); + self.stat_sv_stopspeed = Physics_ClientOption(self, "stopspeed"); + self.stat_sv_airaccelerate = Physics_ClientOption(self, "airaccelerate"); + self.stat_sv_airstopaccelerate = Physics_ClientOption(self, "airstopaccelerate"); + self.stat_sv_jumpvelocity = Physics_ClientOption(self, "jumpvelocity"); + self.stat_gameplayfix_upvelocityclearsonground = UPWARD_VELOCITY_CLEARS_ONGROUND; } #endif @@ -329,7 +404,7 @@ void CPM_PM_Aircontrol(vector wishdir, float wishspeed) if (k <= 0) return; - k *= bound(0, wishspeed / PHYS_MAXAIRSPEED, 1); + k *= bound(0, wishspeed / PHYS_MAXAIRSPEED(self), 1); float zspeed = self.velocity_z; self.velocity_z = 0; @@ -467,7 +542,7 @@ When you press the jump key returns true if handled ============= */ -float PlayerJump (void) +bool PlayerJump (void) { if (PHYS_FROZEN(self)) return true; // no jumping in freezetag when frozen @@ -477,7 +552,7 @@ float PlayerJump (void) return true; // no jumping while blocked #endif - float doublejump = false; + bool doublejump = false; float mjumpheight = PHYS_JUMPVELOCITY; player_multijump = doublejump; @@ -603,7 +678,11 @@ void CheckWaterJump() self.velocity_z = 225; self.flags |= FL_WATERJUMP; SET_JUMP_HELD(self); +#ifdef SVQC self.teleport_time = time + 2; // safety net +#elif defined(CSQC) + pmove_waterjumptime = time + 2; +#endif } } } @@ -621,18 +700,18 @@ void CheckWaterJump() void CheckPlayerJump() { #ifdef SVQC - float was_flying = ITEMS(self) & IT_USING_JETPACK; + float was_flying = ITEMS_STAT(self) & IT_USING_JETPACK; #endif if (JETPACK_JUMP(self) < 2) - ITEMS(self) &= ~IT_USING_JETPACK; + ITEMS_STAT(self) &= ~IT_USING_JETPACK; if(PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_JETPACK(self)) { float air_jump = !PlayerJump() || self.multijump_count > 0; // PlayerJump() has important side effects float activate = JETPACK_JUMP(self) && air_jump && PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_JETPACK(self); - float has_fuel = !PHYS_JETPACK_FUEL || PHYS_AMMO_FUEL(self) || ITEMS(self) & IT_UNLIMITED_WEAPON_AMMO; + float has_fuel = !PHYS_JETPACK_FUEL || PHYS_AMMO_FUEL(self) || ITEMS_STAT(self) & IT_UNLIMITED_WEAPON_AMMO; - if (!(ITEMS(self) & IT_JETPACK)) { } + if (!(ITEMS_STAT(self) & IT_JETPACK)) { } else if (self.jetpack_stopped) { } else if (!has_fuel) { @@ -643,15 +722,15 @@ void CheckPlayerJump() Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_JETPACK_NOFUEL); #endif self.jetpack_stopped = true; - ITEMS(self) &= ~IT_USING_JETPACK; + ITEMS_STAT(self) &= ~IT_USING_JETPACK; } else if (activate && !PHYS_FROZEN(self)) - ITEMS(self) |= IT_USING_JETPACK; + ITEMS_STAT(self) |= IT_USING_JETPACK; } else { self.jetpack_stopped = false; - ITEMS(self) &= ~IT_USING_JETPACK; + ITEMS_STAT(self) &= ~IT_USING_JETPACK; } if (!PHYS_INPUT_BUTTON_JUMP(self)) UNSET_JUMP_HELD(self); @@ -1006,7 +1085,9 @@ void PM_check_spider(void) if (time >= self.spider_slowness) return; PHYS_MAXSPEED(self) *= 0.5; // half speed while slow from spider - self.stat_sv_airspeedlimit_nonqw *= 0.5; + PHYS_MAXAIRSPEED(self) *= 0.5; + PHYS_AIRSPEEDLIMIT_NONQW(self) *= 0.5; + PHYS_AIRSTRAFEACCELERATE(self) *= 0.5; #endif } @@ -1289,7 +1370,7 @@ void PM_jetpack(float maxspd_mod) vector wishvel = v_forward * self.movement_x + v_right * self.movement_y; // add remaining speed as Z component - float maxairspd = PHYS_MAXAIRSPEED * max(1, maxspd_mod); + float maxairspd = PHYS_MAXAIRSPEED(self) * max(1, maxspd_mod); // fix speedhacks :P wishvel = normalize(wishvel) * min(1, vlen(wishvel) / maxairspd); // add the unused velocity as up component @@ -1362,7 +1443,7 @@ void PM_jetpack(float maxspd_mod) wishvel_z = (wishvel_z - PHYS_GRAVITY) * fz + PHYS_GRAVITY; fvel = min(1, vlen(wishvel) / best); - if (PHYS_JETPACK_FUEL && !(ITEMS(self) & IT_UNLIMITED_WEAPON_AMMO)) + if (PHYS_JETPACK_FUEL && !(ITEMS_STAT(self) & IT_UNLIMITED_WEAPON_AMMO)) f = min(1, PHYS_AMMO_FUEL(self) / (PHYS_JETPACK_FUEL * PHYS_INPUT_TIMELENGTH * fvel)); else f = 1; @@ -1375,10 +1456,10 @@ void PM_jetpack(float maxspd_mod) UNSET_ONGROUND(self); #ifdef SVQC - if (!(ITEMS(self) & IT_UNLIMITED_WEAPON_AMMO)) + if (!(ITEMS_STAT(self) & IT_UNLIMITED_WEAPON_AMMO)) self.ammo_fuel -= PHYS_JETPACK_FUEL * PHYS_INPUT_TIMELENGTH * fvel * f; - ITEMS(self) |= IT_USING_JETPACK; + ITEMS_STAT(self) |= IT_USING_JETPACK; // jetpack also inhibits health regeneration, but only for 1 second self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen); @@ -1498,7 +1579,7 @@ void PM_air(float buttons_prev, float maxspd_mod) if (pmove_waterjumptime <= 0) #endif { - float maxairspd = PHYS_MAXAIRSPEED * min(maxspd_mod, 1); + float maxairspd = PHYS_MAXAIRSPEED(self) * min(maxspd_mod, 1); // apply air speed limit float airaccelqw = PHYS_AIRACCEL_QW(self); @@ -1527,9 +1608,9 @@ void PM_air(float buttons_prev, float maxspd_mod) // log dv/dt = logaccel + logmaxspeed + log(1 - accelqw) (when fast) float strafity = IsMoveInDirection(self.movement, -90) + IsMoveInDirection(self.movement, +90); // if one is nonzero, other is always zero if (PHYS_MAXAIRSTRAFESPEED) - wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod)); - if (PHYS_AIRSTRAFEACCELERATE) - airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE*maxspd_mod); + wishspeed = min(wishspeed, GeomLerp(PHYS_MAXAIRSPEED(self)*maxspd_mod, strafity, PHYS_MAXAIRSTRAFESPEED*maxspd_mod)); + if (PHYS_AIRSTRAFEACCELERATE(self)) + airaccel = GeomLerp(airaccel, strafity, PHYS_AIRSTRAFEACCELERATE(self)*maxspd_mod); if (PHYS_AIRSTRAFEACCEL_QW(self)) airaccelqw = (((strafity > 0.5 ? PHYS_AIRSTRAFEACCEL_QW(self) : PHYS_AIRACCEL_QW(self)) >= 0) ? +1 : -1) @@ -1571,12 +1652,14 @@ bool IsFlying(entity a) void PM_Main() { - float buttons = PHYS_INPUT_BUTTON_MASK(self); + int buttons = PHYS_INPUT_BUTTON_MASK(self); #ifdef CSQC self.items = getstati(STAT_ITEMS, 0, 24); self.movement = PHYS_INPUT_MOVEVALUES(self); + vector oldv_angle = self.v_angle; + vector oldangles = self.angles; // we need to save these, as they're abused by other code self.v_angle = PHYS_INPUT_ANGLES(self); self.angles = PHYS_WORLD_ANGLES(self); @@ -1618,7 +1701,7 @@ void PM_Main() self.parm_idlesince = time; } #endif - float buttons_prev = self.buttons_old; + int buttons_prev = self.buttons_old; self.buttons_old = buttons; self.movement_old = self.movement; self.v_angle_old = self.v_angle; @@ -1643,14 +1726,14 @@ void PM_Main() self.race_penalty = 0; #endif - float not_allowed_to_move = 0; + bool not_allowed_to_move = false; #ifdef SVQC if (self.race_penalty) - not_allowed_to_move = 1; + not_allowed_to_move = true; #endif #ifdef SVQC if (time < game_starttime) - not_allowed_to_move = 1; + not_allowed_to_move = true; #endif if (not_allowed_to_move) @@ -1735,7 +1818,7 @@ void PM_Main() maxspeed_mod = self.spectatorspeed; } - float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED) * maxspeed_mod; + float spd = max(PHYS_MAXSPEED(self), PHYS_MAXAIRSPEED(self)) * maxspeed_mod; if(self.speed != spd) { self.speed = spd; @@ -1748,7 +1831,19 @@ void PM_Main() #endif if(PHYS_DEAD(self)) + { + // handle water here + vector midpoint = ((self.absmin + self.absmax) * 0.5); + if(pointcontents(midpoint) == CONTENT_WATER) + { + self.velocity = self.velocity * 0.5; + + // do we want this? + //if(pointcontents(midpoint + '0 0 2') == CONTENT_WATER) + //{ self.velocity_z = 70; } + } goto end; + } #ifdef SVQC if (!self.fixangle && !g_bugrigs) @@ -1788,7 +1883,7 @@ void PM_Main() else if (time < self.ladder_time) PM_ladder(maxspeed_mod); - else if (ITEMS(self) & IT_USING_JETPACK) + else if (ITEMS_STAT(self) & IT_USING_JETPACK) PM_jetpack(maxspeed_mod); else if (IS_ONGROUND(self)) @@ -1814,6 +1909,11 @@ void PM_Main() self.lastflags = self.flags; self.lastclassname = self.classname; + +#ifdef CSQC + self.v_angle = oldv_angle; + self.angles = oldangles; +#endif } #ifdef SVQC