Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No ghost bunnyhopping + landing slowdown rework #857

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
53 changes: 39 additions & 14 deletions mp/src/game/client/neo/c_neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ C_NEO_Player::C_NEO_Player()
m_bInThermOpticCamo = m_bInVision = false;
m_bHasBeenAirborneForTooLongToSuperJump = false;
m_bInAim = false;
m_bCarryingGhost = false;
m_bIneligibleForLoadoutPick = false;
m_bInLean = NEO_LEAN_NONE;

Expand Down Expand Up @@ -798,15 +799,12 @@ void C_NEO_Player::PlayStepSound( Vector &vecOrigin,
BaseClass::PlayStepSound(vecOrigin, psurface, fvol, force);
}

extern ConVar sv_infinite_aux_power;
extern ConVar glow_outline_effect_enable;
void C_NEO_Player::PreThink( void )
extern ConVar neo_ghost_bhopping;
void C_NEO_Player::CalculateSpeed(void)
{
BaseClass::PreThink();

float speed = GetNormSpeed();
static constexpr float DUCK_WALK_SPEED_MODIFIER = 0.75;
if (m_nButtons & IN_DUCK)
if (m_nButtons & IN_DUCK || IsDucked() || IsDucking())
{
speed *= DUCK_WALK_SPEED_MODIFIER;
}
Expand All @@ -816,9 +814,9 @@ void C_NEO_Player::PreThink( void )
}
if (IsSprinting() && !IsAirborne())
{
static constexpr float RECON_SPRINT_SPEED_MODIFIER = 0.75;
static constexpr float OTHER_CLASSES_SPRINT_SPEED_MODIFIER = 0.6;
speed /= m_iNeoClass == NEO_CLASS_RECON ? RECON_SPRINT_SPEED_MODIFIER : OTHER_CLASSES_SPRINT_SPEED_MODIFIER;
static constexpr float RECON_SPRINT_SPEED_MODIFIER = 1.35;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

static constexpr float OTHER_CLASSES_SPRINT_SPEED_MODIFIER = 1.6;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

speed *= m_iNeoClass == NEO_CLASS_RECON ? RECON_SPRINT_SPEED_MODIFIER : OTHER_CLASSES_SPRINT_SPEED_MODIFIER;
}
if (IsInAim())
{
Expand All @@ -830,17 +828,44 @@ void C_NEO_Player::PreThink( void )
speed *= pNeoWep->GetSpeedScale();
}

Vector absoluteVelocity = GetAbsVelocity();
absoluteVelocity.z = 0.f;
float currentSpeed = absoluteVelocity.Length();

if (!neo_ghost_bhopping.GetBool() && GetMoveType() != MOVETYPE_LADDER && currentSpeed > speed && m_bCarryingGhost)
{
float overSpeed = currentSpeed - speed;
absoluteVelocity.NormalizeInPlace();
absoluteVelocity *= -overSpeed;
ApplyAbsVelocityImpulse(absoluteVelocity);
}

// Slowdown after landing
if (!IsAirborne() && m_iNeoClass != NEO_CLASS_RECON)
{
const float deltaTime = gpGlobals->curtime - m_flLastAirborneJumpOkTime;
const float leeway = 1.0f;
if (deltaTime < leeway)
const float timeSinceLanding = gpGlobals->curtime - m_flLastAirborneJumpOkTime;
constexpr float INITIAL_SLOWDOWN_TIME = 0.25f;
constexpr float IMPAIRED_ACCELERATION_TIME = INITIAL_SLOWDOWN_TIME + (1 / 3.f);
if (timeSinceLanding < INITIAL_SLOWDOWN_TIME)
{
speed = MIN(speed, 75.f);
}
else if (timeSinceLanding < IMPAIRED_ACCELERATION_TIME)
{
speed = (speed / 2) + (deltaTime / 2 * (speed));
speed *= timeSinceLanding / IMPAIRED_ACCELERATION_TIME;
}
}
SetMaxSpeed(MAX(speed, 56));

}

extern ConVar sv_infinite_aux_power;
extern ConVar glow_outline_effect_enable;
void C_NEO_Player::PreThink( void )
{
BaseClass::PreThink();

CalculateSpeed();

CheckThermOpticButtons();
CheckVisionButtons();

Expand Down
2 changes: 2 additions & 0 deletions mp/src/game/client/neo/c_neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class C_NEO_Player : public C_HL2MP_Player

virtual void ClientThink( void );
virtual void PreThink( void );
virtual void CalculateSpeed( void );
virtual void PostThink( void );
virtual void Spawn( void );

Expand Down Expand Up @@ -196,6 +197,7 @@ class C_NEO_Player : public C_HL2MP_Player
CNetworkVar(bool, m_bInVision);
CNetworkVar(bool, m_bInAim);
CNetworkVar(int, m_bInLean);
CNetworkVar(bool, m_bCarryingGhost);
CNetworkVar(bool, m_bIneligibleForLoadoutPick);

CNetworkVar(int, m_iNeoClass);
Expand Down
61 changes: 43 additions & 18 deletions mp/src/game/server/neo/neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ CNEO_Player::CNEO_Player()
m_bInThermOpticCamo = m_bInVision = false;
m_bHasBeenAirborneForTooLongToSuperJump = false;
m_bInAim = false;
m_bCarryingGhost = false;
m_bInLean = NEO_LEAN_NONE;

m_iLoadoutWepChoice = 0;
Expand Down Expand Up @@ -662,18 +663,12 @@ void CNEO_Player::CheckLeanButtons()
}
}

