using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using REPO_RemoveCartProtection.Config;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("REPO-RemoveCartProtection")]
[assembly: AssemblyDescription("Mod created by flipf17")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("REPO-RemoveCartProtection")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3936cfd2-4162-4dad-9e0e-5a492a70bf46")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace REPO_RemoveCartProtection
{
[HarmonyPatch]
public static class PhysGrabObjectImpactDetectorPatcher
{
public static Dictionary<PhysGrabObjectImpactDetector, bool> inCartValues = new Dictionary<PhysGrabObjectImpactDetector, bool>();
public static Dictionary<PhysGrabObjectImpactDetector, PhysGrabCart> currentCartValues = new Dictionary<PhysGrabObjectImpactDetector, PhysGrabCart>();
public static Dictionary<PhysGrabObjectImpactDetector, float> breakForceValues = new Dictionary<PhysGrabObjectImpactDetector, float>();
public static HashSet<PhysGrabObject> grabbedObjects = new HashSet<PhysGrabObject>();
[HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")]
[HarmonyPostfix]
public static void OnGrabStarted(ref bool ___isValuable, PhysGrabber player, PhysGrabObject __instance)
{
if ((GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient) || !___isValuable || !__instance.grabbedLocal || __instance.playerGrabbing.Count <= 0 || grabbedObjects.Contains(__instance))
{
return;
}
ValuableObject component = ((Component)__instance).GetComponent<ValuableObject>();
if (!Object.op_Implicit((Object)(object)component) || ((Object)(object)component.physAttributePreset != (Object)null && component.physAttributePreset.mass >= 2f && (Object)(object)component.durabilityPreset != (Object)null && component.durabilityPreset.fragility >= 50f))
{
return;
}
bool flag = false;
string text = ((Object)__instance).name.ToLower();
text = text.Replace(" ", "");
if (!flag)
{
for (int i = 0; i < Plugin.blacklistedItemNames.Length; i++)
{
if (text.Contains(Plugin.blacklistedItemNames[i]))
{
flag = true;
break;
}
}
}
if (!flag)
{
Plugin.LogWarningVerbose("OnGrabbed: " + ((Object)__instance).name);
grabbedObjects.Add(__instance);
}
}
[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "FixedUpdate")]
[HarmonyPrefix]
public static void OnImpactDetectorFixedUpdatePrefix(ref PhysGrabObject ___physGrabObject, ref PhysGrabCart ___currentCart, PhysGrabObjectImpactDetector __instance)
{
if (!GameManager.Multiplayer() || PhotonNetwork.IsMasterClient)
{
inCartValues[__instance] = __instance.inCart;
currentCartValues[__instance] = ___currentCart;
if (grabbedObjects.Contains(___physGrabObject) && __instance.inCart && (Object.op_Implicit((Object)(object)___currentCart) || !ConfigSettings.keepImpactProtectionExtraction.Value) && (!__instance.inCart || Object.op_Implicit((Object)(object)___currentCart) || !((Object)(object)((Component)__instance).gameObject.GetComponent<SurplusValuable>() != (Object)null)))
{
__instance.inCart = false;
___currentCart = null;
}
}
}
[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "FixedUpdate")]
[HarmonyPostfix]
public static void OnImpactDetectorFixedUpdatePostfix(ref PhysGrabObject ___physGrabObject, ref PhysGrabCart ___currentCart, ref bool ___isColliding, ref bool ___impactHappened, ref float ___breakForce, PhysGrabObjectImpactDetector __instance)
{
if (!GameManager.Multiplayer() || PhotonNetwork.IsMasterClient)
{
if (inCartValues.TryGetValue(__instance, out var value))
{
__instance.inCart = value;
}
if (currentCartValues.TryGetValue(__instance, out var value2))
{
___currentCart = value2;
}
}
}
[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "OnCollisionStay")]
[HarmonyPrefix]
public static void OnCollisionStayPrefix(ref PhysGrabObject ___physGrabObject, ref PhysGrabCart ___currentCart, ref bool ___collisionsActive, ref bool ___isMoving, ref bool ___impactHappened, ref float ___breakForce, ref float ___impactLevel1, ref float ___indestructibleSpawnTimer, Collision collision, PhysGrabObjectImpactDetector __instance)
{
if ((GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient) || !___collisionsActive || !___isMoving)
{
return;
}
inCartValues[__instance] = __instance.inCart;
currentCartValues[__instance] = ___currentCart;
breakForceValues[__instance] = ___breakForce;
if (((grabbedObjects.Contains(___physGrabObject) && __instance.inCart) & ___impactHappened) && ___indestructibleSpawnTimer <= 0f)
{
__instance.inCart = false;
___currentCart = null;
float num = ___breakForce;
___breakForce *= ConfigSettings.cartImpactMultiplier.Value;
if (___breakForce < ___impactLevel1 && num >= ___impactLevel1)
{
Plugin.LogWarningVerbose("Prevented impact damage. BreakForce reduced in cart: " + num + " => " + ___breakForce);
}
else if (num >= 50f)
{
Plugin.LogWarningVerbose("BreakForce reduced in cart: " + num + " => " + ___breakForce);
}
}
}
[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "OnCollisionStay")]
[HarmonyPostfix]
public static void OnCollisionStayPostfix(ref PhysGrabObject ___physGrabObject, ref PhysGrabCart ___currentCart, ref bool ___collisionsActive, ref bool ___isMoving, ref bool ___impactHappened, ref float ___breakForce, Collision collision, PhysGrabObjectImpactDetector __instance)
{
if ((!GameManager.Multiplayer() || PhotonNetwork.IsMasterClient) && ___collisionsActive && ___isMoving)
{
if (inCartValues.TryGetValue(__instance, out var value))
{
__instance.inCart = value;
}
if (currentCartValues.TryGetValue(__instance, out var value2))
{
___currentCart = value2;
}
if (breakForceValues.TryGetValue(__instance, out var value3))
{
___breakForce = value3;
}
if (grabbedObjects.Contains(___physGrabObject) && ___physGrabObject.playerGrabbing.Count <= 0)
{
Plugin.LogWarningVerbose("Collided with object while not grabbed by a player. Removing object from grabbedObjects: " + ((Object)___physGrabObject).name);
grabbedObjects.Remove(___physGrabObject);
}
}
}
}
[BepInPlugin("flipf17.RemoveCartProtection", "RemoveCartProtection", "0.1.1")]
public class Plugin : BaseUnityPlugin
{
private Harmony _harmony;
public static Plugin instance;
private static ManualLogSource logger;
internal static string[] blacklistedItemNames;
private void Awake()
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
instance = this;
CreateCustomLogger();
ConfigSettings.BindConfigSettings();
blacklistedItemNames = ConfigSettings.ParseBlacklistedItemNames();
if (blacklistedItemNames != null && blacklistedItemNames.Length != 0)
{
Log("Blacklisting " + blacklistedItemNames.Length + " items for Removing Cart Protection: ");
for (int i = 0; i < blacklistedItemNames.Length; i++)
{
Log(blacklistedItemNames[i]);
}
}
_harmony = new Harmony("RemoveCartProtection");
PatchAll();
Log("RemoveCartProtection loaded");
}
private void PatchAll()
{
IEnumerable<Type> enumerable;
try
{
enumerable = Assembly.GetExecutingAssembly().GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
enumerable = ex.Types.Where((Type t) => t != null);
}
foreach (Type item in enumerable)
{
_harmony.PatchAll(item);
}
}
private void CreateCustomLogger()
{
try
{
logger = Logger.CreateLogSource(string.Format("{0}-{1}", "RemoveCartProtection", "0.1.1"));
}
catch
{
logger = ((BaseUnityPlugin)this).Logger;
}
}
internal static void Log(string message)
{
logger.LogInfo((object)message);
}
internal static void LogError(string message)
{
logger.LogError((object)message);
}
internal static void LogWarning(string message)
{
logger.LogWarning((object)message);
}
internal static void LogVerbose(string message)
{
if (ConfigSettings.verboseLogs.Value)
{
logger.LogInfo((object)("[VERBOSE] " + message));
}
}
internal static void LogErrorVerbose(string message)
{
if (ConfigSettings.verboseLogs.Value)
{
logger.LogError((object)("[VERBOSE] " + message));
}
}
internal static void LogWarningVerbose(string message)
{
if (ConfigSettings.verboseLogs.Value)
{
logger.LogWarning((object)("[VERBOSE] " + message));
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "flipf17.RemoveCartProtection";
public const string PLUGIN_NAME = "RemoveCartProtection";
public const string PLUGIN_VERSION = "0.1.1";
}
}
namespace REPO_RemoveCartProtection.Config
{
[Serializable]
public static class ConfigSettings
{
public static ConfigEntry<bool> keepImpactProtectionExtraction;
public static ConfigEntry<float> cartImpactMultiplier;
public static ConfigEntry<string> removeProtectionBlacklist;
public static ConfigEntry<bool> verboseLogs;
public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>();
internal static void BindConfigSettings()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Expected O, but got Unknown
Plugin.Log("Binding Configs");
keepImpactProtectionExtraction = AddConfigEntry<bool>(((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("General", "Keep Impact Protection In Extraction", true, new ConfigDescription("[Host-only] Keeps the vanilla impact protection from objects in the extraction zone.", (AcceptableValueBase)null, Array.Empty<object>())));
cartImpactMultiplier = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("General", "Cart Impact Multiplier", 0.5f, new ConfigDescription("[Host-only] Lower Value = More Generous. A value of 0.5 will halve the impact when placing items into the cart, decreasing the likelihood of damaging an item. And a value of 1.0 will not reduce the impact at all, so be careful!", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>())));
removeProtectionBlacklist = AddConfigEntry<string>(((BaseUnityPlugin)Plugin.instance).Config.Bind<string>("General", "Remove Impact Protection - Blacklist", "Music Box,Frog,Propane Tank,Wizard Staff,Scream Doll,Saw Blade,", new ConfigDescription("[Host-only] Add item names here to prevent removing impact protection from. Separate each item with a \",\" character. Example: \"ItemName1,ItemName2\"\nItems in this blacklist will behaving normally when placing them into the cart.\nNOTE: Item names are a little funky to reference, so at this time, the formatting will be generous and may not need to match 100% of the item name, but may have issues in strange scenarios. Will refine in the future.", (AcceptableValueBase)null, Array.Empty<object>())));
verboseLogs = AddConfigEntry<bool>(((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("General", "Verbose Logs", false, new ConfigDescription("Enables verbose logs. Useful for debugging.", (AcceptableValueBase)null, Array.Empty<object>())));
cartImpactMultiplier.Value = Mathf.Clamp(cartImpactMultiplier.Value, 0.1f, 2f);
}
internal static ConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
{
currentConfigEntries.Add(((ConfigEntryBase)configEntry).Definition.Key, (ConfigEntryBase)(object)configEntry);
return configEntry;
}
internal static string[] ParseBlacklistedItemNames()
{
if (removeProtectionBlacklist == null || string.IsNullOrEmpty(removeProtectionBlacklist.Value) || removeProtectionBlacklist.Value.Length <= 0)
{
return new string[0];
}
try
{
string text = removeProtectionBlacklist.Value.ToLower();
text = text.Replace(" ", "");
return text.Split(new char[1] { ',' });
}
catch (Exception ex)
{
Plugin.LogError("Error parsing impact protection blacklist.\n" + ex);
return new string[0];
}
}
}
}