using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; using UnityEngine; using tact_csharp2; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("GameAssembly")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SuperBattleGolf_Haptics")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+726cb261100fb3ff66bc2b2beaa4654feecddd38")] [assembly: AssemblyProduct("Super Battle Golf bHaptics integration")] [assembly: AssemblyTitle("SuperBattleGolf_Haptics")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SBG.Haptics { [HarmonyPatch(typeof(MainMenu))] public class MenuPatches { [HarmonyPatch("OnIntroMenuShown")] [HarmonyPostfix] public static void Postfix() { BhapticsSDK2Wrapper.play("gamestart"); } } [HarmonyPatch(typeof(PlayerInfo))] public class PlayerInfoPatches { [HarmonyPatch("UserCode_RpcInformOfBlownAirhorn__PlayerInventory")] [HarmonyPostfix] public static void PostfixAirhornAffected() { BhapticsSDK2Wrapper.playParam("airhorn", 1, 1f, 1f, 0f, 0f); } [HarmonyPatch("UserCode_RpcInformPickedUpItemFromItemSpawner")] [HarmonyPostfix] public static void PostfixItemPickup() { BhapticsSDK2Wrapper.playParam("lightinteract", 1, 0.75f, 1f, 0f, 0f); } } [HarmonyPatch(typeof(PlayerGolfer))] public class GolferPatches { [HarmonyPatch("UpdateSwingNormalizedPower")] [HarmonyPostfix] public static void PostfixOvercharge(PlayerGolfer __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { bool flag = __instance.IsChargingSwing && __instance.SwingNormalizedCharge > 1f; if (flag && !HapticsPlugin.IsOverchargeLoopPlaying) { BhapticsSDK2Wrapper.playLoop("overcharge", 1, 1f, 1f, 0f, 0f, 200, 999999); HapticsPlugin.IsOverchargeLoopPlaying = true; } else if (!flag && HapticsPlugin.IsOverchargeLoopPlaying) { BhapticsSDK2Wrapper.stopByEventId("overcharge"); HapticsPlugin.IsOverchargeLoopPlaying = false; } } } [HarmonyPatch("ClearOverchargedVfx")] [HarmonyPostfix] public static void PostfixClearOverchargeVfx(PlayerGolfer __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { StopOvercharge(); } } private static void StopOvercharge() { if (HapticsPlugin.IsOverchargeLoopPlaying) { BhapticsSDK2Wrapper.stopByEventId("overcharge"); HapticsPlugin.IsOverchargeLoopPlaying = false; } } [HarmonyPatch("InformScored")] [HarmonyPostfix] public static void PostfixScored(PlayerGolfer __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.playParam("holein", 1, 1f, 2f, 0f, 0f); } } [HarmonyPatch("UserCode_RpcInformWillBeEliminated__EliminationReason__Vector3")] [HarmonyPostfix] public static void PostfixEliminated(EliminationReason immediateEliminationReason) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (immediateEliminationReason - 24 <= 1) { BhapticsSDK2Wrapper.playParam("bigexplode", 0, 1f, 0.5f, 0f, 0f); } } } [HarmonyPatch(typeof(PlayerInventory))] public class PlayerInventoryPatches { [HarmonyPatch("TrySelectItemSlot")] [HarmonyPostfix] public static void PostfixSelectItemSlot(PlayerInventory __instance, bool __result) { if (__result) { BhapticsSDK2Wrapper.playParam("lightinteract", 1, 0.75f, 1f, 0f, 0f); } } [HarmonyPatch("TryDeselectItem")] [HarmonyPostfix] public static void PostfixDeselectItem(PlayerInventory __instance, bool __result) { if (__result) { BhapticsSDK2Wrapper.playParam("lightinteract", 1, 0.45f, 1f, 0f, 0f); } } [HarmonyPatch("OnActivatedElectromagnet")] [HarmonyPostfix] public static void PostfixMagnetActivated(PlayerInventory __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.playParam("magnet", 1, 1f, 0.5f, 0f, 0f); } } [HarmonyPatch("OnActivatedOrbitalLaser")] [HarmonyPostfix] public static void PostfixOrbitalLaser(PlayerInventory __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.play("orbitallaseruse"); } } } [HarmonyPatch(typeof(PlayerAudio))] public class PlayerAudioPatches { [HarmonyPatch("PlaySwingHitForAllClients")] [HarmonyPostfix] public static void PostfixSwingHit(PlayerAudio __instance, Hittable hitHittable, bool fromRocketDriver) { PlayerInfo component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null) && ((NetworkBehaviour)component).isLocalPlayer) { BhapticsSDK2Wrapper.stopByEventId("overcharge"); HapticsPlugin.IsOverchargeLoopPlaying = false; PlayerGolfer asGolfer = component.AsGolfer; if (!((Object)(object)asGolfer == (Object)null)) { float swingNormalizedPower = asGolfer.SwingNormalizedPower; BhapticsSDK2Wrapper.playParam("golfhit", 0, swingNormalizedPower, 1f, 0f, 0f); } } } [HarmonyPatch("PlayElephantGunShotForAllClients")] [HarmonyPostfix] public static void PostfixElephantGunShot(PlayerAudio __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.play("elephantgun"); } } [HarmonyPatch("PlayPistolShotForAllClients")] [HarmonyPostfix] public static void PostfixPistolShot(PlayerAudio __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.play("pistol"); } } [HarmonyPatch("PlayFreezeBombShotForAllClients")] [HarmonyPostfix] public static void PostfixFreezeBombShot(PlayerAudio __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.play("iceshot"); } } [HarmonyPatch("PlayItemUseForAllClients")] [HarmonyPostfix] public static void PostfixItemUse(PlayerAudio __instance, ItemType itemType) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if (!((NetworkBehaviour)__instance).isLocalPlayer) { return; } if ((int)itemType != 1) { if ((int)itemType != 4) { if ((int)itemType == 6) { BhapticsSDK2Wrapper.playParam("carthonk", 1, 0.5f, 0.5f, 0f, 0f); } } else { BhapticsSDK2Wrapper.playParam("airhorn", 1, 1f, 0.5f, 0f, 0f); } } else { BhapticsSDK2Wrapper.play("coffee"); } } [HarmonyPatch("PlayRocketLauncherShotForAllClients")] [HarmonyPostfix] public static void PostfixRocketLauncherShot(PlayerAudio __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.play("rocketlauncher"); } } [HarmonyPatch("PlayLandminePlantForAllClients")] [HarmonyPostfix] public static void PostfixLandminePlant(PlayerAudio __instance, bool stomp) { if (((NetworkBehaviour)__instance).isLocalPlayer) { if (stomp) { BhapticsSDK2Wrapper.play("minestomp"); } else { BhapticsSDK2Wrapper.play("mineplant"); } } } } [HarmonyPatch(typeof(PlayerMovement))] public class PlayerMovementPatches { public static bool _wasGrounded = false; private static bool _hasPlayedDiveLand = false; private static DivingState _previousDivingState = (DivingState)0; private static double _lastCollisionTime = double.MinValue; [HarmonyPatch("TriggerJumpInternal")] [HarmonyPostfix] public static void PostfixJump(PlayerMovement __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { _hasPlayedDiveLand = false; BhapticsSDK2Wrapper.playParam("jump", 1, 0.3f, 1f, 0f, 0f); } } [HarmonyPatch("UpdateGroundingState")] [HarmonyPostfix] public static void PostfixGrounding(PlayerMovement __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { bool isGrounded = __instance.IsGrounded; if (isGrounded && !_wasGrounded && !_hasPlayedDiveLand) { BhapticsSDK2Wrapper.playParam("land", 1, 0.3f, 1f, 0f, 0f); } _wasGrounded = isGrounded; } } [HarmonyPatch("SetDivingState")] [HarmonyPostfix] public static void PostfixDiveGrounded(PlayerMovement __instance, DivingState state) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)__instance).isLocalPlayer) { if ((int)state == 1 && (int)_previousDivingState != 1) { _hasPlayedDiveLand = false; BhapticsSDK2Wrapper.play("jump"); } else if ((int)state == 2 && (int)_previousDivingState != 2) { BhapticsSDK2Wrapper.playParam("land", 1, 0.75f, 1f, 0f, 0f); _hasPlayedDiveLand = true; } _previousDivingState = state; } } [HarmonyPatch("PlayRespawnEffectsInternal")] [HarmonyPostfix] public static void PostfixRespawn(PlayerMovement __instance) { if (((NetworkBehaviour)__instance).isLocalPlayer) { BhapticsSDK2Wrapper.playParam("spawn", 1, 1f, 2.1f, 0f, 0f); } } [HarmonyPatch("OnCollisionEnter")] [HarmonyPostfix] public static void PostfixCollision(PlayerMovement __instance, Collision collision) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)__instance).isLocalPlayer && (__instance.IsKnockedOut || __instance.PlayerInfo.AsHittable.IsFrozen) && collision.contactCount > 0 && !((double)BMath.GetTimeSince(_lastCollisionTime) < 0.3)) { Vector3 relativeVelocity = collision.relativeVelocity; float magnitude = ((Vector3)(ref relativeVelocity)).magnitude; if (!(magnitude < 5f)) { float intensity = Mathf.Clamp01(Mathf.InverseLerp(5f, 25f, magnitude)); BhapticsSDK2Wrapper.playParam("playercollision", 0, intensity, 1f, 0f, 0f); _lastCollisionTime = Time.timeAsDouble; } } } [HarmonyPatch("OnLocalPlayerWillApplyItemHitPhysics")] [HarmonyPostfix] public static void PostfixItemHit(ItemType itemType) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected I4, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 if (GameManager.LocalPlayerInfo.isElectromagnetShieldActive && (int)itemType != 10) { BhapticsSDK2Wrapper.play("shieldhit"); return; } switch (itemType - 2) { default: if ((int)itemType != 12) { break; } BhapticsSDK2Wrapper.playParam("frozen", 0, 0.25f, 1f, 0f, 0f); return; case 5: case 6: BhapticsSDK2Wrapper.play("smallexplode"); return; case 1: BhapticsSDK2Wrapper.playParam("shot", 0, 1f, 1f, 0f, 0f); return; case 0: BhapticsSDK2Wrapper.playParam("shot", 0, 1f, 0.5f, 0f, 0f); return; case 2: case 3: case 4: break; } BhapticsSDK2Wrapper.play("hit"); } } [HarmonyPatch(typeof(GolfCartInfo))] public class GolfCartHonkPatches { [HarmonyPatch("PlayHonkForAllClients")] [HarmonyPostfix] public static void PostfixHonk(GolfCartInfo __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) PlayerInfo localPlayerInfo = GameManager.LocalPlayerInfo; if (!((Object)(object)localPlayerInfo == (Object)null) && !((Object)(object)localPlayerInfo.ActiveGolfCartSeat.golfCart != (Object)(object)__instance) && localPlayerInfo.ActiveGolfCartSeat.seat == 0) { BhapticsSDK2Wrapper.playParam("carthonk", 1, 0.5f, 0.5f, 0f, 0f); } } } [HarmonyPatch(typeof(GolfCartMovement))] public class GolfCartCollisionPatches { private const float velocityThreshold = 2f; [HarmonyPatch("OnCollisionEnter")] [HarmonyPostfix] public static void PostfixCollision(GolfCartMovement __instance, Collision collision) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) PlayerInfo localPlayerInfo = GameManager.LocalPlayerInfo; if ((Object)(object)localPlayerInfo == (Object)null) { return; } GolfCartInfo golfCart = localPlayerInfo.ActiveGolfCartSeat.golfCart; if (!((Object)(object)golfCart == (Object)null) && !((Object)(object)((Component)golfCart).GetComponent() != (Object)(object)__instance)) { Vector3 relativeVelocity = collision.relativeVelocity; float magnitude = ((Vector3)(ref relativeVelocity)).magnitude; if (!(magnitude < 2f)) { float intensity = Mathf.Clamp01(Mathf.InverseLerp(2f, 20f, magnitude)); BhapticsSDK2Wrapper.playParam("cartcollision", 0, intensity, 1f, 0f, 0f); } } } [HarmonyPatch("TryTriggerJump")] [HarmonyPostfix] public static void PostfixCartJump(GolfCartMovement __instance, bool __result) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (!__result) { return; } PlayerInfo localPlayerInfo = GameManager.LocalPlayerInfo; if (!((Object)(object)localPlayerInfo == (Object)null)) { GolfCartInfo golfCart = localPlayerInfo.ActiveGolfCartSeat.golfCart; if (!((Object)(object)golfCart == (Object)null) && !((Object)(object)((Component)golfCart).GetComponent() != (Object)(object)__instance)) { BhapticsSDK2Wrapper.play("jump"); } } } } [HarmonyPatch(typeof(JumpPad))] public class JumpPadPatches { [HarmonyPatch("TryApplyJumpInternal")] [HarmonyPostfix] public static void PostfixJumpPad(Hittable hittable) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)hittable).isOwned) { if (!PlayerMovementPatches._wasGrounded) { BhapticsSDK2Wrapper.playParam("land", 1, 0.75f, 1f, 0f, 0f); } BhapticsSDK2Wrapper.play("jump"); return; } PlayerGolfer localPlayerAsGolfer = GameManager.LocalPlayerAsGolfer; PlayerInfo val = ((localPlayerAsGolfer != null) ? ((Component)localPlayerAsGolfer).GetComponent() : null); if (!((Object)(object)val == (Object)null)) { GolfCartInfo golfCart = val.ActiveGolfCartSeat.golfCart; if (!((Object)(object)golfCart == (Object)null) && (Object)(object)golfCart.AsEntity.AsHittable == (Object)(object)hittable) { BhapticsSDK2Wrapper.play("jump"); } } } } [HarmonyPatch(typeof(Checkpoint))] public class CheckpointPatches { [HarmonyPatch("SetIsVisuallyActive")] [HarmonyPostfix] public static void PostfixActivated(Checkpoint __instance, bool isActive, bool suppressEffects) { Checkpoint val = default(Checkpoint); if (!(!isActive || suppressEffects) && CheckpointManager.TryGetLocalPlayerActiveCheckpoint(ref val) && !((Object)(object)val != (Object)(object)__instance)) { BhapticsSDK2Wrapper.play("checkpoint"); } } } [HarmonyPatch(typeof(UiSfx))] public class UiSfxPatches { private static readonly MethodInfo ShouldSupressSfx = AccessTools.Method(typeof(UiSfx), "ShouldSupressSfx", (Type[])null, (Type[])null); [HarmonyPatch("OnPointerEnter")] [HarmonyPostfix] public static void PostfixHover(UiSfx __instance) { if (!IsSuppressed(__instance)) { BhapticsSDK2Wrapper.playParam("lightinteract", 1, 0.3f, 1f, 0f, 0f); } } [HarmonyPatch("OnPointerClick")] [HarmonyPostfix] public static void PostfixClick(UiSfx __instance) { if (!IsSuppressed(__instance)) { BhapticsSDK2Wrapper.playParam("heavyinteract", 1, 0.5f, 1f, 0f, 0f); } } private static bool IsSuppressed(UiSfx instance) { return (bool)ShouldSupressSfx.Invoke(instance, null); } } [BepInPlugin("ggsDylanSBGHaptics", "SBG Haptics", "1.0.0")] public class HapticsPlugin : BaseUnityPlugin { public static ManualLogSource Log; public static TactSuit Suit; private PlayerInfo _localPlayerInfo; private static bool IsCartRumblePlaying = false; private static readonly float[] CartSpeedThresholds = new float[4] { 4f, 8f, 11f, float.MaxValue }; private static readonly float[] CartHapticIntensities = new float[4] { 0.05f, 0.15f, 0.25f, 0.35f }; private static int _currentCartBand = -1; private float _cartRumbleTimer = 0f; private const float CartRumbleRetriggerInterval = 2.7f; private const float AirborneMinVelocity = 10f; private const float AirborneMaxVelocity = 25f; private static bool IsAirbornePlaying = false; private float _airborneTimer = 3.24f; private const float AirbornePatternDuration = 3.24f; private float _speedBoostHapticTimer = 0f; private const float SpeedBoostHapticInterval = 0.34f; public static bool IsOverchargeLoopPlaying = false; private void Awake() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"SBG Haptics: Log initialized."); Suit = new TactSuit(); Log.LogInfo((object)"SBG Haptics: TactSuit initialized."); Harmony val = new Harmony("ggsDylanSBGHaptics"); val.PatchAll(); Log.LogInfo((object)"SBG Haptics: Harmony patches applied."); PlayerGolfer.LocalPlayerMatchResolutionChanged += OnLocalPlayerMatchResolutionChanged; } private void Update() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Invalid comparison between Unknown and I4 //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Invalid comparison between Unknown and I4 //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_localPlayerInfo == (Object)null) { PlayerGolfer localPlayerAsGolfer = GameManager.LocalPlayerAsGolfer; _localPlayerInfo = ((localPlayerAsGolfer != null) ? ((Component)localPlayerAsGolfer).GetComponent() : null); } GolfCartSeat activeGolfCartSeat; if ((Object)(object)_localPlayerInfo != (Object)null) { activeGolfCartSeat = _localPlayerInfo.ActiveGolfCartSeat; if (((GolfCartSeat)(ref activeGolfCartSeat)).IsValid()) { GolfCartInfo golfCart = _localPlayerInfo.ActiveGolfCartSeat.golfCart; GolfCartMovement val = ((golfCart != null) ? ((Component)golfCart).GetComponent() : null); if ((Object)(object)val != (Object)null) { Vector3 linearVelocity = val.AsEntity.Rigidbody.linearVelocity; float magnitude = ((Vector3)(ref linearVelocity)).magnitude; if (val.IsAnyWheelGrounded() && magnitude > 0.01f) { int cartBand = GetCartBand(magnitude); _cartRumbleTimer += Time.deltaTime; if (cartBand != _currentCartBand || _cartRumbleTimer >= 2.7f) { BhapticsSDK2Wrapper.stopByEventId("golfcartride"); BhapticsSDK2Wrapper.playLoop("golfcartride", 1, CartHapticIntensities[cartBand], 1f, 0f, 0f, 200, 999999); _currentCartBand = cartBand; _cartRumbleTimer = 0f; IsCartRumblePlaying = true; } } else { if (IsCartRumblePlaying) { BhapticsSDK2Wrapper.stopByEventId("golfcartride"); IsCartRumblePlaying = false; _currentCartBand = -1; } _cartRumbleTimer = 0f; } } goto IL_01c1; } } if (IsCartRumblePlaying) { BhapticsSDK2Wrapper.stopByEventId("golfcartride"); IsCartRumblePlaying = false; _currentCartBand = -1; _cartRumbleTimer = 0f; } goto IL_01c1; IL_01c1: PlayerInfo localPlayerInfo = _localPlayerInfo; PlayerMovement val2 = ((localPlayerInfo != null) ? localPlayerInfo.Movement : null); bool flag = (Object)(object)val2 != (Object)null && (int)val2.DivingState == 1 && (int)val2.DiveType == 3; int num; if ((Object)(object)val2 != (Object)null) { activeGolfCartSeat = _localPlayerInfo.ActiveGolfCartSeat; num = ((!((GolfCartSeat)(ref activeGolfCartSeat)).IsValid()) ? 1 : 0); } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { _airborneTimer += Time.deltaTime; if (_airborneTimer >= 3.24f) { _airborneTimer = 0f; BhapticsSDK2Wrapper.playParam("airborne", 0, 1f, 3.24f, 0f, 0f); IsAirbornePlaying = true; } } else if (IsAirbornePlaying) { BhapticsSDK2Wrapper.stopByEventId("airborne"); IsAirbornePlaying = false; _airborneTimer = 3.24f; } PlayerMovement localPlayerMovement = GameManager.LocalPlayerMovement; if ((Object)(object)localPlayerMovement != (Object)null && StatusEffectExtensions.HasEffect(localPlayerMovement.StatusEffects, (StatusEffect)2) && !GameManager.LocalPlayerAsGolfer.IsMatchResolved) { _speedBoostHapticTimer += Time.deltaTime; if (_speedBoostHapticTimer >= 0.34f) { _speedBoostHapticTimer = 0f; float num2 = Mathf.Clamp01(localPlayerMovement.SpeedBoostRemainingTime / GameManager.PlayerMovementSettings.MaxSpeedBoostDuration); if (num2 > 0f) { BhapticsSDK2Wrapper.playParam("heartbeat", 0, num2, 1f, 0f, 0f); } } } else { _speedBoostHapticTimer = 0.34f; } } private static void OnLocalPlayerMatchResolutionChanged(PlayerMatchResolution previous, PlayerMatchResolution current) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (PlayerMatchResolutionExtensions.IsResolved(current)) { StopAllHaptics(); } } private void OnApplicationQuit() { StopAllHaptics(); } private void OnDestroy() { PlayerGolfer.LocalPlayerMatchResolutionChanged -= OnLocalPlayerMatchResolutionChanged; StopAllHaptics(); } private static void StopAllHaptics() { BhapticsSDK2Wrapper.stopAll(); IsOverchargeLoopPlaying = false; IsCartRumblePlaying = false; IsAirbornePlaying = false; } private int GetCartBand(float velocity) { for (int i = 0; i < CartSpeedThresholds.Length; i++) { if (velocity < CartSpeedThresholds[i]) { return i; } } return CartHapticIntensities.Length - 1; } } public class TactSuit { public string apiKey = "matJkzdE0KSXpJXdcEKY"; public string workspaceId = "69fa03cc2ff723c4ece0909e"; public TactSuit() { HapticsPlugin.Log.LogInfo((object)"Tactsuit: Constructor started"); try { if (!BhapticsSDK2Wrapper.isPlayerRunning()) { HapticsPlugin.Log.LogInfo((object)"Tactsuit: Player not running, attempting launch..."); BhapticsSDK2Wrapper.launchPlayer(tryLaunch: true); } } catch (Exception ex) { HapticsPlugin.Log.LogError((object)("Tactsuit: Error checking player status: " + ex.Message)); } HapticsPlugin.Log.LogInfo((object)"Tactsuit: Attempting registryAndInit..."); if (BhapticsSDK2Wrapper.registryAndInit(apiKey, workspaceId, "")) { HapticsPlugin.Log.LogInfo((object)"Tactsuit: bHaptics connected!"); } else { HapticsPlugin.Log.LogError((object)"Tactsuit: bHaptics FAILED to connect!"); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "SuperBattleGolf_Haptics"; public const string PLUGIN_NAME = "Super Battle Golf bHaptics integration"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace tact_csharp2 { public class BhapticsSDK2Wrapper { private const string ModuleName = "bhaptics_library"; [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool registryAndInit(string sdkAPIKey, string workspaceId, string initData); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool registryAndInitHost(string sdkAPIKey, string workspaceId, string initData, string url); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool wsIsConnected(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern void wsClose(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool reInitMessage(string sdkAPIKey, string workspaceId, string initData); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int play(string eventId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int playParam(string eventId, int requestId, float intensity, float duration, float angleX, float offsetY); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern void playWithStartTime(string eventId, int requestId, int startMillis, float intensity, float duration, float angleX, float offsetY); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int playDot(int requestId, int position, int durationMillis, int[] motors, int size); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int playWaveform(int requestId, int position, int[] motorValues, int[] playTimeValues, int[] shapeValues, int motorLen); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int playPath(int requestId, int position, float[] xValues, float[] yValues, int[] intensityValues, int Len); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int playLoop(string eventId, int requestId, float intensity, float duration, float angleX, float offsetY, int interval, int maxCount); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int getEventTime(string eventId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern int pause(string eventId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool resume(string eventId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool stop(int requestId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool stopByEventId(string eventId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool stopAll(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool isbHapticsConnected(int position); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool isPlaying(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool isPlayingByRequestId(int requestId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool isPlayingByEventId(string eventId); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool isPlayerRunning(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool isPlayerInstalled(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool launchPlayer(bool tryLaunch); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr getDeviceInfoJson(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] public static extern IntPtr getHapticMappingsJson(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool ping(string address); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool pingAll(); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool swapPosition(string address); [DllImport("bhaptics_library", CallingConvention = CallingConvention.Cdecl)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool setDeviceVsm(string address, int vsm); } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }