From 8f1cd280414d5989a1b14f51e6ffbe9cd2b76da9 Mon Sep 17 00:00:00 2001 From: Thor Hanson Date: Thu, 3 Feb 2022 19:51:06 -0600 Subject: [PATCH] Plumb method for ejecting brass; add ejecting shotgun casings Break out ejecting brass into a dedicated method. Trigger this method after every shot. Add in appropriate delay so that shotgun casings are ejected during the pump action rather than when the shot is fired. --- Sources/Client/Client.h | 1 + Sources/Client/ClientPlayer.cpp | 67 +++++++++++++++++--------------- Sources/Client/ClientPlayer.h | 1 + Sources/Client/Client_Update.cpp | 7 ++++ Sources/Client/IWorldListener.h | 1 + Sources/Client/Weapon.cpp | 14 +++++++ Sources/Client/Weapon.h | 5 +++ 7 files changed, 65 insertions(+), 31 deletions(-) diff --git a/Sources/Client/Client.h b/Sources/Client/Client.h index ba3760e0a..e64ccfffd 100644 --- a/Sources/Client/Client.h +++ b/Sources/Client/Client.h @@ -463,6 +463,7 @@ namespace spades { void PlayerJumped(Player &) override; void PlayerLanded(Player &, bool hurt) override; void PlayerFiredWeapon(Player &) override; + void PlayerEjectedBrass(Player &) override; void PlayerDryFiredWeapon(Player &) override; void PlayerReloadingWeapon(Player &) override; void PlayerReloadedWeapon(Player &) override; diff --git a/Sources/Client/ClientPlayer.cpp b/Sources/Client/ClientPlayer.cpp index d50c3abc0..03046b07e 100644 --- a/Sources/Client/ClientPlayer.cpp +++ b/Sources/Client/ClientPlayer.cpp @@ -1293,6 +1293,41 @@ namespace spades { // make dlight client.MuzzleFire(muzzle, player.GetFront(), &player == world.GetLocalPlayer()); + // sound ambience estimation + auto ambience = ComputeAmbience(); + + asIScriptObject *skin; + // FIXME: what if current tool isn't weapon? + if (ShouldRenderInThirdPersonView()) { + skin = weaponSkin; + } else { + skin = weaponViewSkin; + } + + { + ScriptIWeaponSkin2 interface(skin); + if (interface.ImplementsInterface()) { + interface.SetSoundEnvironment(ambience.room, ambience.size, ambience.distance); + interface.SetSoundOrigin(player.GetEye()); + } else if (ShouldRenderInThirdPersonView() && !hasValidOriginMatrix) { + // Legacy skin scripts rely on OriginMatrix which is only updated when + // the player's location is within the fog range. + return; + } + } + + { + ScriptIWeaponSkin interface(skin); + interface.WeaponFired(); + } + } + + void ClientPlayer::EjectedBrass() { + const SceneDefinition &lastSceneDef = client.GetLastSceneDef(); + IRenderer &renderer = client.GetRenderer(); + IAudioDevice &audioDevice = client.GetAudioDevice(); + Player &p = player; + if (cg_ejectBrass) { float dist = (player.GetOrigin() - lastSceneDef.viewOrigin).GetPoweredLength(); if (dist < 130.f * 130.f) { @@ -1310,9 +1345,7 @@ namespace spades { audioDevice.RegisterSound("Sounds/Weapons/Rifle/ShellWater.opus"); break; case SHOTGUN_WEAPON: - // FIXME: don't want to show shotgun't casing - // because it isn't ejected when firing - // model = renderer.RegisterModel("Models/Weapons/Shotgun/Casing.kv6"); + model = renderer.RegisterModel("Models/Weapons/Shotgun/Casing.kv6"); break; case SMG_WEAPON: model = renderer.RegisterModel("Models/Weapons/SMG/Casing.kv6"); @@ -1348,34 +1381,6 @@ namespace spades { } } } - - // sound ambience estimation - auto ambience = ComputeAmbience(); - - asIScriptObject *skin; - // FIXME: what if current tool isn't weapon? - if (ShouldRenderInThirdPersonView()) { - skin = weaponSkin; - } else { - skin = weaponViewSkin; - } - - { - ScriptIWeaponSkin2 interface(skin); - if (interface.ImplementsInterface()) { - interface.SetSoundEnvironment(ambience.room, ambience.size, ambience.distance); - interface.SetSoundOrigin(player.GetEye()); - } else if (ShouldRenderInThirdPersonView() && !hasValidOriginMatrix) { - // Legacy skin scripts rely on OriginMatrix which is only updated when - // the player's location is within the fog range. - return; - } - } - - { - ScriptIWeaponSkin interface(skin); - interface.WeaponFired(); - } } void ClientPlayer::ReloadingWeapon() { diff --git a/Sources/Client/ClientPlayer.h b/Sources/Client/ClientPlayer.h index cb29bfa13..6739fbfe3 100644 --- a/Sources/Client/ClientPlayer.h +++ b/Sources/Client/ClientPlayer.h @@ -106,6 +106,7 @@ namespace spades { bool IsChangingTool(); void FiredWeapon(); + void EjectedBrass(); void ReloadingWeapon(); void ReloadedWeapon(); diff --git a/Sources/Client/Client_Update.cpp b/Sources/Client/Client_Update.cpp index 0107c5e6d..6a729fcfd 100644 --- a/Sources/Client/Client_Update.cpp +++ b/Sources/Client/Client_Update.cpp @@ -639,6 +639,13 @@ namespace spades { clientPlayers.at(p.GetId())->FiredWeapon(); } + + void Client::PlayerEjectedBrass(spades::client::Player &p) { + SPADES_MARK_FUNCTION(); + + clientPlayers.at(p.GetId())->EjectedBrass(); + } + void Client::PlayerDryFiredWeapon(spades::client::Player &p) { SPADES_MARK_FUNCTION(); diff --git a/Sources/Client/IWorldListener.h b/Sources/Client/IWorldListener.h index e762219f3..7c3b58235 100644 --- a/Sources/Client/IWorldListener.h +++ b/Sources/Client/IWorldListener.h @@ -48,6 +48,7 @@ namespace spades { virtual void PlayerJumped(Player &) = 0; virtual void PlayerLanded(Player &, bool hurt) = 0; virtual void PlayerFiredWeapon(Player &) = 0; + virtual void PlayerEjectedBrass(Player &) = 0; virtual void PlayerDryFiredWeapon(Player &) = 0; virtual void PlayerReloadingWeapon(Player &) = 0; virtual void PlayerReloadedWeapon(Player &) = 0; diff --git a/Sources/Client/Weapon.cpp b/Sources/Client/Weapon.cpp index 6c14582b7..d5ac22b86 100644 --- a/Sources/Client/Weapon.cpp +++ b/Sources/Client/Weapon.cpp @@ -35,6 +35,7 @@ namespace spades { shooting(false), shootingPreviously(false), reloading(false), + unejectedBrass(false), nextShotTime(0.f), reloadStartTime(-101.f), reloadEndTime(-100.f), @@ -58,6 +59,8 @@ namespace spades { void Weapon::SetShooting(bool b) { shooting = b; } + void Weapon::SetUnejectedBrass(bool b) { unejectedBrass = b; } + bool Weapon::IsReadyToShoot() { return (ammo > 0 || !owner.IsLocalPlayer()) && time >= nextShotTime && (!reloading || IsReloadSlow()); @@ -87,6 +90,7 @@ namespace spades { // Automatic operation of weapon. if (time >= nextShotTime && (ammo > 0 || !ownerIsLocalPlayer)) { fired = true; + unejectedBrass = true; // Consume an ammo. if (ammo > 0) { @@ -97,6 +101,7 @@ namespace spades { world.GetListener()->PlayerFiredWeapon(owner); } nextShotTime += GetDelay(); + ejectBrassTime = time + GetEjectBrassTime(); } else if (time >= nextShotTime) { dryFire = true; } @@ -138,6 +143,9 @@ namespace spades { world.GetListener()->PlayerReloadedWeapon(owner); } } + } else if (unejectedBrass && time >= ejectBrassTime) { + unejectedBrass = false; + world.GetListener()->PlayerEjectedBrass(owner); } time += dt; @@ -205,6 +213,7 @@ namespace spades { int GetClipSize() override { return 10; } int GetMaxStock() override { return 50; } float GetReloadTime() override { return 2.5f; } + float GetEjectBrassTime() override { return 0.f; } bool IsReloadSlow() override { return false; } WeaponType GetWeaponType() override { return RIFLE_WEAPON; } int GetDamage(HitType type, float distance) override { @@ -232,6 +241,7 @@ namespace spades { int GetClipSize() override { return 30; } int GetMaxStock() override { return 120; } float GetReloadTime() override { return 2.5f; } + float GetEjectBrassTime() override { return 0.f; } bool IsReloadSlow() override { return false; } WeaponType GetWeaponType() override { return SMG_WEAPON; } int GetDamage(HitType type, float distance) override { @@ -259,6 +269,7 @@ namespace spades { int GetClipSize() override { return 6; } int GetMaxStock() override { return 48; } float GetReloadTime() override { return 0.5f; } + float GetEjectBrassTime() override { return 0.6f; } bool IsReloadSlow() override { return true; } WeaponType GetWeaponType() override { return SHOTGUN_WEAPON; } int GetDamage(HitType type, float distance) override { @@ -289,6 +300,7 @@ namespace spades { int GetClipSize() override { return 8; } int GetMaxStock() override { return 48; } float GetReloadTime() override { return 2.5f; } + float GetEjectBrassTime() override { return 0.f; } bool IsReloadSlow() override { return false; } WeaponType GetWeaponType() override { return RIFLE_WEAPON; } int GetDamage(HitType type, float distance) override { @@ -321,6 +333,7 @@ namespace spades { int GetClipSize() override { return 30; } int GetMaxStock() override { return 150; } float GetReloadTime() override { return 2.5f; } + float GetEjectBrassTime() override { return 0.f; } bool IsReloadSlow() override { return false; } WeaponType GetWeaponType() override { return SMG_WEAPON; } int GetDamage(HitType type, float distance) override { @@ -348,6 +361,7 @@ namespace spades { int GetClipSize() override { return 8; } int GetMaxStock() override { return 48; } float GetReloadTime() override { return 0.4f; } + float GetEjectBrassTime() override { return 0.6f; } bool IsReloadSlow() override { return true; } WeaponType GetWeaponType() override { return SHOTGUN_WEAPON; } int GetDamage(HitType type, float distance) override { diff --git a/Sources/Client/Weapon.h b/Sources/Client/Weapon.h index ec8eb9091..15d880ad0 100644 --- a/Sources/Client/Weapon.h +++ b/Sources/Client/Weapon.h @@ -37,7 +37,9 @@ namespace spades { bool shooting; bool shootingPreviously; bool reloading; + bool unejectedBrass; float nextShotTime; + float ejectBrassTime; float reloadStartTime; float reloadEndTime; @@ -56,6 +58,7 @@ namespace spades { virtual int GetClipSize() = 0; virtual int GetMaxStock() = 0; virtual float GetReloadTime() = 0; + virtual float GetEjectBrassTime() = 0; virtual bool IsReloadSlow() = 0; virtual int GetDamage(HitType, float distance) = 0; virtual WeaponType GetWeaponType() = 0; @@ -70,6 +73,7 @@ namespace spades { void Restock(); void Reset(); void SetShooting(bool); + void SetUnejectedBrass(bool); /** @return true when fired. */ bool FrameNext(float); @@ -82,6 +86,7 @@ namespace spades { bool IsShooting() const { return shooting; } bool IsReloading() const { return reloading; } + bool IsUnejectedBrass() const { return unejectedBrass; } int GetAmmo() { return ammo; } int GetStock() { return stock; }