diff --git a/Source/Patches/PlayerControllerPatches.cs b/Source/Patches/PlayerControllerPatches.cs
index ea9e6379..8fa6c7f7 100644
--- a/Source/Patches/PlayerControllerPatches.cs
+++ b/Source/Patches/PlayerControllerPatches.cs
@@ -1,4 +1,5 @@
-using GameNetcodeStuff;
+using System;
+using GameNetcodeStuff;
using HarmonyLib;
using LCVR.Assets;
using LCVR.Input;
@@ -7,6 +8,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR;
@@ -308,8 +310,7 @@ private static void SwitchedToItemSlot(PlayerControllerB __instance)
}
///
- /// Fix for water suffocation to be calculated from a predetermined offset instead of the camera position,
- /// which fixes an exploit where being too tall prevents drowning
+ /// Fix for water suffocation to be calculated from a clamped offset, so that play area hacks won't affect drowning
///
[HarmonyPatch(typeof(PlayerControllerB), nameof(PlayerControllerB.SetFaceUnderwaterFilters))]
[HarmonyTranspiler]
@@ -321,17 +322,16 @@ [new CodeMatch(OpCodes.Call, Method(typeof(Bounds), nameof(Bounds.Contains), [ty
.Advance(-3)
.RemoveInstructions(3)
.InsertAndAdvance(new CodeInstruction(OpCodes.Call,
- PropertyGetter(typeof(Component), nameof(Component.transform))))
- .InsertAndAdvance(new CodeInstruction(OpCodes.Callvirt,
- PropertyGetter(typeof(Transform), nameof(Transform.position))))
- .InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_R4, 0f))
- .InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_R4, 2.3f))
- .InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_R4, 0f))
- .InsertAndAdvance(new CodeInstruction(OpCodes.Newobj,
- Constructor(typeof(Vector3), [typeof(float), typeof(float), typeof(float)])))
- .InsertAndAdvance(new CodeInstruction(OpCodes.Call,
- Method(typeof(Vector3), "op_Addition", [typeof(Vector3), typeof(Vector3)])))
+ ((Func)GetClampedCameraPosition).Method))
.InstructionEnumeration();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static Vector3 GetClampedCameraPosition(PlayerControllerB player)
+ {
+ var actualHeight = player.transform.InverseTransformPoint(player.gameplayCamera.transform.position).y;
+
+ return player.transform.position + Vector3.up * Mathf.Clamp(actualHeight, 0.5f, 2.35f);
+ }
}
}
diff --git a/Source/Patches/Spectating/EnvironmentPatches.cs b/Source/Patches/Spectating/EnvironmentPatches.cs
index 2d6274b8..c21d5090 100644
--- a/Source/Patches/Spectating/EnvironmentPatches.cs
+++ b/Source/Patches/Spectating/EnvironmentPatches.cs
@@ -3,6 +3,7 @@
using System.Reflection.Emit;
using GameNetcodeStuff;
using HarmonyLib;
+using UnityEngine;
namespace LCVR.Patches.Spectating;
@@ -152,4 +153,16 @@ private static void UnderwaterPreventDeath(PlayerControllerB __instance)
StartOfRound.Instance.drowningTimer = 1;
}
+
+ ///
+ /// Prevent dead players from interacting with footballs
+ ///
+ [HarmonyPatch(typeof(SoccerBallProp), nameof(SoccerBallProp.ActivatePhysicsTrigger))]
+ [HarmonyPrefix]
+ private static bool DontTouchBallPatch(SoccerBallProp __instance, Collider other)
+ {
+ return !other.CompareTag("Player") ||
+ other.GetComponent() != StartOfRound.Instance.localPlayerController ||
+ !StartOfRound.Instance.localPlayerController.isPlayerDead;
+ }
}
diff --git a/Source/Plugin.cs b/Source/Plugin.cs
index 26a44a86..b2a64de4 100644
--- a/Source/Plugin.cs
+++ b/Source/Plugin.cs
@@ -31,7 +31,7 @@ public class Plugin : BaseUnityPlugin
private readonly string[] GAME_ASSEMBLY_HASHES =
[
- "45E2312BEEE3C163658C247354F10EE84DE5D594ED18A3D2EFC6B80F07AC1737", // V62
+ "976BBA44E5F05AC3915A92FA26822F6F7E67BD52F4FFD0371190EF865460F4FB", // V62
];
public new static Config Config { get; private set; }