X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fphysics%2Fplayer.qc;fp=qcsrc%2Fcommon%2Fphysics%2Fplayer.qc;h=5ba6e82685b3204ce2caa5da04c5862253f0c974;hb=be37ea91fb3bbd1a6fa4f0b70b32d1ea95343ad4;hp=20e2d4cc32f16d0b736e421d0a1172262492ff7c;hpb=c1afbb3db4d2b8f1ca73b331ebe00cd276a99f1b;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/physics/player.qc b/qcsrc/common/physics/player.qc index 20e2d4cc3..5ba6e8268 100644 --- a/qcsrc/common/physics/player.qc +++ b/qcsrc/common/physics/player.qc @@ -1,28 +1,32 @@ #include "player.qh" -#include "../triggers/include.qh" +#include "../mapobjects/_mod.qh" #include "../viewloc.qh" #ifdef SVQC #include -#include "../triggers/trigger/viewloc.qh" +#include "../mapobjects/trigger/viewloc.qh" // client side physics bool Physics_Valid(string thecvar) { - return autocvar_g_physics_clientselect && thecvar != "" && thecvar && thecvar != "default" && strhasword(autocvar_g_physics_clientselect_options, thecvar); + return thecvar != "" && thecvar && thecvar != "default" && strhasword(autocvar_g_physics_clientselect_options, thecvar); } float Physics_ClientOption(entity this, string option, float defaultval) { + if(!autocvar_g_physics_clientselect) + return defaultval; + if(IS_REAL_CLIENT(this) && Physics_Valid(CS(this).cvar_cl_physics)) { string s = strcat("g_physics_", CS(this).cvar_cl_physics, "_", option); if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS) return cvar(s); } - if(autocvar_g_physics_clientselect && autocvar_g_physics_clientselect_default) + if(autocvar_g_physics_clientselect_default && autocvar_g_physics_clientselect_default != "" && autocvar_g_physics_clientselect_default != "default") { + // NOTE: not using Physics_Valid here, so the default can be forced to something normally unavailable string s = strcat("g_physics_", autocvar_g_physics_clientselect_default, "_", option); if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS) return cvar(s); @@ -37,26 +41,36 @@ void Physics_UpdateStats(entity this) MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this); float maxspd_mod = PHYS_HIGHSPEED(this); - - STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw), maxspd_mod); - STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw)) - ? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw), maxspd_mod) - : 0; - STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod; - STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking - - STAT(PL_MIN, this) = autocvar_sv_player_mins; - STAT(PL_MAX, this) = autocvar_sv_player_maxs; - STAT(PL_VIEW_OFS, this) = autocvar_sv_player_viewoffset; - STAT(PL_CROUCH_MIN, this) = autocvar_sv_player_crouch_mins; - STAT(PL_CROUCH_MAX, this) = autocvar_sv_player_crouch_maxs; - STAT(PL_CROUCH_VIEW_OFS, this) = autocvar_sv_player_crouch_viewoffset; + STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking + if (autocvar_g_movement_highspeed_q3_compat) { + STAT(MOVEVARS_AIRACCEL_QW, this) = Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw); + STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw); + STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw); + } else { + STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw), maxspd_mod); + STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw)) + ? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw), maxspd_mod) + : 0; + STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod; + } + bool vq3compat = autocvar_sv_vq3compat && autocvar_sv_vq3compat_changehitbox; // NOTE: these hitboxes are off by 1 due to engine differences + STAT(PL_MIN, this) = (vq3compat) ? '-15 -15 -24' : autocvar_sv_player_mins; + STAT(PL_MAX, this) = (vq3compat) ? '15 15 32' : autocvar_sv_player_maxs; + STAT(PL_VIEW_OFS, this) = (vq3compat) ? '0 0 26' : autocvar_sv_player_viewoffset; + STAT(PL_CROUCH_MIN, this) = (vq3compat) ? '-15 -15 -24' : autocvar_sv_player_crouch_mins; + STAT(PL_CROUCH_MAX, this) = (vq3compat) ? '15 15 16' : autocvar_sv_player_crouch_maxs; + STAT(PL_CROUCH_VIEW_OFS, this) = (vq3compat) ? '0 0 12' : autocvar_sv_player_crouch_viewoffset; // old stats // fix some new settings STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, this) = Physics_ClientOption(this, "airaccel_qw_stretchfactor", autocvar_sv_airaccel_qw_stretchfactor); STAT(MOVEVARS_MAXAIRSTRAFESPEED, this) = Physics_ClientOption(this, "maxairstrafespeed", autocvar_sv_maxairstrafespeed); - STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed); + if (autocvar_g_movement_highspeed_q3_compat) { + STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed) * maxspd_mod; + } else { + STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed); + } + STAT(MOVEVARS_AIRSTRAFEACCELERATE, this) = Physics_ClientOption(this, "airstrafeaccelerate", autocvar_sv_airstrafeaccelerate); STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, this) = Physics_ClientOption(this, "warsowbunny_turnaccel", autocvar_sv_warsowbunny_turnaccel); STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, this) = Physics_ClientOption(this, "airaccel_sideways_friction", autocvar_sv_airaccel_sideways_friction); @@ -75,7 +89,10 @@ void Physics_UpdateStats(entity this) STAT(MOVEVARS_AIRACCELERATE, this) = Physics_ClientOption(this, "airaccelerate", autocvar_sv_airaccelerate); STAT(MOVEVARS_AIRSTOPACCELERATE, this) = Physics_ClientOption(this, "airstopaccelerate", autocvar_sv_airstopaccelerate); STAT(MOVEVARS_JUMPVELOCITY, this) = Physics_ClientOption(this, "jumpvelocity", autocvar_sv_jumpvelocity); + STAT(MOVEVARS_JUMPVELOCITY_CROUCH, this) = Physics_ClientOption(this, "jumpvelocity_crouch", autocvar_sv_jumpvelocity_crouch); STAT(MOVEVARS_TRACK_CANJUMP, this) = Physics_ClientOption(this, "track_canjump", autocvar_sv_track_canjump); + + MUTATOR_CALLHOOK(PlayerPhysics_PostUpdateStats, this, maxspd_mod); } #endif @@ -97,42 +114,53 @@ float GeomLerp(float a, float _lerp, float b) void PM_ClientMovement_UpdateStatus(entity this) { -#ifdef CSQC if(!IS_PLAYER(this)) return; - // set crouched - bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this); + bool have_hook = false; for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { - entity wep = viewmodels[slot]; - if(wep.hook && !wasfreed(wep.hook)) + #if defined(CSQC) + entity wepent = viewmodels[slot]; + #elif defined(SVQC) + .entity weaponentity = weaponentities[slot]; + entity wepent = this.(weaponentity); + #endif + if(wepent.hook && !wasfreed(wepent.hook)) { - do_crouch = false; - break; // don't bother checking the others + have_hook = true; + break; } } - if(this.waterlevel >= WATERLEVEL_SWIMMING) + bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this); + if(this.viewloc && !(this.viewloc.spawnflags & VIEWLOC_FREEMOVE) && PHYS_CS(this).movement.x < 0) + do_crouch = true; + if (have_hook) { do_crouch = false; - if(hud != HUD_NORMAL) + //} else if (this.waterlevel >= WATERLEVEL_SWIMMING) { + //do_crouch = false; + } else if (PHYS_INVEHICLE(this)) { do_crouch = false; - if(STAT(FROZEN, this)) + } else if (STAT(FROZEN, this) || IS_DEAD(this)) { do_crouch = false; + } - if (do_crouch) - { - // wants to crouch, this always works - if (!IS_DUCKED(this)) SET_DUCKED(this); - } - else - { - // wants to stand, if currently crouching we need to check for a low ceiling first - if (IS_DUCKED(this)) - { - tracebox(this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), this.origin, MOVE_NORMAL, this); - if (!trace_startsolid) UNSET_DUCKED(this); + if (do_crouch) { + if (!IS_DUCKED(this)) { + SET_DUCKED(this); + this.view_ofs = STAT(PL_CROUCH_VIEW_OFS, this); + setsize(this, STAT(PL_CROUCH_MIN, this), STAT(PL_CROUCH_MAX, this)); + // setanim(this, this.anim_duck, false, true, true); // this anim is BROKEN anyway } + } else if (IS_DUCKED(this)) { + tracebox(this.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), this.origin, false, this); + if (!trace_startsolid) { + UNSET_DUCKED(this); + this.view_ofs = STAT(PL_VIEW_OFS, this); + setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this)); + } } +#ifdef CSQC if (IS_ONGROUND(this) || this.velocity.z <= 0 || PHYS_WATERJUMP_TIME(this) <= 0) PHYS_WATERJUMP_TIME(this) = 0; @@ -303,7 +331,7 @@ bool PlayerJump(entity this) #endif bool doublejump = false; - float mjumpheight = PHYS_JUMPVELOCITY(this); + float mjumpheight = ((PHYS_JUMPVELOCITY_CROUCH(this) && IS_DUCKED(this)) ? PHYS_JUMPVELOCITY_CROUCH(this) : PHYS_JUMPVELOCITY(this)); bool track_jump = PHYS_CL_TRACK_CANJUMP(this); if (MUTATOR_CALLHOOK(PlayerJump, this, mjumpheight, doublejump)) @@ -453,7 +481,7 @@ void CheckPlayerJump(entity this) bool air_jump = !playerjump || M_ARGV(2, bool); bool activate = JETPACK_JUMP(this) && air_jump && PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_JETPACK(this); - bool has_fuel = !PHYS_JETPACK_FUEL(this) || PHYS_AMMO_FUEL(this) || (ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO); + bool has_fuel = !PHYS_JETPACK_FUEL(this) || PHYS_AMMO_FUEL(this) || (ITEMS_STAT(this) & IT_UNLIMITED_AMMO); if (!(ITEMS_STAT(this) & ITEM_Jetpack.m_itemid)) { } else if (this.jetpack_stopped) { } @@ -766,7 +794,7 @@ void PM_jetpack(entity this, float maxspd_mod, float dt) wishvel_z = (wishvel_z - PHYS_GRAVITY(this)) * fz + PHYS_GRAVITY(this); fvel = min(1, vlen(wishvel) / best); - if (PHYS_JETPACK_FUEL(this) && !(ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO)) + if (PHYS_JETPACK_FUEL(this) && !(ITEMS_STAT(this) & IT_UNLIMITED_AMMO)) f = min(1, PHYS_AMMO_FUEL(this) / (PHYS_JETPACK_FUEL(this) * dt * fvel)); else f = 1; @@ -779,8 +807,8 @@ void PM_jetpack(entity this, float maxspd_mod, float dt) UNSET_ONGROUND(this); #ifdef SVQC - if (!(ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO)) - this.ammo_fuel -= PHYS_JETPACK_FUEL(this) * dt * fvel * f; + if (!(ITEMS_STAT(this) & IT_UNLIMITED_AMMO)) + TakeResource(this, RES_FUEL, PHYS_JETPACK_FUEL(this) * dt * fvel * f); ITEMS_STAT(this) |= IT_USING_JETPACK; @@ -797,7 +825,8 @@ bool IsFlying(entity this) return false; if(this.waterlevel >= WATERLEVEL_SWIMMING) return false; - traceline(this.origin, this.origin - '0 0 48', MOVE_NORMAL, this); + tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 24', MOVE_NORMAL, this); + //traceline(this.origin, this.origin - '0 0 48', MOVE_NORMAL, this); if(trace_fraction < 1) return false; return true;