diff --git a/src/common/engine/m_haptics.cpp b/src/common/engine/m_haptics.cpp index c8a84b0cb..8315ab95e 100644 --- a/src/common/engine/m_haptics.cpp +++ b/src/common/engine/m_haptics.cpp @@ -143,6 +143,7 @@ CUSTOM_CVARD(Int, haptics_compat, HAPTCOMPAT_MATCH, CVAR_ARCHIVE | CVAR_GLOBALCO CVARD(Bool, haptics_do_menus, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "allow haptic feedback for menus"); CVARD(Bool, haptics_do_world, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "allow haptic feedback for things acting on player"); +CVARD(Bool, haptics_do_damage, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "allow haptic feedback for things hurting player"); CVARD(Bool, haptics_do_action, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "allow haptic feedback for player doing things"); // CODE -------------------------------------------------------------------- diff --git a/src/playsim/p_enemy.cpp b/src/playsim/p_enemy.cpp index 209a7bccf..91a861768 100644 --- a/src/playsim/p_enemy.cpp +++ b/src/playsim/p_enemy.cpp @@ -3214,7 +3214,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_Pain) sfx_id = S_FindSound(pain_amount); } - S_Sound (self, CHAN_VOICE, 0, sfx_id, 1, ATTN_NORM); + IFVIRTUALPTR(self, AActor, PlayerHurtMakeRumble) + { + VMValue params[2] = { self, self->player->attacker.Get() }; + VMCall(func, params, 2, nullptr, 0); + } + + S_Sound (self, CHAN_VOICE, CHANF_NORUMBLE, sfx_id, 1, ATTN_NORM); } else if (self->PainSound.isvalid()) { diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 9af36f5a3..b9268e3be 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -3288,6 +3288,15 @@ static void PlayerLandedMakeRumble(AActor* self, AActor *onmobj) } } +static void PlayerDiedMakeRumble(AActor* self, AActor *source) +{ + IFVIRTUALPTR(self, AActor, PlayerDiedMakeRumble) + { + VMValue params[2] = { self, source }; + VMCall(func, params, 2, nullptr, 0); + } +} + //=========================================================================== // // PlayerLandedOnThing @@ -7723,7 +7732,7 @@ AActor *P_SpawnMissileXYZ (DVector3 pos, AActor *source, AActor *dest, PClassAct } AActor *th = Spawn (source->Level, type, pos, ALLOW_REPLACE); - + // record missile's originator if (owner == NULL) owner = source; th->target = owner; diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index 34d481f26..0bcf52fd7 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -968,11 +968,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream) { if (self->DeathSound != NO_SOUND) { - S_Sound (self, CHAN_VOICE, 0, self->DeathSound, 1, ATTN_NORM); + S_Sound (self, CHAN_VOICE, CHANF_NORUMBLE, self->DeathSound, 1, ATTN_NORM); } else { - S_Sound (self, CHAN_VOICE, 0, "*death", 1, ATTN_NORM); + S_Sound (self, CHAN_VOICE, CHANF_NORUMBLE, "*death", 1, ATTN_NORM); } return 0; } @@ -1022,7 +1022,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream) } } } - S_Sound (self, chan, 0, sound, 1, ATTN_NORM); + S_Sound (self, chan, CHANF_NORUMBLE, sound, 1, ATTN_NORM); return 0; } diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index cc5cfe1e4..96a4a039d 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1264,6 +1264,7 @@ OptionMenu "HapticsOptions" protected StaticText "$HAPMNU_OPTIONS" Option "$HAPMNU_OPT_MENU", "haptics_do_menus", "OnOff" Option "$HAPMNU_OPT_ACTION", "haptics_do_action", "OnOff" + Option "$HAPMNU_OPT_DAMAGE", "haptics_do_damage", "OnOff" Option "$HAPMNU_OPT_WORLD", "haptics_do_world", "OnOff" } diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 82d806199..a3a34a963 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1635,23 +1635,23 @@ class Actor : Thinker native { if (DeathSound) { - A_StartSound(DeathSound, CHAN_VOICE, CHANF_DEFAULT, 1, bBoss || bFullvolDeath? ATTN_NONE : ATTN_NORM); + A_StartSound(DeathSound, CHAN_VOICE, CHANF_DEFAULT|CHANF_NORUMBLE, 1, bBoss || bFullvolDeath? ATTN_NONE : ATTN_NORM); } } void A_XScream() { - A_StartSound(player? Sound("*gibbed") : Sound("misc/gibbed"), CHAN_VOICE); + A_StartSound(player? Sound("*gibbed") : Sound("misc/gibbed"), CHAN_VOICE, CHANF_NORUMBLE); } void A_ActiveSound() { if (ActiveSound) { - A_StartSound(ActiveSound, CHAN_VOICE); + A_StartSound(ActiveSound, CHAN_VOICE, CHANF_NORUMBLE); } } - + virtual void PlayerLandedMakeGruntSound(actor onmobj) { bool grunted; @@ -1663,7 +1663,7 @@ class Actor : Thinker native // Why should this number vary by gravity? if (self.Vel.Z < -self.player.mo.GruntSpeed) { - A_StartSound("*grunt", CHAN_VOICE); + A_StartSound("*grunt", CHAN_VOICE, CHANF_NORUMBLE); grunted = true; } bool isliquid = (pos.Z <= floorz) && HitFloor (); @@ -1671,11 +1671,11 @@ class Actor : Thinker native { if (!grunted) { - A_StartSound("*land", CHAN_AUTO); + A_StartSound("*land", CHAN_AUTO, CHANF_NORUMBLE); } else { - A_StartSoundIfNotSame("*land", "*grunt", CHAN_AUTO); + A_StartSoundIfNotSame("*land", "*grunt", CHAN_AUTO, CHANF_NORUMBLE); } } } @@ -1697,7 +1697,7 @@ class Actor : Thinker native if (oldlevel < 3 && WaterLevel == 3) { // Our head just went under. - A_StartSound("*dive", CHAN_VOICE, attenuation: ATTN_NORM); + A_StartSound("*dive", CHAN_VOICE, CHANF_NORUMBLE, attenuation: ATTN_NORM); } else if (oldlevel == 3 && WaterLevel < 3) { @@ -1705,7 +1705,7 @@ class Actor : Thinker native if (player.air_finished > Level.maptime) { // We hadn't run out of air yet. - A_StartSound("*surface", CHAN_VOICE, attenuation: ATTN_NORM); + A_StartSound("*surface", CHAN_VOICE, CHANF_NORUMBLE, attenuation: ATTN_NORM); } // If we were running out of air, then ResetAirSupply() will play *gasp. } @@ -1732,6 +1732,20 @@ class Actor : Thinker native } } + virtual void PlayerHurtMakeRumble(actor source) + { + if (!CVar.GetCVar("haptics_do_damage").GetBool()) return; + + Haptics.Rumble("*pain"); + } + + virtual void PlayerDiedMakeRumble(actor source) + { + if (!CVar.GetCVar("haptics_do_damage").GetBool()) return; + + Haptics.Rumble("*death"); + } + virtual void PlayerUsedSomethingMakeRumble(int activationType, int levelNum, int lineNum, int lineSpecial) { if (!CVar.GetCVar("haptics_do_action").GetBool()) return; diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index c32116b1e..152be9b72 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -835,6 +835,8 @@ class PlayerPawn : Actor { Super.Die (source, inflictor, dmgflags, MeansOfDeath); + if (player.mo == self) Super.PlayerDiedMakeRumble(inflictor); + if (player != NULL && player.mo == self) player.bonuscount = 0; // [RL0] To allow voodoo zombies, don't kill the player together with voodoo dolls if the compat flag is enabled