Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 55 additions & 2 deletions src/game/shared/neo/weapons/weapon_neobasecombatweapon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,19 @@ void CNEOBaseCombatWeapon::Equip(CBaseCombatCharacter* pOwner)

bool CNEOBaseCombatWeapon::Reload( void )
{
// an empty weapon reloads with its slide held back until the release, where the model has that reload
if (UsesClipsForAmmo1() && m_iClip1 <= 0 && SelectWeightedSequence(ACT_VM_RELOAD_EMPTY) != ACTIVITY_NOT_AVAILABLE)
{
if (!DefaultReload(GetMaxClip1(), GetMaxClip2(), ACT_VM_RELOAD_EMPTY))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we have any weapons that benefit from this change? It might be a good idea regardless, but from what I can tell the tachi reload has the slide forward when reloading while empty

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's a fair point, and maybe for consistency, arguably the full animations need to be implemented for this to be cohesive.

This PR is the same idea but with a custom animation to fix the tachi slide back:

#2259

These are the differences between master and the two PRs:

case8c-slide-reload-tachi.mp4

{
return false;
}

// others see the reload, as for a reload with rounds left
ToHL2MPPlayer(GetOwner())->DoAnimationEvent(PLAYERANIMEVENT_RELOAD);
return true;
}

return BaseClass::Reload();

#if(0)
Expand Down Expand Up @@ -498,6 +511,16 @@ bool CNEOBaseCombatWeapon::Deploy(void)
AddEffects(EF_BONEMERGE);
m_bTriggerReset = true;

// An empty weapon draws with its slide held back where the model has that draw,
// which carries no activity, so it is picked by name
static constexpr const char *VM_SEQ_DRAW_EMPTY = "drawempty";
const int iDrawEmpty = (UsesClipsForAmmo1() && m_iClip1 <= 0) ? LookupSequence(VM_SEQ_DRAW_EMPTY) : ACTIVITY_NOT_AVAILABLE;
if (iDrawEmpty != ACTIVITY_NOT_AVAILABLE)
{
SetSequence(iDrawEmpty);
SendViewModelAnim(iDrawEmpty);
}

#ifdef DEBUG
CNEO_Player* pOwner = NULL;
if (GetOwner())
Expand Down Expand Up @@ -941,6 +964,22 @@ void CNEOBaseCombatWeapon::DryFire()
m_flNextPrimaryAttack = gpGlobals->curtime + GetFastestDryRefireTime(); // SequenceDuration();
}

// An empty weapon idles on its empty sequence where the model has one, such as a pistol with its slide held back
bool CNEOBaseCombatWeapon::SendWeaponAnim(int iActivity)
{
if (iActivity == ACT_VM_IDLE && UsesClipsForAmmo1() && m_iClip1 <= 0 && HasEmptyIdle())
{
iActivity = ACT_VM_IDLE_EMPTY;
}

return BaseClass::SendWeaponAnim(iActivity);
}

bool CNEOBaseCombatWeapon::HasEmptyIdle()
{
return SelectWeightedSequence(ACT_VM_IDLE_EMPTY) != ACTIVITY_NOT_AVAILABLE;
}

void CNEOBaseCombatWeapon::PrimaryAttack(void)
{
if (ShootingIsPrevented())
Expand Down Expand Up @@ -1019,8 +1058,6 @@ void CNEOBaseCombatWeapon::PrimaryAttack(void)
#endif // GAME_DLL
}

SendWeaponAnim(GetPrimaryAttackActivity());
SetWeaponIdleTime(gpGlobals->curtime + 2.0);
if (IsSemiAuto())
{
m_bTriggerReset = false;
Expand Down Expand Up @@ -1064,6 +1101,22 @@ void CNEOBaseCombatWeapon::PrimaryAttack(void)
m_iPrimaryAmmoCount -= info.m_iShots;
}

// the last round's shot locks a pistol's slide back:
// the pistols' dry fire sequence is a shot's kick with the slide held back,
static constexpr NEO_WEP_BITS_UNDERLYING_TYPE NEO_WEP_SLIDE_LOCK = NEO_WEP_MILSO | NEO_WEP_TACHI;
if (UsesClipsForAmmo1() && m_iClip1 <= 0 && (GetNeoWepBits() & NEO_WEP_SLIDE_LOCK))
{
SendWeaponAnim(ACT_VM_DRYFIRE);
}
else
{
SendWeaponAnim(GetPrimaryAttackActivity());
}

// and goes straight on to the empty idle when it ends
const bool bEmptyIdleNext = UsesClipsForAmmo1() && m_iClip1 <= 0 && HasEmptyIdle();
SetWeaponIdleTime(gpGlobals->curtime + (bEmptyIdleNext ? SequenceDuration() : 2.0));

info.m_flDistance = MAX_TRACE_LENGTH;
info.m_iAmmoType = m_iPrimaryAmmoType;
info.m_iTracerFreq = UsesTracers() ? 1 : 0;
Expand Down
2 changes: 2 additions & 0 deletions src/game/shared/neo/weapons/weapon_neobasecombatweapon.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ class CNEOBaseCombatWeapon : public CBaseHL2MPCombatWeapon
#endif

virtual void DryFire(void);
virtual bool SendWeaponAnim(int iActivity) override;

virtual Activity GetPrimaryAttackActivity(void) override;
#ifdef CLIENT_DLL
Expand Down Expand Up @@ -292,6 +293,7 @@ class CNEOBaseCombatWeapon : public CBaseHL2MPCombatWeapon

private:
CNEOBaseCombatWeapon(const CNEOBaseCombatWeapon &other);
bool HasEmptyIdle();

};

Expand Down
Loading