void CNEO_Player::PreThink(void)
extern ConVar neo_ghost_bhopping;
void CNEO_Player::CalculateSpeed(void)
{
BaseClass::PreThink();

if (!m_bInThermOpticCamo)
{
CloakPower_Update();
}

float speed = GetNormSpeed();
static constexpr float DUCK_WALK_SPEED_MODIFIER = 0.75;
if (m_nButtons & IN_DUCK)
if (m_nButtons & IN_DUCK || IsDucked() || IsDucking())
{
speed *= DUCK_WALK_SPEED_MODIFIER;
}
Expand All @@ -683,30 +678,60 @@ void CNEO_Player::PreThink(void)
}
if (IsSprinting() && !IsAirborne())
{
static constexpr float RECON_SPRINT_SPEED_MODIFIER = 0.75;
static constexpr float OTHER_CLASSES_SPRINT_SPEED_MODIFIER = 0.6;
speed /= m_iNeoClass == NEO_CLASS_RECON ? RECON_SPRINT_SPEED_MODIFIER : OTHER_CLASSES_SPRINT_SPEED_MODIFIER;
static constexpr float RECON_SPRINT_SPEED_MODIFIER = 1.35;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this defined in a header somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
I don't think so? Also I just did this pre-emptively in preperation for your pr to fix these values, if you're defining this in the header somewhere then ill update the pr once i see what that looks like

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define NEO_RECON_SPRINT_SPEED (NEO_BASE_SPRINT_SPEED * NEO_RECON_SPEED_MODIFIER)

Copy link
Contributor Author

@AdamTadeusz AdamTadeusz Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically this is the NEO_SPRINT_MODIFIER which has a value of 1.6, but recons have a different sprint modifier to the other classes

NEO_RECON_SPRINT_SPEED has a value of 272 if I'm not mistaken

(Edit) perhaps they have the same sprint speed modifier, I'm not going to pretend I know how to dive into the dll of the original game and get the exact values, but following the calculations here https://steamcommunity.com/sharedfiles/filedetails/?id=281690103 and ones ive taken myself I can say with confidence that assuming recons have a different sprint speed modifier is a decent enough way of getting the correct speed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nagrywanie.ekranu.2025-01-29.174832.mp4

Here is a recording of the sprint speed of a recon in the original after removing all weapons (hence why the viewmodel is slightly off), the value of 272 is 2 units off and we're currently using the speed with a knife or other very light weapon as the base speed anyway (which despite Agiels protests I don't think is really an issue).

static constexpr float OTHER_CLASSES_SPRINT_SPEED_MODIFIER = 1.6;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

speed *= m_iNeoClass == NEO_CLASS_RECON ? RECON_SPRINT_SPEED_MODIFIER : OTHER_CLASSES_SPRINT_SPEED_MODIFIER;
}
if (m_bInAim.Get())
if (IsInAim())
{
static constexpr float AIM_SPEED_MODIFIER = 0.6;
speed *= AIM_SPEED_MODIFIER;
}
if (auto pNeoWep = static_cast<CNEOBaseCombatWeapon *>(GetActiveWeapon()))
if (auto pNeoWep = static_cast<CNEOBaseCombatWeapon*>(GetActiveWeapon()))
{
speed *= pNeoWep->GetSpeedScale();
}

Vector absoluteVelocity = GetAbsVelocity();
absoluteVelocity.z = 0.f;
float currentSpeed = absoluteVelocity.Length();

if (!neo_ghost_bhopping.GetBool() && GetMoveType() != MOVETYPE_LADDER && currentSpeed > speed && m_bCarryingGhost)
{
float overSpeed = currentSpeed - speed;
absoluteVelocity.NormalizeInPlace();
absoluteVelocity *= -overSpeed;
ApplyAbsVelocityImpulse(absoluteVelocity);
}

// Slowdown after landing
if (!IsAirborne() && m_iNeoClass != NEO_CLASS_RECON)
{
const float deltaTime = gpGlobals->curtime - m_flLastAirborneJumpOkTime;
const float leeway = 1.0f;
if (deltaTime < leeway)
const float timeSinceLanding = gpGlobals->curtime - m_flLastAirborneJumpOkTime;
constexpr float INITIAL_SLOWDOWN_TIME = 0.25f;
constexpr float IMPAIRED_ACCELERATION_TIME = INITIAL_SLOWDOWN_TIME + (1 / 3.f);
if (timeSinceLanding < INITIAL_SLOWDOWN_TIME)
{
speed = (speed / 2) + (deltaTime / 2 * (speed));
speed = MIN(speed, 75.f);
}
else if (timeSinceLanding < IMPAIRED_ACCELERATION_TIME)
{
speed *= timeSinceLanding / IMPAIRED_ACCELERATION_TIME;
}
}
SetMaxSpeed(MAX(speed, 56));
}

