From d4a6e1c6aa4da4e3735bb5ad44352a490737e5be Mon Sep 17 00:00:00 2001 From: Marcus Minhorst Date: Mon, 21 Jul 2025 22:45:32 -0400 Subject: [PATCH] Added rumble from world --- src/common/engine/m_haptics.cpp | 1 + src/playsim/p_map.cpp | 19 ++++++++++++++ src/playsim/p_mobj.cpp | 17 +++++++++++++ src/playsim/p_spec.cpp | 6 ++++- src/playsim/p_teleport.cpp | 7 ++++++ src/rendering/r_utility.cpp | 11 +++++++- wadsrc/static/menudef.txt | 1 + wadsrc/static/zscript/actors/actor.zs | 36 +++++++++++++++++++++++++++ 8 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/common/engine/m_haptics.cpp b/src/common/engine/m_haptics.cpp index 02be43b9e..c8a84b0cb 100644 --- a/src/common/engine/m_haptics.cpp +++ b/src/common/engine/m_haptics.cpp @@ -142,6 +142,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_action, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "allow haptic feedback for player doing things"); // CODE -------------------------------------------------------------------- diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index fcd748e53..d4095c530 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -1714,11 +1714,30 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch } if (thing->flags2 & MF2_PUSHABLE && !(tm.thing->flags2 & MF2_CANNOTPUSH)) { // Push thing + if (thing->lastpush != tm.PushTime) { thing->PlayPushSound(); thing->Vel += tm.thing->Vel.XY() * thing->pushfactor; thing->lastpush = tm.PushTime; + + if (tm.thing == players[consoleplayer].mo || tm.thing == players[consoleplayer].camera) + { + IFVIRTUALPTR(tm.thing, AActor, PlayerPushedSomethingMakeRumble) + { + VMValue params[1] = { thing }; + VMCall(func, params, 1, nullptr, 0); + } + } + else if (thing == players[consoleplayer].mo || thing == players[consoleplayer].camera) + { + // I assume the player can be pushed, correct? + IFVIRTUALPTR(thing, AActor, PlayerWasPushedMakeRumble) + { + VMValue params[1] = { tm.thing }; + VMCall(func, params, 1, nullptr, 0); + } + } } } solid = (thing->flags & MF_SOLID) && diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 10a4ed8ae..9af36f5a3 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -3272,6 +3272,22 @@ DEFINE_ACTION_FUNCTION(AActor, CheckFakeFloorTriggers) P_CheckFakeFloorTriggers(self, oldz, oldz_has_viewh); return 0; } + +//========================================================================== +// +// Rumble functions +// +//========================================================================== + +static void PlayerLandedMakeRumble(AActor* self, AActor *onmobj) +{ + IFVIRTUALPTR(self, AActor, PlayerLandedMakeRumble) + { + VMValue params[2] = { self, onmobj }; + VMCall(func, params, 2, nullptr, 0); + } +} + //=========================================================================== // // PlayerLandedOnThing @@ -3305,6 +3321,7 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj) P_FallingDamage (mo); + PlayerLandedMakeRumble(mo, onmobj); PlayerLandedMakeGruntSound(mo, onmobj); // mo->player->centering = true; diff --git a/src/playsim/p_spec.cpp b/src/playsim/p_spec.cpp index 21a7e56e0..04beabdc8 100644 --- a/src/playsim/p_spec.cpp +++ b/src/playsim/p_spec.cpp @@ -81,6 +81,7 @@ #include "g_levellocals.h" #include "gstrings.h" #include "i_soundinternal.h" +#include "m_joy.h" #include "m_random.h" #include "p_3dmidtex.h" #include "p_acs.h" @@ -97,6 +98,7 @@ static FRandom pr_actorinspecialsector ("ActorInSpecialSector"); EXTERN_CVAR(Bool, cl_predict_specials) EXTERN_CVAR(Bool, forcewater) +EXTERN_CVAR (Bool, haptics_do_world) // [RH] Check dmflags for noexit and respond accordingly bool FLevelLocals::CheckIfExitIsGood (AActor *self, level_info_t *info) @@ -210,6 +212,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVe P_ChangeSwitchTexture (line->sidedef[0], repeat, special); line->special = 0; } + // end of changed code if (developer >= DMSG_SPAMMY && buttonSuccess) { @@ -639,7 +642,8 @@ void P_GiveSecret(FLevelLocals *Level, AActor *actor, bool printmessage, bool pl Printf(PRINT_HIGH | PRINT_NONOTIFY, "Secret found in sector %d\n", sectornum); } } - if (playsound) S_Sound (CHAN_AUTO, CHANF_UI, "misc/secret", 1, ATTN_NORM); + if (playsound) + S_Sound (CHAN_AUTO, CHANF_UI|(haptics_do_world?CHANF_RUMBLE:CHANF_NORUMBLE), "misc/secret", 1, ATTN_NORM); } } Level->found_secrets++; diff --git a/src/playsim/p_teleport.cpp b/src/playsim/p_teleport.cpp index 6e39daef2..0c3b79786 100644 --- a/src/playsim/p_teleport.cpp +++ b/src/playsim/p_teleport.cpp @@ -190,6 +190,13 @@ bool P_Teleport (AActor *thing, DVector3 pos, DAngle angle, int flags) { player->mo->Angles.Pitch = nullAngle; } + if (player->mo == players[consoleplayer].mo || player->mo == players[consoleplayer].camera) + { + IFVIRTUALPTR(player->mo, AActor, PlayerTeleportedMakeRumble) + { + CallVM(func, player->mo); + } + } } if (!(flags & TELF_KEEPORIENTATION)) { diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index 4c3136211..c648f3caa 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -44,6 +44,7 @@ #include "i_interface.h" #include "i_time.h" #include "i_video.h" +#include "m_haptics.h" #include "m_random.h" #include "p_3dmidtex.h" #include "p_effect.h" @@ -64,6 +65,7 @@ const float MY_SQRT2 = float(1.41421356237309504880); // sqrt(2) extern bool DrawFSHUD; // [RH] Defined in d_main.cpp EXTERN_CVAR (Bool, cl_capfps) +EXTERN_CVAR (Bool, haptics_do_world) // TYPES ------------------------------------------------------------------- @@ -1040,8 +1042,15 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA if (!WorldPaused()) { FQuakeJiggers jiggers; - if (DEarthquake::StaticGetQuakeIntensities(viewPoint.TicFrac, viewPoint.camera, jiggers) > 0) + int intensity = DEarthquake::StaticGetQuakeIntensities(viewPoint.TicFrac, viewPoint.camera, jiggers); + if (intensity > 0) { + if (haptics_do_world) + { + // f(0)->1 f(9)->0 + Joy_Rumble("world/quake", (9.0-intensity)/9); + } + const double quakeFactor = r_quakeintensity; if (jiggers.RollIntensity || jiggers.RollWave) iView->AngleOffsets.Roll = DAngle::fromDeg(QuakePower(quakeFactor, jiggers.RollIntensity, jiggers.RollWave)); diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 9e4bbca99..cc5cfe1e4 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_WORLD", "haptics_do_world", "OnOff" } //------------------------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 3efe514b0..82d806199 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1717,6 +1717,21 @@ class Actor : Thinker native // //---------------------------------------------------------------------------- + virtual void PlayerLandedMakeRumble(actor onmobj) + { + if (!CVar.GetCVar("haptics_do_world").GetBool()) return; + + bool isliquid = (pos.Z <= floorz) && HitFloor (); + if (onmobj != NULL || !isliquid) + { + Haptics.Rumble("*land"); + } + else if (self.Vel.Z < -self.player.mo.GruntSpeed) + { + Haptics.Rumble("*grunt"); + } + } + virtual void PlayerUsedSomethingMakeRumble(int activationType, int levelNum, int lineNum, int lineSpecial) { if (!CVar.GetCVar("haptics_do_action").GetBool()) return; @@ -1724,6 +1739,27 @@ class Actor : Thinker native Haptics.Rumble("*usesuccess"); } + virtual void PlayerTeleportedMakeRumble() + { + if (!CVar.GetCVar("haptics_do_world").GetBool()) return; + + Haptics.Rumble("misc/teleport"); + } + + virtual void PlayerPushedSomethingMakeRumble(actor thing) + { + if (!CVar.GetCVar("haptics_do_world").GetBool()) return; + + Haptics.Rumble("misc/push"); + } + + virtual void PlayerWasPushedMakeRumble(actor source) + { + if (!CVar.GetCVar("haptics_do_world").GetBool()) return; + + Haptics.Rumble("misc/pushed"); + } + //---------------------------------------------------------------------------- // // PROC A_CheckSkullDone