using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DynamicRepoGrabBeam.ColorLogic;
using DynamicRepoGrabBeam.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("DynamicRepoGrabBeam")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8aa2bc3b34b8df8e0126a9169fc65a05d752a06c")]
[assembly: AssemblyProduct("DynamicRepoGrabBeam")]
[assembly: AssemblyTitle("DynamicRepoGrabBeam")]
[assembly: AssemblyVersion("1.0.0.0")]
[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;
}
}
}
[BepInPlugin("com.repo.DynamicRepoGrabBeam", "Grab Beam Mod", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
public static ConfigEntry<float> LightMax;
public static ConfigEntry<float> HeavyMin;
public static ConfigEntry<Color> LightColor;
public static ConfigEntry<Color> MediumColor;
public static ConfigEntry<Color> HeavyColor;
public static ConfigEntry<Color> PlayerGrabColor;
public static ConfigEntry<Color> RotationModeColor;
public static ConfigEntry<float> MaxStunVisualForce;
public static ConfigEntry<float> ForceSaturationScale;
public static ConfigEntry<float> ForceBrightnessScale;
public static ConfigEntry<float> ForceAlphaScale;
public static ConfigEntry<bool> EnableDebugLogs;
public static ManualLogSource Log
{
get
{
Plugin instance = Instance;
if (instance == null)
{
return null;
}
return ((BaseUnityPlugin)instance).Logger;
}
}
private void Awake()
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
BeamColorManager.Initialize();
LightMax = ((BaseUnityPlugin)this).Config.Bind<float>("Weight Thresholds", "LightMax", 2f, "Max mass for light objects");
HeavyMin = ((BaseUnityPlugin)this).Config.Bind<float>("Weight Thresholds", "HeavyMin", 3f, "Min mass for heavy objects");
LightColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Colors", "LightWeight", new Color(0f, 1f, 0f, 0.5f), "Beam color for light objects (50% opacity)");
MediumColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Colors", "MediumWeight", new Color(1f, 1f, 0f, 0.5f), "Beam color for medium objects (50% opacity)");
HeavyColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Colors", "HeavyWeight", new Color(1f, 0f, 0f, 0.5f), "Beam color for heavy objects (50% opacity)");
PlayerGrabColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Colors", "PlayerGrabBeam", new Color(0f, 1f, 1f, 0.5f), "Beam color when grabbing another player (50% opacity)");
RotationModeColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Colors", "RotationModeBeam", new Color(1f, 0.5f, 1f, 0.5f), "Beam color override while rotating (used instead of default purple)");
MaxStunVisualForce = ((BaseUnityPlugin)this).Config.Bind<float>("Force", "MaxStunVisualForce", 15f, "Force value that causes full saturation intensity");
ForceSaturationScale = ((BaseUnityPlugin)this).Config.Bind<float>("Force", "SaturationScale", 0.2f, "How much saturation increases with normalized impact force");
ForceBrightnessScale = ((BaseUnityPlugin)this).Config.Bind<float>("Force", "BrightnessScale", 0.03f, "How much brightness increases with normalized impact force");
ForceAlphaScale = ((BaseUnityPlugin)this).Config.Bind<float>("Force", "AlphaScale", 0.3f, "How much transparency (alpha) increases with normalized impact force");
EnableDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugLogs", false, "Enable force debug output");
if (EnableDebugLogs.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Debug logging is ENABLED.");
}
new Harmony("com.repo.DynamicRepoGrabBeam").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Grab Beam Mod v1.0.0 initialized successfully");
}
}
public class BeamColorObserver : MonoBehaviour
{
private readonly Dictionary<PhysGrabber, int> lastGrabs = new Dictionary<PhysGrabber, int>();
private readonly List<PhysGrabber> cachedGrabbers = new List<PhysGrabber>();
private float updateInterval = 0.2f;
private float timer;
private float rescanInterval = 10f;
private float rescanTimer;
private void Awake()
{
RescanGrabbers();
}
private void Update()
{
timer -= Time.deltaTime;
rescanTimer -= Time.deltaTime;
if (rescanTimer <= 0f)
{
RescanGrabbers();
rescanTimer = rescanInterval;
}
if (timer > 0f)
{
return;
}
timer = updateInterval;
Rigidbody val = default(Rigidbody);
foreach (PhysGrabber cachedGrabber in cachedGrabbers)
{
if ((Object)(object)cachedGrabber == (Object)null)
{
continue;
}
PhysGrabObject grabbedObject = cachedGrabber.GetGrabbedObject();
if ((Object)(object)grabbedObject == (Object)null)
{
continue;
}
if (!((Component)grabbedObject).TryGetComponent<Rigidbody>(ref val))
{
Plugin.Log.LogWarning((object)("[DynamicRepoGrabBeam] Delaying recolor: Rigidbody missing for object '" + ((Object)grabbedObject).name + "' (grabber '" + ((Object)cachedGrabber).name + "')"));
}
else
{
int instanceID = ((Object)grabbedObject).GetInstanceID();
if (!lastGrabs.TryGetValue(cachedGrabber, out var value) || value != instanceID)
{
lastGrabs[cachedGrabber] = instanceID;
BeamColorManager.UpdateBeamFor(cachedGrabber, grabbedObject);
}
}
}
}
private void RescanGrabbers()
{
cachedGrabbers.Clear();
cachedGrabbers.AddRange(Object.FindObjectsOfType<PhysGrabber>());
}
}
namespace DynamicRepoGrabBeam.Patches
{
public static class PhysGrabberAccessors
{
private static readonly FieldInfo grabbedObjField;
private static readonly FieldInfo beamField;
private static readonly FieldInfo isPlayerField;
private static readonly Func<PhysGrabObjectImpactDetector, float> BreakForceGetter;
private static readonly Func<PhysGrabObjectImpactDetector, float> FragilityGetter;
static PhysGrabberAccessors()
{
grabbedObjField = AccessTools.Field(typeof(PhysGrabber), "grabbedPhysGrabObject");
beamField = AccessTools.Field(typeof(PhysGrabber), "physGrabBeam");
isPlayerField = AccessTools.Field(typeof(PhysGrabObject), "isPlayer");
BreakForceGetter = CreateFieldGetter<float>("breakForce");
FragilityGetter = CreateFieldGetter<float>("impactFragilityMultiplier");
if (BreakForceGetter == null)
{
Debug.LogError((object)"[DynamicRepoGrabBeam] BreakForceGetter delegate failed!");
}
if (FragilityGetter == null)
{
Debug.LogError((object)"[DynamicRepoGrabBeam] FragilityGetter delegate failed!");
}
}
public static bool IsPlayer(this PhysGrabObject obj)
{
if (isPlayerField != null)
{
return (bool)isPlayerField.GetValue(obj);
}
return false;
}
public static PhysGrabObject GetGrabbedObject(this PhysGrabber instance)
{
object? value = grabbedObjField.GetValue(instance);
return (PhysGrabObject)((value is PhysGrabObject) ? value : null);
}
public static GameObject GetBeamObject(this PhysGrabber instance)
{
object? value = beamField.GetValue(instance);
return (GameObject)((value is GameObject) ? value : null);
}
public static float GetBreakForce(this PhysGrabObjectImpactDetector det)
{
return BreakForceGetter(det);
}
public static float GetFragility(this PhysGrabObjectImpactDetector det)
{
return FragilityGetter(det);
}
private static Func<PhysGrabObjectImpactDetector, T> CreateFieldGetter<T>(string fieldName)
{
try
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(PhysGrabObjectImpactDetector), "target");
return Expression.Lambda<Func<PhysGrabObjectImpactDetector, T>>(Expression.Field(parameterExpression, fieldName), new ParameterExpression[1] { parameterExpression }).Compile();
}
catch (Exception ex)
{
Debug.LogError((object)("[DynamicRepoGrabBeam] Failed to create delegate for '" + fieldName + "': " + ex.Message));
return (PhysGrabObjectImpactDetector _) => default(T);
}
}
}
}
namespace DynamicRepoGrabBeam.ColorLogic
{
public class PlayerGrabColorStrategy : IBeamColorStrategy
{
public bool Applies(PhysGrabber grabber, PhysGrabObject obj)
{
return obj.IsPlayer();
}
public Color Modify(Color current, PhysGrabber grabber, PhysGrabObject obj)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return Plugin.PlayerGrabColor.Value;
}
public Color ModifyFast(Color current, PhysGrabber grabber, PhysGrabObject obj, float impact, BeamContext ctx)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return Plugin.PlayerGrabColor.Value;
}
}
public class MassColorStrategy : IBeamColorStrategy
{
public bool Applies(PhysGrabber grabber, PhysGrabObject obj)
{
if (obj.IsPlayer())
{
return false;
}
Rigidbody val = default(Rigidbody);
return ((Component)obj).TryGetComponent<Rigidbody>(ref val);
}
public Color Modify(Color current, PhysGrabber grabber, PhysGrabObject obj)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
Rigidbody val = default(Rigidbody);
if (!((Component)obj).TryGetComponent<Rigidbody>(ref val))
{
return current;
}
float mass = val.mass;
float value = Plugin.LightMax.Value;
float value2 = Plugin.HeavyMin.Value;
if (mass < value)
{
return Plugin.LightColor.Value;
}
if (mass > value2)
{
return Plugin.HeavyColor.Value;
}
return Plugin.MediumColor.Value;
}
public Color ModifyFast(Color current, PhysGrabber grabber, PhysGrabObject obj, float impact, BeamContext ctx)
{
//IL_0001: 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)
return Modify(current, grabber, obj);
}
}
public class RotationLightenStrategy : IBeamColorStrategy
{
public bool Applies(PhysGrabber grabber, PhysGrabObject obj)
{
return grabber.isRotating;
}
public Color Modify(Color current, PhysGrabber grabber, PhysGrabObject obj)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return Plugin.RotationModeColor.Value;
}
public Color ModifyFast(Color current, PhysGrabber grabber, PhysGrabObject obj, float impact, BeamContext ctx)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
if (!grabber.isRotating)
{
return current;
}
if (Plugin.EnableDebugLogs.Value)
{
Plugin.Log.LogInfo((object)"[Rotation] Overriding beam with RotationModeColor");
}
return Plugin.RotationModeColor.Value;
}
}
public class BeamContext
{
public PhysGrabObject GrabbedObject { get; }
public Renderer BeamRenderer { get; }
public float H0 { get; }
public float S0 { get; }
public float V0 { get; }
public float MaxForce { get; }
public float SaturationScale { get; }
public float BrightnessScale { get; }
public float AlphaScale { get; }
public Color BaseColor { get; }
public BeamContext(PhysGrabObject obj, Renderer renderer, float h, float s, float v, float maxForce, float satScale, float brightScale, float alphaScale, Color baseColor)
{
//IL_004c: 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)
GrabbedObject = obj;
BeamRenderer = renderer;
H0 = h;
S0 = s;
V0 = v;
MaxForce = maxForce;
SaturationScale = satScale;
BrightnessScale = brightScale;
AlphaScale = alphaScale;
BaseColor = baseColor;
}
}
public class ForceEffectStrategy : IBeamColorStrategy
{
public static float ComputeImpact(PhysGrabObject obj)
{
PhysGrabObjectImpactDetector det = default(PhysGrabObjectImpactDetector);
if (!((Component)obj).TryGetComponent<PhysGrabObjectImpactDetector>(ref det))
{
return 0f;
}
float breakForce = det.GetBreakForce();
float fragility = det.GetFragility();
return breakForce / 8f * fragility;
}
public bool Applies(PhysGrabber grabber, PhysGrabObject obj)
{
PhysGrabObjectImpactDetector val = default(PhysGrabObjectImpactDetector);
return ((Component)obj).TryGetComponent<PhysGrabObjectImpactDetector>(ref val);
}
public Color Modify(Color current, PhysGrabber grabber, PhysGrabObject obj)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
return current;
}
public Color ModifyFast(Color current, PhysGrabber grabber, PhysGrabObject obj, float ignoredImpact, BeamContext ctx)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
float num = ComputeImpact(obj);
float num2 = Mathf.Clamp01(num / ctx.MaxForce);
if (Plugin.EnableDebugLogs.Value)
{
Plugin.Log.LogInfo((object)$"[ForceEffectStrategy] Impact = {num:F2}, Strength = {num2:F2}");
}
float h = ctx.H0;
float s = ctx.S0;
float v = ctx.V0;
s = Mathf.Clamp01(s + num2 * ctx.SaturationScale);
v = Mathf.Clamp01(v + num2 * ctx.BrightnessScale);
Color result = Color.HSVToRGB(h, s, v);
result.a = Mathf.Lerp(0.1f, 1f, num2 * ctx.AlphaScale);
return result;
}
}
public interface IBeamColorStrategy
{
bool Applies(PhysGrabber grabber, PhysGrabObject obj);
Color Modify(Color current, PhysGrabber grabber, PhysGrabObject obj);
Color ModifyFast(Color current, PhysGrabber grabber, PhysGrabObject obj, float impact, BeamContext ctx);
}
public static class BeamColorManager
{
[HarmonyPatch(typeof(PhysGrabber), "Update")]
private static class Hook_LateUpdate
{
private static void Postfix(PhysGrabber __instance)
{
PhysGrabObject grabbedObject = __instance.GetGrabbedObject();
if ((Object)(object)grabbedObject == (Object)null)
{
_ctx = null;
lastObj = null;
return;
}
if (_ctx == null || (Object)(object)grabbedObject != (Object)(object)lastObj)
{
lastObj = grabbedObject;
BuildContext(__instance, grabbedObject);
}
UpdateBeam(__instance);
}
}
private static readonly List<IBeamColorStrategy> allStrategies = new List<IBeamColorStrategy>
{
new PlayerGrabColorStrategy(),
new MassColorStrategy(),
new ForceEffectStrategy(),
new RotationLightenStrategy()
};
private static BeamContext _ctx;
private static List<IBeamColorStrategy> _active;
private static PhysGrabObject lastObj = null;
public static void Initialize()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: 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)
GameObject val = new GameObject("BeamColorObserver")
{
hideFlags = (HideFlags)61
};
val.AddComponent<BeamColorObserver>();
val.SetActive(true);
Plugin.Log.LogInfo((object)"[DynamicRepoGrabBeam] BeamColorObserver GameObject created and observing.");
}
private static void BuildContext(PhysGrabber grabber, PhysGrabObject obj)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
GameObject beamObject = grabber.GetBeamObject();
Renderer val = ((beamObject != null) ? beamObject.GetComponentInChildren<Renderer>() : null);
if ((Object)(object)val == (Object)null)
{
return;
}
Color val2 = Color.white;
foreach (IBeamColorStrategy allStrategy in allStrategies)
{
if (allStrategy is ForceEffectStrategy)
{
break;
}
if (allStrategy.Applies(grabber, obj))
{
val2 = allStrategy.Modify(val2, grabber, obj);
}
}
float h = default(float);
float s = default(float);
float v = default(float);
Color.RGBToHSV(val2, ref h, ref s, ref v);
_ctx = new BeamContext(obj, val, h, s, v, Plugin.MaxStunVisualForce.Value, Plugin.ForceSaturationScale.Value, Plugin.ForceBrightnessScale.Value, Plugin.ForceAlphaScale.Value, val2);
_active = allStrategies.ToList();
}
private static void UpdateBeam(PhysGrabber grabber)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: 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_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: 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)
float impact = 0f;
PhysGrabObjectImpactDetector val = default(PhysGrabObjectImpactDetector);
if (((Component)_ctx.GrabbedObject).TryGetComponent<PhysGrabObjectImpactDetector>(ref val))
{
impact = ForceEffectStrategy.ComputeImpact(_ctx.GrabbedObject);
}
Color val2 = Color.HSVToRGB(_ctx.H0, _ctx.S0, _ctx.V0);
foreach (IBeamColorStrategy item in _active)
{
val2 = item.ModifyFast(val2, grabber, _ctx.GrabbedObject, impact, _ctx);
}
ApplyBeamColor(_ctx.BeamRenderer, val2);
}
public static void ApplyBeamColor(Renderer rend, Color color)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
Material material = rend.material;
material.SetColor("_Color", color);
material.SetColor("_EmissionColor", color);
}
public static void UpdateBeamFor(PhysGrabber grabber, PhysGrabObject obj)
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)obj == (Object)null)
{
return;
}
GameObject beamObject = grabber.GetBeamObject();
Renderer val = ((beamObject != null) ? beamObject.GetComponentInChildren<Renderer>() : null);
if ((Object)(object)val == (Object)null)
{
return;
}
Rigidbody val2 = default(Rigidbody);
bool num = ((Component)obj).TryGetComponent<Rigidbody>(ref val2);
float num2 = (num ? val2.mass : (-1f));
Color val3;
if (!num || num2 <= 0f)
{
val3 = Plugin.MediumColor.Value;
Plugin.Log.LogWarning((object)("[DynamicRepoGrabBeam] Applying fallback color for '" + ((Object)obj).name + "' grabbed by '" + ((Object)grabber).name + "' (missing Rigidbody)"));
}
else
{
val3 = Color.white;
foreach (IBeamColorStrategy allStrategy in allStrategies)
{
if (allStrategy is ForceEffectStrategy)
{
break;
}
if (allStrategy.Applies(grabber, obj))
{
val3 = allStrategy.Modify(val3, grabber, obj);
}
}
}
float num3 = default(float);
float num4 = default(float);
float num5 = default(float);
Color.RGBToHSV(val3, ref num3, ref num4, ref num5);
BeamContext ctx = new BeamContext(obj, val, num3, num4, num5, Plugin.MaxStunVisualForce.Value, Plugin.ForceSaturationScale.Value, Plugin.ForceBrightnessScale.Value, Plugin.ForceAlphaScale.Value, val3);
float impact = 0f;
PhysGrabObjectImpactDetector val4 = default(PhysGrabObjectImpactDetector);
if (((Component)obj).TryGetComponent<PhysGrabObjectImpactDetector>(ref val4))
{
impact = ForceEffectStrategy.ComputeImpact(obj);
}
Color val5 = Color.HSVToRGB(num3, num4, num5);
foreach (IBeamColorStrategy allStrategy2 in allStrategies)
{
val5 = allStrategy2.ModifyFast(val5, grabber, obj, impact, ctx);
}
ApplyBeamColor(val, val5);
}
}
}