void CNEO_Player::PreThink(void)
{
BaseClass::PreThink();

if (!m_bInThermOpticCamo)
{
CloakPower_Update();
}

CalculateSpeed();

CheckThermOpticButtons();
CheckVisionButtons();
Expand Down
2 changes: 2 additions & 0 deletions mp/src/game/server/neo/neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class CNEO_Player : public CHL2MP_Player
virtual void Precache(void) OVERRIDE;
virtual void Spawn(void) OVERRIDE;
virtual void PostThink(void) OVERRIDE;
virtual void CalculateSpeed(void);
virtual void PreThink(void) OVERRIDE;
virtual void PlayerDeathThink(void) OVERRIDE;
virtual bool HandleCommand_JoinTeam(int team) OVERRIDE;
Expand Down Expand Up @@ -245,6 +246,7 @@ class CNEO_Player : public CHL2MP_Player
CNetworkVar(bool, m_bHasBeenAirborneForTooLongToSuperJump);
CNetworkVar(bool, m_bInAim);
CNetworkVar(int, m_bInLean);
CNetworkVar(bool, m_bCarryingGhost);
CNetworkVar(bool, m_bIneligibleForLoadoutPick);

CNetworkVar(float, m_flCamoAuxLastTime);
Expand Down
2 changes: 2 additions & 0 deletions mp/src/game/shared/neo/neo_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ void CNEORules::Think(void)
if ((playerTeam == TEAM_JINRAI || playerTeam == TEAM_NSF) && RespawnWithRet(player, false))
{
player->m_bInAim = false;
player->m_bCarryingGhost = false;
player->m_bInThermOpticCamo = false;
player->m_bInVision = false;
player->m_bIneligibleForLoadoutPick = false;
Expand Down Expand Up @@ -2026,6 +2027,7 @@ void CNEORules::StartNextRound()
pPlayer->Spawn();

pPlayer->m_bInAim = false;
pPlayer->m_bCarryingGhost = false;
pPlayer->m_bInThermOpticCamo = false;
pPlayer->m_bInVision = false;
pPlayer->m_bIneligibleForLoadoutPick = false;
Expand Down
2 changes: 2 additions & 0 deletions mp/src/game/shared/neo/neo_player_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ ConVar neo_aim_hold("neo_aim_hold", "0", FCVAR_USERINFO | FCVAR_ARCHIVE, "Hold t
ConVar neo_recon_superjump_intensity("neo_recon_superjump_intensity", "250", FCVAR_REPLICATED | FCVAR_CHEAT,
"Recon superjump intensity multiplier.", true, 1.0, false, 0);

ConVar neo_ghost_bhopping("neo_ghost_bhopping", "0", FCVAR_REPLICATED, "Allow ghost bunnyhopping", true, 0, true, 1);

bool IsAllowedToZoom(CNEOBaseCombatWeapon *pWep)
{
if (!pWep || pWep->m_bInReload || pWep->GetRoundBeingChambered())
Expand Down
7 changes: 7 additions & 0 deletions mp/src/game/shared/neo/weapons/weapon_ghost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ void CWeaponGhost::OnPickedUp(CBaseCombatCharacter *pNewOwner)
neoOwner->StopSprinting();
}

neoOwner->m_bCarryingGhost = true;

#ifdef GAME_DLL
CTeamRecipientFilter filter(NEORules()->GetOpposingTeam(neoOwner), true);
EmitSound_t params;
Expand All @@ -190,6 +192,11 @@ void CWeaponGhost::OnPickedUp(CBaseCombatCharacter *pNewOwner)

void CWeaponGhost::Drop(const Vector &vecVelocity)
{
if (GetOwner())
{
auto neoOwner = static_cast<CNEO_Player*>(GetOwner());
neoOwner->m_bCarryingGhost = false;
}
BaseClass::Drop(vecVelocity);
#if !defined( CLIENT_DLL )
SetRemoveable(false);
Expand Down
12 changes: 12 additions & 0 deletions mp/src/game/shared/neo/weapons/weapon_ghost.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ class CWeaponGhost : public CNEOBaseCombatWeapon

void TryGhostPing(float closestEnemy);
#endif
virtual void UpdateOnRemove() override
{
if (GetOwner())
{
auto neoPlayer = static_cast<CNEO_Player*>(GetPlayerOwner());
neoPlayer->m_bCarryingGhost = false;
}
#ifdef CLIENT_DLL
StopGhostSound();
#endif //CLIENT_DLL
BaseClass::UpdateOnRemove();
};

private:

Expand Down
Loading