diff --git a/src/game/client/neo/c_neo_player.cpp b/src/game/client/neo/c_neo_player.cpp index 5bfc8bd7c..0b4096cbb 100644 --- a/src/game/client/neo/c_neo_player.cpp +++ b/src/game/client/neo/c_neo_player.cpp @@ -88,7 +88,6 @@ IMPLEMENT_CLIENTCLASS_DT(C_NEO_Player, DT_NEO_Player, CNEO_Player) RecvPropBool(RECVINFO(m_bInThermOpticCamo)), RecvPropBool(RECVINFO(m_bLastTickInThermOpticCamo)), RecvPropBool(RECVINFO(m_bInVision)), - RecvPropBool(RECVINFO(m_bHasBeenAirborneForTooLongToSuperJump)), RecvPropBool(RECVINFO(m_bInAim)), RecvPropBool(RECVINFO(m_bIneligibleForLoadoutPick)), RecvPropBool(RECVINFO(m_bCarryingGhost)), @@ -121,7 +120,6 @@ BEGIN_PREDICTION_DATA(C_NEO_Player) DEFINE_PRED_FIELD(m_bInAim, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE), DEFINE_PRED_FIELD(m_bInLean, FIELD_INTEGER, FTYPEDESC_INSENDTABLE), DEFINE_PRED_FIELD(m_bInVision, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE), - DEFINE_PRED_FIELD(m_bHasBeenAirborneForTooLongToSuperJump, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE), DEFINE_PRED_FIELD_TOL(m_flVisionLastTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE), DEFINE_PRED_FIELD_TOL(m_flJumpLastTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE), @@ -451,7 +449,6 @@ C_NEO_Player::C_NEO_Player() m_iXP.GetForModify() = 0; m_bInThermOpticCamo = m_bInVision = false; - m_bHasBeenAirborneForTooLongToSuperJump = false; m_bInAim = false; m_bCarryingGhost = false; m_bIneligibleForLoadoutPick = false; @@ -459,8 +456,6 @@ C_NEO_Player::C_NEO_Player() m_flCamoAuxLastTime = 0; m_flVisionLastTime = 0; - m_flLastAirborneJumpOkTime = 0; - m_flLastSuperJumpTime = 0; m_bFirstAliveTick = true; m_bFirstDeathTick = true; @@ -1170,27 +1165,6 @@ void C_NEO_Player::PreThink( void ) Lean(); } - // Eek. See rationale for this thing in CNEO_Player::PreThink - if (IsAirborne()) - { - m_flLastAirborneJumpOkTime = gpGlobals->curtime; - const float deltaTime = gpGlobals->curtime - m_flLastAirborneJumpOkTime; - const float leeway = 0.5f; - if (deltaTime > leeway) - { - m_bHasBeenAirborneForTooLongToSuperJump = false; - m_flLastAirborneJumpOkTime = gpGlobals->curtime; - } - else - { - m_bHasBeenAirborneForTooLongToSuperJump = true; - } - } - else - { - m_bHasBeenAirborneForTooLongToSuperJump = false; - } - if (m_iNeoClass == NEO_CLASS_RECON && (m_afButtonPressed & IN_JUMP) && (m_nButtons & IN_SPEED) && IsAllowedToSuperJump()) @@ -1466,48 +1440,6 @@ void C_NEO_Player::UpdateGlowEffects(int iNewTeam) } #endif // GLOWS_ENABLE -bool C_NEO_Player::IsAllowedToSuperJump(void) -{ - if (!IsSprinting()) - return false; - - if (IsCarryingGhost()) - return false; - - if (GetMoveParent()) - return false; - - if (IsPlayerUnderwater()) - return false; - - // Can't superjump whilst airborne (although it is kind of cool) - if (m_bHasBeenAirborneForTooLongToSuperJump) - return false; - - // Only superjump if we have a reasonable jump direction in mind - // NEO TODO (Rain): should we support sideways superjumping? - if ((m_nButtons & (IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT)) == 0) - { - return false; - } - - // The suit check is for prediction only, actual power drain happens serverside - if (m_HL2Local.m_flSuitPower < SUPER_JMP_COST) - return false; - - if (SUPER_JMP_DELAY_BETWEEN_JUMPS > 0) - { - m_flLastSuperJumpTime = gpGlobals->curtime; - const float deltaTime = gpGlobals->curtime - m_flLastSuperJumpTime; - if (deltaTime > SUPER_JMP_DELAY_BETWEEN_JUMPS) - return false; - - m_flLastSuperJumpTime = gpGlobals->curtime; - } - - return true; -} - // This is applied for prediction purposes. It should match CNEO_Player's method. void C_NEO_Player::SuperJump(void) { @@ -1551,6 +1483,7 @@ float C_NEO_Player::CloakPower_CurrentVisualPercentage(void) const void C_NEO_Player::Spawn( void ) { BaseClass::Spawn(); + FixupOnGroundFlag(); m_bLastTickInThermOpticCamo = m_bInThermOpticCamo = false; m_flCamoAuxLastTime = 0; @@ -1981,8 +1914,6 @@ void C_NEO_Player::CSpectatorTakeoverPlayerUpdate(C_NEO_Player* pPlayerTakeoverT m_flCamoAuxLastTime = pPlayerTakeoverTarget->m_flCamoAuxLastTime; m_flVisionLastTime = pPlayerTakeoverTarget->m_flVisionLastTime; - m_flLastAirborneJumpOkTime = pPlayerTakeoverTarget->m_flLastAirborneJumpOkTime; - m_flLastSuperJumpTime = pPlayerTakeoverTarget->m_flLastSuperJumpTime; m_bPreviouslyReloading = pPlayerTakeoverTarget->m_bPreviouslyReloading; m_bLastTickInThermOpticCamo = pPlayerTakeoverTarget->m_bLastTickInThermOpticCamo; m_flTocFactor = pPlayerTakeoverTarget->m_flTocFactor; diff --git a/src/game/client/neo/c_neo_player.h b/src/game/client/neo/c_neo_player.h index c5d7015b8..60464ea78 100644 --- a/src/game/client/neo/c_neo_player.h +++ b/src/game/client/neo/c_neo_player.h @@ -205,6 +205,7 @@ class C_NEO_Player : public C_HL2MP_Player void CheckLeanButtons(); void PlayCloakSound(); void SetCloakState(bool state); + void FixupOnGroundFlag(); bool IsAllowedToSuperJump(void); @@ -222,8 +223,6 @@ class C_NEO_Player : public C_HL2MP_Player CNetworkVar(int, m_iXP); CNetworkVar(int, m_iLoadoutWepChoice); CNetworkVar(int, m_iNextSpawnClassChoice); - - CNetworkVar(bool, m_bHasBeenAirborneForTooLongToSuperJump); CNetworkVar(float, m_flCamoAuxLastTime); CNetworkVar(float, m_flVisionLastTime); @@ -264,9 +263,6 @@ class C_NEO_Player : public C_HL2MP_Player bool m_bPreviouslyReloading; bool m_bSpecRefreshedStates; - float m_flLastAirborneJumpOkTime; - float m_flLastSuperJumpTime; - float m_flTocFactor; // Cloak strength, controls tint, refraction amount. Lower values make player more difficult to spot // Non-network version of m_szNeoName with dupe checker index diff --git a/src/game/server/neo/neo_player.cpp b/src/game/server/neo/neo_player.cpp index 17766eeda..8de413763 100644 --- a/src/game/server/neo/neo_player.cpp +++ b/src/game/server/neo/neo_player.cpp @@ -63,7 +63,6 @@ SendPropEHandle(SENDINFO(m_hCommandingPlayer)), SendPropBool(SENDINFO(m_bInThermOpticCamo)), SendPropBool(SENDINFO(m_bLastTickInThermOpticCamo)), SendPropBool(SENDINFO(m_bInVision)), -SendPropBool(SENDINFO(m_bHasBeenAirborneForTooLongToSuperJump)), SendPropBool(SENDINFO(m_bShowTestMessage)), SendPropBool(SENDINFO(m_bInAim)), SendPropBool(SENDINFO(m_bIneligibleForLoadoutPick)), @@ -105,7 +104,6 @@ DEFINE_FIELD(m_bInLean, FIELD_INTEGER), DEFINE_FIELD(m_bInThermOpticCamo, FIELD_BOOLEAN), DEFINE_FIELD(m_bLastTickInThermOpticCamo, FIELD_BOOLEAN), DEFINE_FIELD(m_bInVision, FIELD_BOOLEAN), -DEFINE_FIELD(m_bHasBeenAirborneForTooLongToSuperJump, FIELD_BOOLEAN), DEFINE_FIELD(m_bShowTestMessage, FIELD_BOOLEAN), DEFINE_FIELD(m_bInAim, FIELD_BOOLEAN), @@ -584,7 +582,6 @@ CNEO_Player::CNEO_Player() V_memset(m_szNeoCrosshair.GetForModify(), 0, sizeof(m_szNeoCrosshair)); m_bInThermOpticCamo = m_bInVision = false; - m_bHasBeenAirborneForTooLongToSuperJump = false; m_bInAim = false; m_bCarryingGhost = false; m_bInLean = NEO_LEAN_NONE; @@ -597,11 +594,8 @@ CNEO_Player::CNEO_Player() m_flCamoAuxLastTime = 0; m_flVisionLastTime = 0; - m_flLastAirborneJumpOkTime = 0; - m_flLastSuperJumpTime = 0; m_botThermOpticCamoDisruptedTimer.Invalidate(); - m_bFirstDeathTick = true; m_bCorpseSet = false; m_bPreviouslyReloading = false; @@ -722,6 +716,7 @@ void CNEO_Player::Spawn(void) } BaseClass::Spawn(); + FixupOnGroundFlag(); SetMaxHealth(MAX_HEALTH_FOR_CLASS[m_iNeoClass]); SetHealth(GetMaxHealth()); @@ -1149,37 +1144,6 @@ void CNEO_Player::PreThink(void) Lean(); } - // NEO HACK (Rain): Just bodging together a check for if we're allowed - // to superjump, or if we've been airborne too long for that. - // Ideally this should get cleaned up and moved to wherever - // the regular engine jump does a similar check. - bool newNetAirborneVal; - if (IsAirborne()) - { - m_flLastAirborneJumpOkTime = gpGlobals->curtime; - const float deltaTime = gpGlobals->curtime - m_flLastAirborneJumpOkTime; - const float leeway = 0.5f; - if (deltaTime > leeway) - { - newNetAirborneVal = false; - m_flLastAirborneJumpOkTime = gpGlobals->curtime; - } - else - { - newNetAirborneVal = true; - } - } - else - { - newNetAirborneVal = false; - } - // Only send the network update if we actually changed state - if (m_bHasBeenAirborneForTooLongToSuperJump != newNetAirborneVal) - { - m_bHasBeenAirborneForTooLongToSuperJump = newNetAirborneVal; - NetworkStateChanged(); - } - if (m_iNeoClass == NEO_CLASS_RECON && (m_afButtonPressed & IN_JUMP) && (m_nButtons & IN_SPEED) && IsAllowedToSuperJump()) @@ -1662,51 +1626,6 @@ void CNEO_Player::SuperJump(void) ApplyAbsVelocityImpulse(forward * boostIntensity); } -bool CNEO_Player::IsAllowedToSuperJump(void) -{ - // NEOJANK: Bots are exempt from certain checks due to their their erratic input control - if (!IsBot()) - { - if (!IsSprinting()) - return false; - } - - if (IsCarryingGhost()) - return false; - - if (GetMoveParent()) - return false; - - if (IsPlayerUnderwater()) - return false; - - // Can't superjump whilst airborne (although it is kind of cool) - if (m_bHasBeenAirborneForTooLongToSuperJump) - return false; - - // Only superjump if we have a reasonable jump direction in mind - // NEO TODO (Rain): should we support sideways superjumping? - if ((m_nButtons & (IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT)) == 0) - { - return false; - } - - if (SuitPower_GetCurrentPercentage() < SUPER_JMP_COST) - return false; - - if (SUPER_JMP_DELAY_BETWEEN_JUMPS > 0) - { - m_flLastSuperJumpTime = gpGlobals->curtime; - const float deltaTime = gpGlobals->curtime - m_flLastSuperJumpTime; - if (deltaTime > SUPER_JMP_DELAY_BETWEEN_JUMPS) - return false; - - m_flLastSuperJumpTime = gpGlobals->curtime; - } - - return true; -} - void CNEO_Player::PostThink(void) { BaseClass::PostThink(); @@ -4294,14 +4213,11 @@ void CNEO_Player::SpectatorTakeoverPlayerPreThink() m_HL2Local.m_flSuitPower = pPlayerTakeoverTarget->m_HL2Local.m_flSuitPower; m_bInThermOpticCamo = pPlayerTakeoverTarget->m_bInThermOpticCamo; - m_bHasBeenAirborneForTooLongToSuperJump = pPlayerTakeoverTarget->m_bHasBeenAirborneForTooLongToSuperJump; m_bInAim = pPlayerTakeoverTarget->m_bInAim; Weapon_SetZoom(pPlayerTakeoverTarget->m_bInAim); m_bCarryingGhost = pPlayerTakeoverTarget->m_bCarryingGhost; m_bInLean = pPlayerTakeoverTarget->m_bInLean; m_flCamoAuxLastTime = pPlayerTakeoverTarget->m_flCamoAuxLastTime; - m_flLastAirborneJumpOkTime = pPlayerTakeoverTarget->m_flLastAirborneJumpOkTime; - m_flLastSuperJumpTime = pPlayerTakeoverTarget->m_flLastSuperJumpTime; m_botThermOpticCamoDisruptedTimer.Invalidate(); // taken over by player m_bFirstDeathTick = pPlayerTakeoverTarget->m_bFirstDeathTick; m_bCorpseSet = pPlayerTakeoverTarget->m_bCorpseSet; diff --git a/src/game/server/neo/neo_player.h b/src/game/server/neo/neo_player.h index dd603fda4..c146e9a7d 100644 --- a/src/game/server/neo/neo_player.h +++ b/src/game/server/neo/neo_player.h @@ -266,6 +266,7 @@ class CNEO_Player : public CHL2MP_Player void CheckLeanButtons(); void PlayCloakSound(bool removeLocalPlayer = true); void SetCloakState(bool state); + void FixupOnGroundFlag(); public: CNetworkVar(int, m_iNeoClass); @@ -292,7 +293,6 @@ class CNEO_Player : public CHL2MP_Player CNetworkVar(bool, m_bInThermOpticCamo); CNetworkVar(bool, m_bLastTickInThermOpticCamo); CNetworkVar(bool, m_bInVision); - CNetworkVar(bool, m_bHasBeenAirborneForTooLongToSuperJump); CNetworkVar(bool, m_bInAim); CNetworkVar(int, m_bInLean); CNetworkVar(bool, m_bCarryingGhost); @@ -349,9 +349,6 @@ class CNEO_Player : public CHL2MP_Player bool m_bPreviouslyReloading; bool m_bNeoNameHasSet; - float m_flLastAirborneJumpOkTime; - float m_flLastSuperJumpTime; - // Non-network version of m_szNeoName with dupe checker index mutable char m_szNeoNameWDupeIdx[MAX_PLAYER_NAME_LENGTH + 10]; mutable bool m_szNeoNameWDupeIdxNeedUpdate; diff --git a/src/game/shared/neo/neo_player_shared.cpp b/src/game/shared/neo/neo_player_shared.cpp index 2f1b1a5f7..4ee62dc18 100644 --- a/src/game/shared/neo/neo_player_shared.cpp +++ b/src/game/shared/neo/neo_player_shared.cpp @@ -884,3 +884,64 @@ bool CNEO_Player::TestHitboxes(const Ray_t& ray, unsigned int fContentsMask, tra return true; } + +bool CNEO_Player::IsAllowedToSuperJump() +{ + // NEOJANK: Bots are exempt from certain checks due to their their erratic input control + if (!IsBot()) + { + if (!IsSprinting()) + return false; + } + + if (IsCarryingGhost()) + return false; + + if (GetMoveParent()) + return false; + + if (IsAirborne()) + return false; + + if (GetWaterLevel() > WL_Feet) + return false; + + // Only superjump if we have a reasonable jump direction in mind + // NEO TODO (Rain): should we support sideways superjumping? + if ((m_nButtons & (IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT)) == 0) + { + return false; + } + + if (SuitPower_GetCurrentPercentage() < SUPER_JMP_COST) + return false; + + return true; +} + +// BaseClass::Spawn sets FL_ONGROUND for us, which is convenient but not guaranteed correct, +// for example if spawning in/above a body of water. This matters especially for the recon +// superjump validity check. So let's check if we've actually got a ground or not. +// Another case that goes out of whack without this fixup is being able to superjump mid-air +// when spawning into a warmup/non-freezetime'd match, before hitting the floor for the first time. +void CNEO_Player::FixupOnGroundFlag() +{ + // Assert that the client side baseclass doesn't do this (and therefore we need do nothing for it) + Assert((GetFlags() & FL_ONGROUND) == IsServer()); +#ifdef GAME_DLL + if (GetTeamNumber() < FIRST_GAME_TEAM) // if it's not a player, don't bother + return; + const Vector& start = GetAbsOrigin(); + const Vector& maxs = GetPlayerMaxs(); + const Vector& mins = GetPlayerMins(); + float playerHeight = maxs.z - mins.z; + Vector end(start.x, start.y, start.z - playerHeight); + Ray_t ray; + ray.Init(start, end, mins, maxs); + trace_t trace; + UTIL_TraceRay(ray, MASK_PLAYERSOLID, this, COLLISION_GROUP_PLAYER_MOVEMENT, &trace); + const bool foundGround = trace.DidHit(); + if (!foundGround) + RemoveFlag(FL_ONGROUND); // not actually on ground, remove it! +#endif +} diff --git a/src/game/shared/neo/neo_player_shared.h b/src/game/shared/neo/neo_player_shared.h index 9e621e937..95e27e087 100644 --- a/src/game/shared/neo/neo_player_shared.h +++ b/src/game/shared/neo/neo_player_shared.h @@ -177,10 +177,6 @@ COMPILE_TIME_ASSERT(NEO_ASSAULT_CROUCH_SPEED == NEO_VIP_CROUCH_SPEED); #define MIN_CLOAK_AUX 0.1f #define SPRINT_START_MIN (2.0f) -// Original NT allows chaining superjumps up ramps, -// so leaving this zeroed for enabling movement tricks. -#define SUPER_JMP_DELAY_BETWEEN_JUMPS 0 - // NEO Activities #define ACT_NEO_ATTACK ACT_RANGE_ATTACK1 #define ACT_NEO_RELOAD ACT_RELOAD