using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using MelonLoader;
using Microsoft.CodeAnalysis;
using Realism;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: MelonInfo(typeof(Mod), "Realism", "3.3.0", "Codex", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : System.Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(/*Could not decode attribute arguments.*/)]
internal sealed class RefSafetyRulesAttribute : System.Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Realism
{
public sealed class Mod : MelonMod
{
private enum MuzzleFlashStyle
{
Standard,
CompactBurst,
TaperedCone,
SplitJet,
Smoke
}
private sealed class TracerEffect
{
public object GameObject;
public object OuterLineGameObject;
public object CoreLineGameObject;
public object Transform;
public object OuterLine;
public object CoreLine;
public object Origin;
public object Direction;
public object Projectile;
public object ProjectileTransform;
public object ProjectileBody;
public object LastPosition;
public System.DateTime Started;
public System.DateTime FinishedAt;
public bool TrackingProjectile;
public bool HasFinishedAt;
public float Length;
public float Speed;
public float Life;
public float HeadSize;
public float OuterStartWidth;
public float OuterEndWidth;
public float CoreStartWidth;
public float CoreEndWidth;
}
private sealed class ProjectileCandidate
{
public object Projectile;
public object Transform;
public object Rigidbody;
public object Position;
public object Direction;
public float Speed;
}
private sealed class SparkEffect
{
public object GameObject;
public object TailGameObject;
public object Transform;
public object TailTransform;
public object Origin;
public object Direction;
public System.DateTime Started;
public float Life;
public float Length;
public float Speed;
public float HeadSize;
public float TailWidth;
}
private sealed class SmokePuff
{
public object GameObject;
public object Transform;
public object Material;
public object Origin;
public object Velocity;
public System.DateTime Started;
public float Life;
public float Size;
public float Alpha;
}
private static bool earRingingEnabled = true;
private static bool muzzleFlashEnabled = true;
private static bool sparksEnabled = true;
private static bool smokeEnabled = true;
private static bool tracersEnabled = true;
private static MuzzleFlashStyle muzzleFlashStyle = MuzzleFlashStyle.Standard;
private static float ringingVolumeSetting = 100f;
private const float RemoteRingingRange = 18f;
private static System.Delegate fireHandler;
private static System.Type boneMenu;
private static System.Type pageType;
private static System.Type unityObject;
private static System.Type gameObjectType;
private static System.Type vector3Type;
private static object modPage;
private static Mod instance;
private static bool eventSubscribed;
private static bool shotErrorLogged;
private static bool shotHookObservedLogged;
private static bool remoteShotObservedLogged;
private static bool audioErrorLogged;
private static bool visualErrorLogged;
private static bool tracerSpawnLogged;
private static bool tracerUpdateLogged;
private static bool tracerShaderLogged;
private static bool tracerProjectileLookupLogged;
private static bool remoteVisualsLogged;
private static bool remoteRingingLogged;
private static bool remoteDistantRingingSuppressedLogged;
private static bool? mobilePlatformCache;
private static bool projectileTypesScanned;
private static System.Type[] projectileTypes = System.Array.Empty<System.Type>();
private static readonly object[] muzzleStyleMenuElements = new object[5];
private static readonly HashSet<MuzzleFlashStyle> muzzleFlashStylesLogged = new HashSet<MuzzleFlashStyle>();
private static readonly ConcurrentQueue<object> pendingGunFires = new ConcurrentQueue<object>();
private static object ringingGameObject;
private static object ringingSource;
private static object ringingClip;
private static float ringingLevel;
private static float ringingVolume;
private static System.DateTime ringingUpdated = System.DateTime.MinValue;
private static readonly Random effectRandom = new Random();
private static readonly Dictionary<string, object> materialCache = new Dictionary<string, object>();
private static readonly Dictionary<string, object> tracerMaterialCache = new Dictionary<string, object>();
private static readonly List<TracerEffect> tracers = new List<TracerEffect>();
private static readonly List<SparkEffect> sparks = new List<SparkEffect>();
private static readonly List<SmokePuff> smokePuffs = new List<SmokePuff>();
public override void OnInitializeMelon()
{
instance = this;
((MelonBase)this).LoggerInstance.Msg("Realism 3.3.0 loaded; BoneMenu setup will retry until BoneLib is ready.");
if (FindType("LabFusion.Entities.NetworkPlayerManager") != (System.Type)null)
{
((MelonBase)this).LoggerInstance.Msg("LabFusion detected; Realism effects are generated locally from BoneLib gun-fire events, including replicated shots.");
}
TryBuildMenu();
TrySubscribeToGunFire();
}
public override void OnUpdate()
{
if (modPage == null)
{
TryBuildMenu();
}
if (!eventSubscribed)
{
TrySubscribeToGunFire();
}
ProcessPendingGunFires();
UpdateRinging();
UpdateTracers();
UpdateSparks();
UpdateSmoke();
}
public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
{
ClearSceneVisuals();
object obj = default(object);
while (pendingGunFires.TryDequeue(ref obj))
{
}
((MelonBase)this).LoggerInstance.Msg("Scene unloading (" + sceneName + "); cleared transient Realism visuals and queued shots.");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
gameObjectType = FindType("UnityEngine.GameObject");
unityObject = FindType("UnityEngine.Object");
vector3Type = FindType("UnityEngine.Vector3");
shotHookObservedLogged = false;
tracerSpawnLogged = false;
tracerUpdateLogged = false;
tracerShaderLogged = false;
tracerProjectileLookupLogged = false;
visualErrorLogged = false;
RebindGunFireAfterSceneChange();
((MelonBase)this).LoggerInstance.Msg("Scene loaded (" + sceneName + "); refreshed Realism visual references and gun-fire hook.");
}
private static void ClearSceneVisuals()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: 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_017e: Unknown result type (might be due to invalid IL or missing references)
Enumerator<TracerEffect> enumerator = tracers.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
TracerEffect current = enumerator.Current;
Destroy(current.GameObject, 0f);
Destroy(current.OuterLineGameObject, 0f);
Destroy(current.CoreLineGameObject, 0f);
}
}
finally
{
((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
}
tracers.Clear();
Enumerator<SparkEffect> enumerator2 = sparks.GetEnumerator();
try
{
while (enumerator2.MoveNext())
{
SparkEffect current2 = enumerator2.Current;
Destroy(current2.GameObject, 0f);
Destroy(current2.TailGameObject, 0f);
}
}
finally
{
((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
}
sparks.Clear();
Enumerator<SmokePuff> enumerator3 = smokePuffs.GetEnumerator();
try
{
while (enumerator3.MoveNext())
{
SmokePuff current3 = enumerator3.Current;
Destroy(current3.GameObject, 0f);
}
}
finally
{
((System.IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
}
smokePuffs.Clear();
Enumerator<string, object> enumerator4 = tracerMaterialCache.Values.GetEnumerator();
try
{
while (enumerator4.MoveNext())
{
object current4 = enumerator4.Current;
Destroy(current4, 0f);
}
}
finally
{
((System.IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose();
}
tracerMaterialCache.Clear();
Enumerator<string, object> enumerator5 = materialCache.Values.GetEnumerator();
try
{
while (enumerator5.MoveNext())
{
object current5 = enumerator5.Current;
Destroy(current5, 0f);
}
}
finally
{
((System.IDisposable)enumerator5/*cast due to .constrained prefix*/).Dispose();
}
materialCache.Clear();
}
private void RebindGunFireAfterSceneChange()
{
try
{
EventInfo val = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.Hooking", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null))?.GetEvent("OnPostFireGun", (BindingFlags)24);
if (val != (EventInfo)null && fireHandler != null)
{
try
{
val.RemoveEventHandler((object)null, fireHandler);
}
catch
{
}
}
eventSubscribed = false;
fireHandler = null;
TrySubscribeToGunFire();
}
catch (System.Exception ex)
{
eventSubscribed = false;
((MelonBase)this).LoggerInstance.Warning("Gun-fire hook refresh failed after scene change: " + ex.GetBaseException().Message);
}
}
private void TryBuildMenu()
{
//IL_0256: Unknown result type (might be due to invalid IL or missing references)
try
{
boneMenu = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.BoneMenu.Menu", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null));
pageType = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.BoneMenu.Page", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null));
if (boneMenu == (System.Type)null || pageType == (System.Type)null)
{
return;
}
PropertyInfo property = pageType.GetProperty("Root", (BindingFlags)24);
object obj = ((property != null) ? property.GetValue((object)null) : null);
if (obj == null)
{
return;
}
MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)pageType.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "CreatePage" && ((MethodBase)m).GetParameters().Length != 0 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(string)));
if (val == (MethodInfo)null)
{
return;
}
System.Type type = FindType("UnityEngine.Color");
object obj2;
if (type == null)
{
obj2 = null;
}
else
{
PropertyInfo property2 = type.GetProperty("white", (BindingFlags)24);
obj2 = ((property2 != null) ? property2.GetValue((object)null) : null);
}
object color = obj2;
object parent = CreateBoneMenuPage(val, obj, "Realism", type, color);
object page = CreateBoneMenuPage(val, parent, "Ear Ringing", type, color);
object page2 = CreateBoneMenuPage(val, parent, "Muzzle Flash", type, color);
object page3 = CreateBoneMenuPage(val, parent, "Sparks", type, color);
object page4 = CreateBoneMenuPage(val, parent, "Smoke", type, color);
object page5 = CreateBoneMenuPage(val, parent, "Bullet Tracers", type, color);
MethodInfo val2 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)pageType.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "CreateBool"));
MethodInfo val3 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)pageType.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "CreateFloat" && Enumerable.Count<ParameterInfo>((System.Collections.Generic.IEnumerable<ParameterInfo>)((MethodBase)m).GetParameters(), (Func<ParameterInfo, bool>)((ParameterInfo p) => p.ParameterType == typeof(float))) == 4));
if (val2 == (MethodInfo)null || val3 == (MethodInfo)null)
{
throw new MissingMethodException("BoneLib menu setting methods were unavailable.");
}
CreateBoneMenuBool(val2, page, "Enabled", type, color, earRingingEnabled, [CompilerGenerated] (bool value) =>
{
earRingingEnabled = value;
((MelonBase)this).LoggerInstance.Msg("Ear ringing " + (value ? "enabled" : "disabled") + ".");
});
CreateBoneMenuFloat(val3, page, "Volume (%)", type, color, ringingVolumeSetting, 5f, 0f, 100f, [CompilerGenerated] (float value) =>
{
ringingVolumeSetting = value;
((MelonBase)this).LoggerInstance.Msg($"Ear ringing volume set to {value:0}%.");
});
CreateBoneMenuBool(val2, page2, "Enabled", type, color, muzzleFlashEnabled, [CompilerGenerated] (bool value) =>
{
muzzleFlashEnabled = value;
((MelonBase)this).LoggerInstance.Msg("Muzzle flash " + (value ? "enabled" : "disabled") + ".");
});
AddMuzzleFlashStyleToggles(val2, page2, type, color);
CreateBoneMenuBool(val2, page3, "Enabled", type, color, sparksEnabled, [CompilerGenerated] (bool value) =>
{
sparksEnabled = value;
((MelonBase)this).LoggerInstance.Msg("Sparks " + (value ? "enabled" : "disabled") + ".");
});
CreateBoneMenuBool(val2, page4, "Enabled", type, color, smokeEnabled, [CompilerGenerated] (bool value) =>
{
smokeEnabled = value;
((MelonBase)this).LoggerInstance.Msg("Smoke " + (value ? "enabled" : "disabled") + ".");
});
CreateBoneMenuBool(val2, page5, "Enabled", type, color, tracersEnabled, [CompilerGenerated] (bool value) =>
{
tracersEnabled = value;
((MelonBase)this).LoggerInstance.Msg("Bullet tracers " + (value ? "enabled" : "disabled") + ".");
});
modPage = parent;
((MelonBase)this).LoggerInstance.Msg("Realism BoneMenu pages for ringing, selectable muzzle flash styles, sparks, smoke and tracers added. Choose one of the four style toggles; its check mark marks the active style.");
}
catch (System.Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("BoneMenu setup will retry: " + ex.GetBaseException().Message);
}
}
private static object CreateBoneMenuPage(MethodInfo method, object parent, string name, System.Type colorType, object color)
{
ParameterInfo[] parameters = ((MethodBase)method).GetParameters();
object[] array = Enumerable.ToArray<object>(Enumerable.Select<ParameterInfo, object>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, object>)((ParameterInfo p) => p.HasDefaultValue ? p.DefaultValue : (p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null))));
for (int num = 0; num < parameters.Length; num++)
{
if (parameters[num].ParameterType == typeof(string))
{
array[num] = name;
}
else if (colorType != (System.Type)null && parameters[num].ParameterType == colorType && color != null)
{
array[num] = color;
}
}
return ((MethodBase)method).Invoke(parent, array);
}
private static object CreateBoneMenuBool(MethodInfo method, object page, string name, System.Type colorType, object color, bool value, Action<bool> callback)
{
ParameterInfo[] parameters = ((MethodBase)method).GetParameters();
object[] array = Enumerable.ToArray<object>(Enumerable.Select<ParameterInfo, object>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, object>)((ParameterInfo p) => p.HasDefaultValue ? p.DefaultValue : (p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null))));
for (int num = 0; num < parameters.Length; num++)
{
if (parameters[num].ParameterType == typeof(string))
{
array[num] = name;
}
else if (parameters[num].ParameterType == typeof(bool))
{
array[num] = value;
}
else if (colorType != (System.Type)null && parameters[num].ParameterType == colorType && color != null)
{
array[num] = color;
}
else if (typeof(System.Delegate).IsAssignableFrom(parameters[num].ParameterType))
{
array[num] = callback;
}
}
return ((MethodBase)method).Invoke(page, array);
}
private static void CreateBoneMenuFloat(MethodInfo method, object page, string name, System.Type colorType, object color, float value, float increment, float min, float max, Action<float> callback)
{
ParameterInfo[] parameters = ((MethodBase)method).GetParameters();
object[] array = Enumerable.ToArray<object>(Enumerable.Select<ParameterInfo, object>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, object>)((ParameterInfo p) => p.HasDefaultValue ? p.DefaultValue : (p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null))));
float[] array2 = new float[4] { value, increment, min, max };
int num = 0;
for (int num2 = 0; num2 < parameters.Length; num2++)
{
if (parameters[num2].ParameterType == typeof(string))
{
array[num2] = name;
}
else if (parameters[num2].ParameterType == typeof(float) && num < array2.Length)
{
array[num2] = array2[num++];
}
else if (colorType != (System.Type)null && parameters[num2].ParameterType == colorType && color != null)
{
array[num2] = color;
}
else if (typeof(System.Delegate).IsAssignableFrom(parameters[num2].ParameterType))
{
array[num2] = callback;
}
}
((MethodBase)method).Invoke(page, array);
}
private static void AddMuzzleFlashStyleToggles(MethodInfo createBool, object page, System.Type colorType, object color)
{
MuzzleFlashStyle[] array = (MuzzleFlashStyle[])System.Enum.GetValues(typeof(MuzzleFlashStyle));
for (int i = 0; i < array.Length; i++)
{
MuzzleFlashStyle style = array[i];
int index = i;
string name = style switch
{
MuzzleFlashStyle.Standard => "Standard",
MuzzleFlashStyle.CompactBurst => "Compact Burst",
MuzzleFlashStyle.TaperedCone => "Tapered Cone",
MuzzleFlashStyle.SplitJet => "Split Jet",
MuzzleFlashStyle.Smoke => "Smoke",
_ => "Smoke",
};
muzzleStyleMenuElements[index] = CreateBoneMenuBool(createBool, page, name, colorType, color, muzzleFlashStyle == style, delegate(bool enabled)
{
if (enabled)
{
SelectMuzzleFlashStyle(style);
}
else if (muzzleFlashStyle == style && muzzleStyleMenuElements[index] != null)
{
Set(muzzleStyleMenuElements[index], "Value", true);
}
});
}
}
private static void SelectMuzzleFlashStyle(MuzzleFlashStyle style)
{
muzzleFlashStyle = style;
for (int i = 0; i < muzzleStyleMenuElements.Length; i++)
{
if (muzzleStyleMenuElements[i] != null)
{
Set(muzzleStyleMenuElements[i], "Value", i == (int)style);
}
}
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg($"Selected muzzle flash style: {style}.");
}
}
private void TrySubscribeToGunFire()
{
try
{
EventInfo val = Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType("BoneLib.Hooking", false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null))?.GetEvent("OnPostFireGun", (BindingFlags)24);
if (!(val == (EventInfo)null))
{
MethodInfo method = val.EventHandlerType.GetMethod("Invoke");
ParameterExpression val2 = Expression.Parameter(((MethodBase)method).GetParameters()[0].ParameterType, "gun");
MethodInfo method2 = typeof(Mod).GetMethod("OnGunFired", (BindingFlags)40);
fireHandler = Expression.Lambda(val.EventHandlerType, (Expression)(object)Expression.Call(method2, (Expression)(object)Expression.Convert((Expression)(object)val2, typeof(object))), (ParameterExpression[])(object)new ParameterExpression[1] { val2 }).Compile();
val.AddEventHandler((object)null, fireHandler);
eventSubscribed = true;
((MelonBase)this).LoggerInstance.Msg("Connected to BoneLib gun-fire events.");
}
}
catch (System.Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Gun-fire hook unavailable: " + ex.GetBaseException().Message);
}
}
private static void OnGunFired(object gun)
{
if (gun != null)
{
pendingGunFires.Enqueue(gun);
}
}
private static void ProcessPendingGunFires()
{
int num = 0;
object gun = default(object);
while (num < 32 && pendingGunFires.TryDequeue(ref gun))
{
num++;
HandleGunFired(gun);
}
}
private static void HandleGunFired(object gun)
{
try
{
if (gun == null)
{
return;
}
if (!shotHookObservedLogged)
{
shotHookObservedLogged = true;
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg("Received the first gun-fire event; processing enabled Realism effects.");
}
}
bool flag = IsRemoteGunShot(gun);
if (flag && !remoteShotObservedLogged)
{
remoteShotObservedLogged = true;
Mod mod2 = instance;
if (mod2 != null)
{
((MelonBase)mod2).LoggerInstance.Msg("Received a replicated Fusion gun shot; rendering local Realism effects for it.");
}
}
gameObjectType = FindType("UnityEngine.GameObject");
unityObject = FindType("UnityEngine.Object");
vector3Type = FindType("UnityEngine.Vector3");
bool fusionActive = FindType("LabFusion.Entities.NetworkPlayerManager") != (System.Type)null;
if (muzzleFlashEnabled || sparksEnabled || smokeEnabled || tracersEnabled)
{
try
{
SpawnShotVisuals(gun, muzzleFlashEnabled, sparksEnabled, smokeEnabled, tracersEnabled, fusionActive);
if (flag && !remoteVisualsLogged)
{
remoteVisualsLogged = true;
Mod mod3 = instance;
if (mod3 != null)
{
((MelonBase)mod3).LoggerInstance.Msg("Generated the enabled Realism visual effects for the first replicated Fusion shot.");
}
}
}
catch (System.Exception error)
{
LogEffectError(ref visualErrorLogged, "muzzle flash/sparks/smoke/tracer", error);
}
}
if (!earRingingEnabled || !ShouldRingForShot(gun, flag))
{
return;
}
try
{
RaiseRinging();
if (flag && !remoteRingingLogged)
{
remoteRingingLogged = true;
Mod mod4 = instance;
if (mod4 != null)
{
((MelonBase)mod4).LoggerInstance.Msg("Applied Realism ear ringing for the first replicated Fusion shot.");
}
}
}
catch (System.Exception error2)
{
LogEffectError(ref audioErrorLogged, "audio", error2);
}
}
catch (System.Exception ex)
{
if (!shotErrorLogged)
{
shotErrorLogged = true;
Mod mod5 = instance;
if (mod5 != null)
{
((MelonBase)mod5).LoggerInstance.Warning("Realism shot effect failed: " + ex.GetBaseException().Message);
}
}
}
}
private static System.Type FindType(string fullName)
{
return Enumerable.FirstOrDefault<System.Type>(Enumerable.Select<Assembly, System.Type>((System.Collections.Generic.IEnumerable<Assembly>)AppDomain.CurrentDomain.GetAssemblies(), (Func<Assembly, System.Type>)((Assembly a) => a.GetType(fullName, false))), (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null));
}
private static bool IsUnityObjectAlive(object value)
{
if (value == null)
{
return false;
}
System.Type objectType = FindType("UnityEngine.Object");
if (objectType == (System.Type)null || !objectType.IsInstanceOfType(value))
{
return true;
}
MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)objectType.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "op_Equality" && ((MethodBase)m).GetParameters().Length == 2 && Enumerable.All<ParameterInfo>((System.Collections.Generic.IEnumerable<ParameterInfo>)((MethodBase)m).GetParameters(), (Func<ParameterInfo, bool>)((ParameterInfo p) => p.ParameterType == objectType))));
try
{
return val == (MethodInfo)null || !Convert.ToBoolean(((MethodBase)val).Invoke((object)null, new object[2] { value, null }));
}
catch
{
return false;
}
}
private static void ResetRingingAudio()
{
if (IsUnityObjectAlive(ringingGameObject))
{
Destroy(ringingGameObject, 0f);
}
else if (IsUnityObjectAlive(ringingClip))
{
Destroy(ringingClip, 0f);
}
ringingGameObject = (ringingSource = (ringingClip = null));
ringingLevel = (ringingVolume = 0f);
ringingUpdated = System.DateTime.MinValue;
}
private static bool IsRemoteGunShot(object gun)
{
if (FindType("LabFusion.Entities.NetworkPlayerManager") == (System.Type)null)
{
return false;
}
try
{
return IsRemoteFiringHand(GetFiringHand(gun));
}
catch
{
return false;
}
}
private static bool ShouldRingForShot(object gun, bool isRemoteShot)
{
if (!isRemoteShot)
{
return true;
}
try
{
System.Type type = FindType("BoneLib.Player");
object obj;
if (type == null)
{
obj = null;
}
else
{
PropertyInfo property = type.GetProperty("Head", (BindingFlags)24);
obj = ((property != null) ? property.GetValue((object)null) : null);
}
object o = obj;
object obj2 = Get(o, "position");
if (obj2 == null)
{
object obj3;
if (type == null)
{
obj3 = null;
}
else
{
PropertyInfo property2 = type.GetProperty("RigManager", (BindingFlags)24);
obj3 = ((property2 != null) ? property2.GetValue((object)null) : null);
}
object o2 = obj3;
obj2 = Get(Get(o2, "transform"), "position");
}
object obj4 = Get(GetFireTransform(gun), "position");
vector3Type = vector3Type ?? FindType("UnityEngine.Vector3");
if (obj2 == null || obj4 == null || vector3Type == (System.Type)null)
{
return false;
}
MethodInfo method = vector3Type.GetMethod("Distance", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
if (method == (MethodInfo)null)
{
return false;
}
float num = Convert.ToSingle(((MethodBase)method).Invoke((object)null, new object[2] { obj2, obj4 }));
if (num <= 18f)
{
return true;
}
if (!remoteDistantRingingSuppressedLogged)
{
remoteDistantRingingSuppressedLogged = true;
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg($"Suppressed distant Fusion ear ringing ({num:0.0} units away; limit {18f:0} units).");
}
}
return false;
}
catch
{
return false;
}
}
private static void LogEffectError(ref bool alreadyLogged, string effect, System.Exception error)
{
if (!alreadyLogged)
{
alreadyLogged = true;
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Warning("Realism " + effect + " failed: " + error.GetBaseException().Message);
}
}
}
private static object Get(object o, string name)
{
if (o == null)
{
return null;
}
PropertyInfo property = o.GetType().GetProperty(name, (BindingFlags)52);
object obj = ((property != null) ? property.GetValue(o) : null);
if (obj == null)
{
FieldInfo field = o.GetType().GetField(name, (BindingFlags)52);
obj = ((field != null) ? field.GetValue(o) : null);
}
return obj;
}
private static object Call(object o, string name, params object[] args)
{
object result;
if (o == null)
{
result = null;
}
else
{
MethodInfo obj = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)o.GetType().GetMethods((BindingFlags)20), (Func<MethodInfo, bool>)delegate(MethodInfo m)
{
if (((MemberInfo)m).Name != name || ((MethodBase)m).GetParameters().Length != args.Length)
{
return false;
}
ParameterInfo[] parameters = ((MethodBase)m).GetParameters();
return Enumerable.All<bool>(Enumerable.Select<ParameterInfo, bool>((System.Collections.Generic.IEnumerable<ParameterInfo>)parameters, (Func<ParameterInfo, int, bool>)((ParameterInfo p, int i) => args[i] == null || p.ParameterType.IsInstanceOfType(args[i]) || (args[i] is System.Type && p.ParameterType == typeof(System.Type)))), (Func<bool, bool>)((bool ok) => ok));
});
result = ((obj != null) ? ((MethodBase)obj).Invoke(o, args) : null);
}
return result;
}
private static object AddUnityComponent(object gameObject, System.Type componentType)
{
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
if (gameObject == null || componentType == (System.Type)null)
{
return null;
}
MethodInfo[] methods = gameObject.GetType().GetMethods((BindingFlags)20);
System.Exception ex = null;
System.Collections.Generic.IEnumerator<MethodInfo> enumerator = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "AddComponent" && ((MethodBase)m).IsGenericMethodDefinition && ((MethodBase)m).GetParameters().Length == 0)).GetEnumerator();
try
{
while (((System.Collections.IEnumerator)enumerator).MoveNext())
{
MethodInfo current = enumerator.Current;
try
{
return ((MethodBase)current.MakeGenericMethod(new System.Type[1] { componentType })).Invoke(gameObject, (object[])null);
}
catch (System.Exception ex2)
{
ex = ex2.GetBaseException();
}
}
}
finally
{
((System.IDisposable)enumerator)?.Dispose();
}
System.Collections.Generic.IEnumerator<MethodInfo> enumerator2 = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "AddComponent" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))).GetEnumerator();
try
{
while (((System.Collections.IEnumerator)enumerator2).MoveNext())
{
MethodInfo current2 = enumerator2.Current;
try
{
return ((MethodBase)current2).Invoke(gameObject, new object[1] { componentType });
}
catch (System.Exception ex3)
{
ex = ex3.GetBaseException();
}
}
}
finally
{
((System.IDisposable)enumerator2)?.Dispose();
}
throw new InvalidOperationException("Unity AddComponent could not create " + componentType.FullName + ".", (System.Exception)(((object)ex) ?? ((object)new MissingMethodException(gameObject.GetType().FullName, "AddComponent<T>()"))));
}
private static object GetUnityComponent(object gameObject, System.Type componentType)
{
if (gameObject == null || componentType == (System.Type)null)
{
return null;
}
MethodInfo[] methods = gameObject.GetType().GetMethods((BindingFlags)20);
System.Collections.Generic.IEnumerator<MethodInfo> enumerator = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "GetComponent" && ((MethodBase)m).IsGenericMethodDefinition && ((MethodBase)m).GetParameters().Length == 0)).GetEnumerator();
try
{
while (((System.Collections.IEnumerator)enumerator).MoveNext())
{
MethodInfo current = enumerator.Current;
try
{
return ((MethodBase)current.MakeGenericMethod(new System.Type[1] { componentType })).Invoke(gameObject, (object[])null);
}
catch
{
}
}
}
finally
{
((System.IDisposable)enumerator)?.Dispose();
}
System.Collections.Generic.IEnumerator<MethodInfo> enumerator2 = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "GetComponent" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))).GetEnumerator();
try
{
while (((System.Collections.IEnumerator)enumerator2).MoveNext())
{
MethodInfo current2 = enumerator2.Current;
try
{
return ((MethodBase)current2).Invoke(gameObject, new object[1] { componentType });
}
catch
{
}
}
}
finally
{
((System.IDisposable)enumerator2)?.Dispose();
}
return null;
}
private static object FindUnityObject(System.Type targetType)
{
System.Type type = FindType("UnityEngine.Object");
if (type == (System.Type)null || targetType == (System.Type)null)
{
return null;
}
MethodInfo[] methods = type.GetMethods((BindingFlags)24);
System.Collections.Generic.IEnumerator<MethodInfo> enumerator = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "FindObjectOfType" && ((MethodBase)m).IsGenericMethodDefinition && ((MethodBase)m).GetParameters().Length == 0)).GetEnumerator();
try
{
while (((System.Collections.IEnumerator)enumerator).MoveNext())
{
MethodInfo current = enumerator.Current;
try
{
return ((MethodBase)current.MakeGenericMethod(new System.Type[1] { targetType })).Invoke((object)null, (object[])null);
}
catch
{
}
}
}
finally
{
((System.IDisposable)enumerator)?.Dispose();
}
System.Collections.Generic.IEnumerator<MethodInfo> enumerator2 = Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)methods, (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "FindObjectOfType" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))).GetEnumerator();
try
{
while (((System.Collections.IEnumerator)enumerator2).MoveNext())
{
MethodInfo current2 = enumerator2.Current;
try
{
return ((MethodBase)current2).Invoke((object)null, new object[1] { targetType });
}
catch
{
}
}
}
finally
{
((System.IDisposable)enumerator2)?.Dispose();
}
return null;
}
private static object NewVector(float x, float y, float z)
{
return Activator.CreateInstance(vector3Type, new object[3] { x, y, z });
}
private static object GetFireTransform(object gun)
{
return Get(gun, "firePointTransform") ?? FindMuzzleTransform(Get(gun, "transform")) ?? Get(gun, "transform");
}
private static bool IsMobilePlatform()
{
if (mobilePlatformCache.HasValue)
{
return mobilePlatformCache.Value;
}
try
{
PropertyInfo val = FindType("UnityEngine.Application")?.GetProperty("isMobilePlatform", (BindingFlags)24);
mobilePlatformCache = Convert.ToBoolean(((val != null) ? val.GetValue((object)null) : null) ?? ((object)false));
}
catch
{
mobilePlatformCache = false;
}
return mobilePlatformCache.Value;
}
private static void SpawnShotVisuals(object gun, bool spawnMuzzleFlash, bool spawnSparks, bool spawnSmoke, bool spawnTracer, bool fusionActive)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
object fireTransform = GetFireTransform(gun);
object obj = Get(fireTransform, "position");
object obj2 = Get(fireTransform, "forward");
if (obj == null || obj2 == null)
{
throw new InvalidOperationException("Gun firePointTransform was unavailable.");
}
object obj3 = Get(fireTransform, "right");
object obj4 = Get(fireTransform, "up");
object obj5 = OffsetVector(obj, obj2, 0.025f);
MuzzleFlashStyle muzzleFlashStyle = Mod.muzzleFlashStyle;
if (spawnMuzzleFlash)
{
SpawnMuzzleFlash(obj5, obj2, obj3, obj4, muzzleFlashStyle);
if (muzzleFlashStylesLogged.Add(muzzleFlashStyle))
{
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg($"Rendered muzzle flash profile: {muzzleFlashStyle}.");
}
}
}
bool flag = IsMobilePlatform();
if (spawnSparks && (!spawnMuzzleFlash || muzzleFlashStyle != MuzzleFlashStyle.Smoke))
{
int num = (flag ? 3 : 8);
for (int i = 0; i < num; i++)
{
float rightScale = (float)(effectRandom.NextDouble() * 1.6 - 0.8);
float upScale = (float)(effectRandom.NextDouble() * 1.6 - 0.8);
float forwardScale = 0.35f + (float)effectRandom.NextDouble() * 0.65f;
object direction = CombineDirections(obj2, obj3, rightScale, obj4, upScale, forwardScale);
SpawnSpark(obj5, direction, 0.21f + (float)effectRandom.NextDouble() * 0.19f);
}
}
if (spawnSmoke && (!spawnMuzzleFlash || muzzleFlashStyle != MuzzleFlashStyle.Smoke))
{
int num2 = 3;
float num3 = 1f;
float num4 = 1f;
float num5 = 0.038f;
float num6 = 0.2f;
switch (muzzleFlashStyle)
{
case MuzzleFlashStyle.CompactBurst:
num2 = (flag ? 1 : 2);
num3 = 0.72f;
num4 = 0.78f;
num5 = 0.022f;
num6 = 0.12f;
break;
case MuzzleFlashStyle.TaperedCone:
num2 = (flag ? 3 : 5);
num3 = 1.2f;
num4 = 1.25f;
num5 = 0.034f;
num6 = 0.2f;
break;
case MuzzleFlashStyle.SplitJet:
num2 = (flag ? 2 : 4);
num3 = 1.04f;
num4 = 1.08f;
num5 = 0.09f;
num6 = 1.15f;
break;
}
for (int j = 0; j < num2; j++)
{
float distance = ((num2 == 1) ? 0f : (((float)j - (float)(num2 - 1) * 0.5f) * num5));
float distance2 = (float)(effectRandom.NextDouble() * 0.025 - 0.0125);
object position = OffsetVector(OffsetVector(OffsetVector(obj5, obj3, distance), obj4, distance2), obj2, 0.025f * (float)j);
float rightScale2 = (float)(effectRandom.NextDouble() * 0.07 - 0.035) * num6;
object velocity = CombineDirections(obj2, obj3, rightScale2, obj4, 0.045f + (float)effectRandom.NextDouble() * 0.035f, 0.025f);
SpawnSmoke(position, (0.055f + 0.008f * (float)j) * num3, (0.5f + 0.08f * (float)j) * num4, velocity);
}
}
if (spawnTracer)
{
ProjectileCandidate projectileCandidate = FindFiredProjectile(obj5, obj2);
object start = projectileCandidate?.Position ?? OffsetVector(obj5, obj2, flag ? 0.09f : 0.12f);
SpawnTracer(start, projectileCandidate?.Direction ?? obj2, fusionActive, projectileCandidate);
}
}
private static void SpawnMuzzleFlash(object position, object direction, object right, object up, MuzzleFlashStyle style)
{
switch (style)
{
case MuzzleFlashStyle.CompactBurst:
{
object obj = OffsetVector(position, direction, 0.045f);
SpawnFlashOrb(obj, direction, 0.17f, 0.17f, 0.15f, 1f, 0.96f, 0.72f, 22f, 0.19f);
SpawnFlashCapsule(OffsetVector(obj, right, -0.075f), CombineDirections(direction, right, -1.55f), 0.095f, 0.38f, 1f, 0.64f, 0.18f, 15f, 0.18f);
SpawnFlashCapsule(OffsetVector(obj, right, 0.075f), CombineDirections(direction, right, 1.55f), 0.095f, 0.38f, 1f, 0.64f, 0.18f, 15f, 0.18f);
SpawnFlashCapsule(OffsetVector(obj, up, -0.075f), CombineDirections(direction, up, -1.55f), 0.095f, 0.38f, 1f, 0.72f, 0.22f, 15f, 0.18f);
SpawnFlashCapsule(OffsetVector(obj, up, 0.075f), CombineDirections(direction, up, 1.55f), 0.095f, 0.38f, 1f, 0.72f, 0.22f, 15f, 0.18f);
AddMuzzleLight(position, 1f, 0.72f, 0.38f, 7f, 4.2f, 0.17f);
break;
}
case MuzzleFlashStyle.TaperedCone:
SpawnFlashOrb(OffsetVector(position, direction, 0.045f), direction, 0.105f, 0.105f, 0.14f, 1f, 0.98f, 0.78f, 24f, 0.19f);
SpawnFlashCylinder(OffsetVector(position, direction, 0.16f), direction, 0.205f, 0.28f, 1f, 0.69f, 0.2f, 18f, 0.18f);
SpawnFlashCylinder(OffsetVector(position, direction, 0.37f), direction, 0.145f, 0.3f, 1f, 0.52f, 0.11f, 14f, 0.18f);
SpawnFlashCylinder(OffsetVector(position, direction, 0.59f), direction, 0.082f, 0.28f, 1f, 0.35f, 0.065f, 10f, 0.17f);
AddMuzzleLight(position, 1f, 0.48f, 0.16f, 6.8f, 4.4f, 0.17f);
break;
case MuzzleFlashStyle.SplitJet:
SpawnFlashOrb(OffsetVector(position, direction, 0.045f), direction, 0.11f, 0.11f, 0.13f, 1f, 0.98f, 0.78f, 22f, 0.19f);
SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.13f), right, -0.09f), CombineDirections(direction, right, -1.85f), 0.135f, 0.64f, 1f, 0.43f, 0.075f, 16f, 0.18f);
SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.13f), right, 0.09f), CombineDirections(direction, right, 1.85f), 0.135f, 0.64f, 1f, 0.43f, 0.075f, 16f, 0.18f);
SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.34f), right, -0.24f), CombineDirections(direction, right, -2.65f), 0.075f, 0.34f, 1f, 0.43f, 0.075f, 12f, 0.17f);
SpawnFlashCapsule(OffsetVector(OffsetVector(position, direction, 0.34f), right, 0.24f), CombineDirections(direction, right, 2.65f), 0.075f, 0.34f, 1f, 0.43f, 0.075f, 12f, 0.17f);
AddMuzzleLight(position, 1f, 0.55f, 0.22f, 7f, 4.2f, 0.17f);
break;
case MuzzleFlashStyle.Smoke:
SpawnSmokeOnlyFlash(position, direction, right, up);
break;
default:
SpawnGlow(position, direction, right, up);
break;
}
}
private static System.Type[] GetProjectileTypes()
{
//IL_0070: Expected O, but got Unknown
if (projectileTypesScanned)
{
return projectileTypes;
}
projectileTypesScanned = true;
System.Type type = FindType("UnityEngine.Component");
if (type == (System.Type)null)
{
return projectileTypes;
}
List<System.Type> val = new List<System.Type>();
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly val2 in assemblies)
{
System.Type[] array;
try
{
array = val2.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
ReflectionTypeLoadException ex2 = ex;
array = Enumerable.ToArray<System.Type>(Enumerable.Where<System.Type>((System.Collections.Generic.IEnumerable<System.Type>)ex2.Types, (Func<System.Type, bool>)((System.Type t) => t != (System.Type)null)));
}
catch
{
continue;
}
System.Type[] array2 = array;
foreach (System.Type type2 in array2)
{
if (!(type2 == (System.Type)null) && !type2.IsAbstract && !type2.ContainsGenericParameters && type.IsAssignableFrom(type2) && ((MemberInfo)type2).Name.IndexOf("Projectile", (StringComparison)5) >= 0)
{
val.Add(type2);
}
}
}
projectileTypes = Enumerable.ToArray<System.Type>((System.Collections.Generic.IEnumerable<System.Type>)Enumerable.OrderBy<System.Type, int>((System.Collections.Generic.IEnumerable<System.Type>)val, (Func<System.Type, int>)((System.Type t) => (!((MemberInfo)t).Name.Equals("Projectile", (StringComparison)5)) ? 1 : 0)));
return projectileTypes;
}
private static ProjectileCandidate FindFiredProjectile(object muzzle, object forward)
{
System.Type type = FindType("UnityEngine.Object");
System.Type type2 = FindType("UnityEngine.Rigidbody");
MethodInfo method = vector3Type.GetMethod("Distance", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
MethodInfo method2 = vector3Type.GetMethod("Dot", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
if (type == (System.Type)null || type2 == (System.Type)null || method == (MethodInfo)null || method2 == (MethodInfo)null)
{
return null;
}
MethodInfo[] array = Enumerable.ToArray<MethodInfo>(Enumerable.Where<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "FindObjectsOfType" && !((MethodBase)m).IsGenericMethod && ((MethodBase)m).GetParameters().Length >= 1 && ((MethodBase)m).GetParameters()[0].ParameterType == typeof(System.Type))));
ProjectileCandidate projectileCandidate = null;
float num = 3.4028235E+38f;
System.Type[] array2 = GetProjectileTypes();
foreach (System.Type type3 in array2)
{
object obj = null;
MethodInfo[] array3 = array;
foreach (MethodInfo val in array3)
{
try
{
ParameterInfo[] parameters = ((MethodBase)val).GetParameters();
obj = ((MethodBase)val).Invoke((object)null, (parameters.Length != 1) ? new object[2] { type3, false } : new object[1] { type3 });
if (obj != null)
{
break;
}
}
catch
{
}
}
if (!(obj is System.Collections.IEnumerable enumerable))
{
continue;
}
foreach (object item in enumerable)
{
if (item == null)
{
continue;
}
object obj3 = Get(item, "transform");
object unityComponent = GetUnityComponent(item, type2);
if (obj3 == null || unityComponent == null)
{
continue;
}
object obj4 = Get(obj3, "position");
object o = Get(unityComponent, "velocity") ?? Get(unityComponent, "linearVelocity");
float num4 = Convert.ToSingle(Get(o, "magnitude") ?? ((object)0f));
if (obj4 == null || num4 < 5f)
{
continue;
}
float num5 = Convert.ToSingle(((MethodBase)method).Invoke((object)null, new object[2] { muzzle, obj4 }));
if (num5 > 2.25f)
{
continue;
}
object obj5 = Get(o, "normalized") ?? Get(obj3, "forward");
float num6 = Convert.ToSingle(((MethodBase)method2).Invoke((object)null, new object[2] { forward, obj5 }));
if (!(num6 < 0.72f))
{
float num7 = num5 + (1f - num6) * 0.35f;
if (!(num7 >= num))
{
num = num7;
projectileCandidate = new ProjectileCandidate
{
Projectile = item,
Transform = obj3,
Rigidbody = unityComponent,
Position = obj4,
Direction = obj5,
Speed = num4
};
}
}
}
if (projectileCandidate != null)
{
break;
}
}
if (projectileCandidate != null && !tracerProjectileLookupLogged)
{
tracerProjectileLookupLogged = true;
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg($"Found the first live Marrow projectile ({projectileCandidate.Speed:0} units/s); its tracer will follow the projectile.");
}
}
return projectileCandidate;
}
private static void SpawnTracer(object start, object direction, bool fusionActive, ProjectileCandidate projectile)
{
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
object obj = null;
object obj2 = null;
object obj3 = null;
try
{
int num = (IsMobilePlatform() ? 3 : 10);
while (tracers.Count >= num)
{
TracerEffect tracerEffect = tracers[0];
Destroy(tracerEffect.GameObject, 0f);
Destroy(tracerEffect.OuterLineGameObject, 0f);
Destroy(tracerEffect.CoreLineGameObject, 0f);
tracers.RemoveAt(0);
}
System.Type type = FindType("UnityEngine.PrimitiveType");
object obj4 = System.Enum.Parse(type, "Sphere");
MethodInfo method = gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24);
obj = ((MethodBase)method).Invoke((object)null, new object[1] { obj4 });
obj2 = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] tracer glow" });
obj3 = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] tracer core" });
object obj5 = Get(obj, "transform");
RemovePrimitiveCollider(obj);
System.Type type2 = FindType("UnityEngine.LineRenderer");
if (type2 == (System.Type)null)
{
throw new InvalidOperationException("Unity LineRenderer was unavailable.");
}
object obj6 = AddUnityComponent(obj2, type2);
object obj7 = AddUnityComponent(obj3, type2);
float num2 = (fusionActive ? 1.15f : 1f);
float num3 = 0.018f * num2;
float num4 = 0.004f * num2;
float num5 = 0.024f * num2;
float num6 = 0.0015f * num2;
float num7 = 0.005f * num2;
object obj8 = Normalize(direction);
Set(obj5, "position", start);
Set(obj5, "localScale", NewVector(num3, num3, num3));
DisableShadows(obj);
ConfigureTracerLine(obj6, num4, num5, 1.6f, 0.72f, 0.04f, 3.5f, 0.48f);
ConfigureTracerLine(obj7, num6, num7, 2.4f, 1.9f, 0.75f, 4.8f);
SetTracerLinePoints(obj6, OffsetVector(start, obj8, -1.2f), start);
SetTracerLinePoints(obj7, OffsetVector(start, obj8, -1.2f), start);
ApplyTracerMaterial(obj, 2.4f, 1.95f, 0.85f, 5f);
if (!IsMobilePlatform())
{
if (IsMobilePlatform() && muzzleFlashStyle != MuzzleFlashStyle.Standard)
{
return;
}
System.Type type3 = FindType("UnityEngine.Light");
if (type3 != (System.Type)null)
{
object o = AddUnityComponent(obj, type3);
Set(o, "intensity", 2.2f * num2);
Set(o, "range", 1.4f * num2);
Set(o, "color", Activator.CreateInstance(FindType("UnityEngine.Color"), new object[4] { 1f, 0.72f, 0.32f, 1f }));
System.Type type4 = FindType("UnityEngine.LightShadows");
if (type4 != (System.Type)null)
{
Set(o, "shadows", System.Enum.Parse(type4, "None"));
}
}
}
bool flag = projectile != null;
tracers.Add(new TracerEffect
{
GameObject = obj,
OuterLineGameObject = obj2,
CoreLineGameObject = obj3,
Transform = obj5,
OuterLine = obj6,
CoreLine = obj7,
Origin = start,
Direction = (flag ? projectile.Direction : obj8),
Started = System.DateTime.UtcNow,
Length = 1.2f,
Speed = (flag ? projectile.Speed : 85f),
Life = (flag ? 1.5f : 0.26f),
HeadSize = num3,
OuterStartWidth = num4,
OuterEndWidth = num5,
CoreStartWidth = num6,
CoreEndWidth = num7,
Projectile = (flag ? projectile.Projectile : null),
ProjectileTransform = (flag ? projectile.Transform : null),
ProjectileBody = (flag ? projectile.Rigidbody : null),
LastPosition = start,
TrackingProjectile = flag
});
if (!tracerSpawnLogged)
{
tracerSpawnLogged = true;
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg("Spawned a gold tracer with a bright core and tapered 3D glow.");
}
}
}
catch
{
Destroy(obj, 0f);
Destroy(obj2, 0f);
Destroy(obj3, 0f);
throw;
}
}
private static void ConfigureTracerLine(object line, float startWidth, float endWidth, float r, float g, float b, float emission, float alpha = 1f)
{
Set(line, "useWorldSpace", true);
Set(line, "positionCount", 2);
Set(line, "startWidth", startWidth);
Set(line, "endWidth", endWidth);
Set(line, "numCapVertices", 4);
Set(line, "numCornerVertices", 2);
System.Type type = FindType("UnityEngine.LineAlignment");
if (type != (System.Type)null)
{
try
{
Set(line, "alignment", System.Enum.Parse(type, "View"));
}
catch
{
}
}
ApplyTracerMaterial(line, r, g, b, emission, alpha);
}
private static void SetTracerLinePoints(object line, object tail, object head)
{
Call(line, "SetPosition", 0, tail);
Call(line, "SetPosition", 1, head);
}
private static void ApplyTracerMaterial(object obj, float r, float g, float b, float emission, float alpha = 1f)
{
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_033d: Unknown result type (might be due to invalid IL or missing references)
string text = $"{r:R}|{g:R}|{b:R}|{emission:R}|{alpha:R}";
System.Type type = FindType("UnityEngine.Renderer");
object value = default(object);
if (tracerMaterialCache.TryGetValue(text, ref value))
{
object obj2 = ((type != (System.Type)null && type.IsInstanceOfType(obj)) ? obj : GetUnityComponent(obj, type));
if (obj2 == null)
{
throw new InvalidOperationException("Tracer primitive has no MeshRenderer.");
}
Set(obj2, "enabled", true);
Set(obj2, "material", value);
return;
}
System.Type type2 = FindType("UnityEngine.Shader");
MethodInfo method = type2.GetMethod("Find", (BindingFlags)24);
object obj3 = null;
string text2 = null;
string[] array = new string[6] { "Particles/Additive", "Legacy Shaders/Particles/Additive", "Unlit/Color", "Universal Render Pipeline/Unlit", "Sprites/Default", "Standard" };
foreach (string text3 in array)
{
obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[1] { text3 }) : null);
if (obj3 != null)
{
text2 = text3;
break;
}
}
if (obj3 == null)
{
throw new InvalidOperationException("Unity could not find a tracer shader.");
}
object obj4 = Activator.CreateInstance(FindType("UnityEngine.Material"), new object[1] { obj3 });
System.Type type3 = FindType("UnityEngine.Color");
object obj5 = Activator.CreateInstance(type3, new object[4] { r, g, b, alpha });
Set(obj4, "color", obj5);
Call(obj4, "SetColor", "_TintColor", obj5);
Call(obj4, "EnableKeyword", "_EMISSION");
Call(obj4, "SetColor", "_EmissionColor", Activator.CreateInstance(type3, new object[4]
{
r * emission,
g * emission,
b * emission,
alpha
}));
Call(obj4, "SetFloat", "_Metallic", 0.05f);
Call(obj4, "SetFloat", "_Glossiness", 0.45f);
object obj6 = ((type != (System.Type)null && type.IsInstanceOfType(obj)) ? obj : GetUnityComponent(obj, type));
if (obj6 == null)
{
throw new InvalidOperationException("Tracer effect has no renderer.");
}
Set(obj6, "enabled", true);
Set(obj6, "material", obj4);
tracerMaterialCache[text] = obj4;
if (!tracerShaderLogged)
{
tracerShaderLogged = true;
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg("Tracer material shader selected: " + text2 + ".");
}
}
}
private static void SpawnSpark(object start, object direction, float length)
{
int num = (IsMobilePlatform() ? 12 : 36);
while (sparks.Count >= num)
{
SparkEffect sparkEffect = sparks[0];
Destroy(sparkEffect.GameObject, 0f);
Destroy(sparkEffect.TailGameObject, 0f);
sparks.RemoveAt(0);
}
object obj = null;
object obj2 = null;
try
{
System.Type type = FindType("UnityEngine.PrimitiveType");
object obj3 = System.Enum.Parse(type, "Sphere");
MethodInfo method = gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24);
obj = ((MethodBase)method).Invoke((object)null, new object[1] { obj3 });
obj2 = ((MethodBase)method).Invoke((object)null, new object[1] { obj3 });
object obj4 = Get(obj, "transform");
object obj5 = Get(obj2, "transform");
RemovePrimitiveCollider(obj);
RemovePrimitiveCollider(obj2);
DisableShadows(obj);
DisableShadows(obj2);
Set(obj4, "position", start);
Set(obj5, "position", OffsetVector(start, direction, (0f - length) * 0.2f));
float num2 = 0.028f + (float)effectRandom.NextDouble() * 0.01f;
float num3 = 0.014f + (float)effectRandom.NextDouble() * 0.004f;
Set(obj4, "localScale", NewVector(num2, num2, num2));
Set(obj5, "localScale", NewVector(num3, num3, length * 0.66f));
System.Type type2 = FindType("UnityEngine.Quaternion");
MethodInfo method2 = type2.GetMethod("LookRotation", (BindingFlags)24, (Binder)null, new System.Type[1] { vector3Type }, (ParameterModifier[])null);
object obj6 = ((method2 != null) ? ((MethodBase)method2).Invoke((object)null, new object[1] { direction }) : null);
if (obj6 != null)
{
Set(obj4, "rotation", obj6);
Set(obj5, "rotation", obj6);
}
ApplyMaterial(obj, 1f, 0.97f, 0.78f, 1f, 9f, transparent: false);
ApplyMaterial(obj2, 1f, 0.56f, 0.16f, 1f, 6f, transparent: false);
sparks.Add(new SparkEffect
{
GameObject = obj,
TailGameObject = obj2,
Transform = obj4,
TailTransform = obj5,
Origin = start,
Direction = direction,
Started = System.DateTime.UtcNow,
Life = 0.2f,
Length = length,
Speed = 2.5f + (float)effectRandom.NextDouble() * 2.5f,
HeadSize = num2,
TailWidth = num3
});
}
catch
{
Destroy(obj, 0f);
Destroy(obj2, 0f);
throw;
}
}
private static object Normalize(object vector)
{
return Get(vector, "normalized") ?? vector;
}
private static object CombineDirections(object forward, object right, float rightScale, object up, float upScale, float forwardScale = 1f)
{
MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
object obj = ((MethodBase)method).Invoke((object)null, new object[2]
{
((MethodBase)method2).Invoke((object)null, new object[2] { forward, forwardScale }),
((MethodBase)method2).Invoke((object)null, new object[2] { right, rightScale })
});
return Normalize(((MethodBase)method).Invoke((object)null, new object[2]
{
obj,
((MethodBase)method2).Invoke((object)null, new object[2] { up, upScale })
}));
}
private static object CombineDirections(object forward, object side, float sideScale)
{
MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
return Normalize(((MethodBase)method).Invoke((object)null, new object[2]
{
forward,
((MethodBase)method2).Invoke((object)null, new object[2] { side, sideScale })
}));
}
private static object OffsetVector(object origin, object axis, float distance)
{
MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
return ((MethodBase)method).Invoke((object)null, new object[2]
{
origin,
((MethodBase)method2).Invoke((object)null, new object[2] { axis, distance })
});
}
private static void SpawnGlow(object position, object direction, object right, object up)
{
MethodInfo method = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
MethodInfo method2 = vector3Type.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
object position2 = ((MethodBase)method).Invoke((object)null, new object[2]
{
position,
((MethodBase)method2).Invoke((object)null, new object[2] { direction, 0.035f })
});
SpawnFlashOrb(position2, direction, 0.105f, 0.105f, 0.12f, 1f, 0.88f, 0.58f, 6.5f, 0.065f);
object position3 = ((MethodBase)method).Invoke((object)null, new object[2]
{
position,
((MethodBase)method2).Invoke((object)null, new object[2] { direction, 0.11f })
});
SpawnFlashOrb(position3, direction, 0.075f, 0.075f, 0.28f, 1f, 0.48f, 0.16f, 4.8f, 0.06f);
float[] array = new float[3];
RuntimeHelpers.InitializeArray((System.Array)array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
float[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
object obj = ((i == 2) ? up : right);
object direction2 = Normalize(((MethodBase)method).Invoke((object)null, new object[2]
{
direction,
((MethodBase)method2).Invoke((object)null, new object[2]
{
obj,
array2[i]
})
}));
object position4 = ((MethodBase)method).Invoke((object)null, new object[2]
{
position,
((MethodBase)method2).Invoke((object)null, new object[2] { direction, 0.025f })
});
SpawnFlashOrb(position4, direction2, 0.032f, 0.032f, 0.12f + 0.025f * (float)i, 1f, 0.62f, 0.24f, 3.6f, 0.05f);
}
AddMuzzleLight(position);
}
private static void SpawnFlashOrb(object position, object direction, float sx, float sy, float sz, float r, float g, float b, float emission, float life)
{
System.Type type = FindType("UnityEngine.PrimitiveType");
object obj = System.Enum.Parse(type, "Sphere");
object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
try
{
object o = Get(obj2, "transform");
RemovePrimitiveCollider(obj2);
if (IsMobilePlatform() && muzzleFlashStyle != MuzzleFlashStyle.Standard)
{
DisableShadows(obj2);
}
Set(o, "position", position);
Set(o, "localScale", NewVector(sx, sy, sz));
System.Type type2 = FindType("UnityEngine.Quaternion");
MethodInfo method = type2.GetMethod("LookRotation", (BindingFlags)24, (Binder)null, new System.Type[1] { vector3Type }, (ParameterModifier[])null);
object obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[1] { direction }) : null);
if (obj3 != null)
{
Set(o, "rotation", obj3);
}
ApplyMaterial(obj2, r, g, b, 1f, emission, transparent: false);
}
finally
{
Destroy(obj2, life);
}
}
private static void SpawnFlashCylinder(object position, object direction, float diameter, float length, float r, float g, float b, float emission, float life)
{
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
System.Type type = FindType("UnityEngine.PrimitiveType");
object obj = System.Enum.Parse(type, "Cylinder");
object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
try
{
object o = Get(obj2, "transform");
RemovePrimitiveCollider(obj2);
if (IsMobilePlatform())
{
DisableShadows(obj2);
}
Set(o, "position", position);
Set(o, "localScale", NewVector(diameter, length * 0.5f, diameter));
System.Type type2 = FindType("UnityEngine.Quaternion");
MethodInfo method = type2.GetMethod("FromToRotation", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
object obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[2]
{
NewVector(0f, 1f, 0f),
direction
}) : null);
if (obj3 == null)
{
throw new MissingMethodException("Unity Quaternion.FromToRotation was unavailable.");
}
Set(o, "rotation", obj3);
ApplyMaterial(obj2, r, g, b, 1f, emission, transparent: false);
}
finally
{
Destroy(obj2, life);
}
}
private static void SpawnFlashCapsule(object position, object direction, float width, float length, float r, float g, float b, float emission, float life)
{
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
System.Type type = FindType("UnityEngine.PrimitiveType");
object obj = System.Enum.Parse(type, "Capsule");
object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
try
{
object o = Get(obj2, "transform");
RemovePrimitiveCollider(obj2);
if (IsMobilePlatform())
{
DisableShadows(obj2);
}
Set(o, "position", position);
Set(o, "localScale", NewVector(width, length * 0.5f, width));
System.Type type2 = FindType("UnityEngine.Quaternion");
MethodInfo method = type2.GetMethod("FromToRotation", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
object obj3 = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[2]
{
NewVector(0f, 1f, 0f),
direction
}) : null);
if (obj3 == null)
{
throw new MissingMethodException("Unity Quaternion.FromToRotation was unavailable.");
}
Set(o, "rotation", obj3);
ApplyMaterial(obj2, r, g, b, 1f, emission, transparent: false);
}
finally
{
Destroy(obj2, life);
}
}
private static void SpawnSmokeOnlyFlash(object position, object direction, object right, object up)
{
MethodInfo method = vector3Type.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
MethodInfo method2 = vector3Type.GetMethod("op_Addition", (BindingFlags)24);
bool flag = IsMobilePlatform();
int num = (flag ? 5 : 8);
for (int i = 0; i < num; i++)
{
float num2 = (float)(effectRandom.NextDouble() * 0.09 - 0.045);
object origin = OffsetVector(position, direction, 0.02f + 0.048f * (float)i);
origin = OffsetVector(origin, right, num2);
origin = OffsetVector(origin, up, (float)(effectRandom.NextDouble() * 0.035 - 0.0175));
object velocity = ((MethodBase)method2).Invoke((object)null, new object[2]
{
((MethodBase)method).Invoke((object)null, new object[2]
{
right,
num2 * 0.55f
}),
((MethodBase)method2).Invoke((object)null, new object[2]
{
((MethodBase)method).Invoke((object)null, new object[2]
{
up,
0.045f + 0.018f * (float)i
}),
((MethodBase)method).Invoke((object)null, new object[2]
{
direction,
0.035f + 0.012f * (float)i
})
})
});
float life = (flag ? (0.72f + 0.07f * (float)i) : (1.05f + 0.09f * (float)i));
float size = 0.095f + 0.014f * (float)i;
SpawnSmoke(origin, size, life, velocity, 0.29f);
}
}
private static void SpawnSmoke(object position, float size, float life, object velocity, float alpha = 0.22f)
{
int num = (IsMobilePlatform() ? 18 : 64);
while (smokePuffs.Count >= num)
{
SmokePuff smokePuff = smokePuffs[0];
Destroy(smokePuff.GameObject, 0f);
smokePuffs.RemoveAt(0);
}
System.Type type = FindType("UnityEngine.PrimitiveType");
object obj = System.Enum.Parse(type, "Sphere");
object obj2 = ((MethodBase)gameObjectType.GetMethod("CreatePrimitive", (BindingFlags)24)).Invoke((object)null, new object[1] { obj });
try
{
RemovePrimitiveCollider(obj2);
object obj3 = Get(obj2, "transform");
Set(obj3, "position", position);
Set(obj3, "localScale", NewVector(size, size, size));
ApplyMaterial(obj2, 0.4f, 0.4f, 0.4f, alpha, 0f, transparent: true);
object unityComponent = GetUnityComponent(obj2, FindType("UnityEngine.Renderer"));
Set(unityComponent, "shadowCastingMode", System.Enum.Parse(FindType("UnityEngine.Rendering.ShadowCastingMode"), "Off"));
Set(unityComponent, "receiveShadows", !IsMobilePlatform());
object material = Get(unityComponent, "material");
smokePuffs.Add(new SmokePuff
{
GameObject = obj2,
Transform = obj3,
Material = material,
Origin = position,
Velocity = velocity,
Started = System.DateTime.UtcNow,
Life = life,
Size = size,
Alpha = alpha
});
}
catch
{
Destroy(obj2, 0f);
throw;
}
}
private static void AddMuzzleLight(object position)
{
AddMuzzleLight(position, 1f, 0.66f, 0.32f, 3.1f, 2.6f, 0.065f);
}
private static void AddMuzzleLight(object position, float r, float g, float b, float intensity, float range, float life)
{
if (IsMobilePlatform() && muzzleFlashStyle != MuzzleFlashStyle.Standard)
{
return;
}
System.Type componentType = FindType("UnityEngine.Light");
object obj = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] muzzle flash light" });
try
{
object o = AddUnityComponent(obj, componentType);
Set(Get(obj, "transform"), "position", position);
Set(o, "intensity", intensity);
Set(o, "range", range);
Set(o, "shadows", System.Enum.Parse(FindType("UnityEngine.LightShadows"), "None"));
object value = Activator.CreateInstance(FindType("UnityEngine.Color"), new object[4] { r, g, b, 1f });
Set(o, "color", value);
}
finally
{
Destroy(obj, life);
}
}
private static object MakeMaterial(float r, float g, float b, float alpha, float emission, bool transparent)
{
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
string text = $"{r:R}|{g:R}|{b:R}|{alpha:R}|{emission:R}|{transparent}";
object result = default(object);
if (materialCache.TryGetValue(text, ref result))
{
return result;
}
System.Type type = FindType("UnityEngine.Shader");
MethodInfo method = type.GetMethod("Find", (BindingFlags)24);
string[] array = ((!transparent) ? new string[3] { "Standard", "Unlit/Color", "Sprites/Default" } : new string[6] { "Standard", "Legacy Shaders/Transparent/Diffuse", "Particles/Standard Unlit", "Legacy Shaders/Particles/Alpha Blended", "Unlit/Transparent", "Sprites/Default" });
object obj = null;
string[] array2 = array;
foreach (string text2 in array2)
{
obj = ((method != null) ? ((MethodBase)method).Invoke((object)null, new object[1] { text2 }) : null);
if (obj != null)
{
break;
}
}
if (obj == null)
{
throw new InvalidOperationException("Unity could not find a supported Realism effect shader.");
}
System.Type type2 = FindType("UnityEngine.Material");
object obj2 = Activator.CreateInstance(type2, new object[1] { obj });
System.Type type3 = FindType("UnityEngine.Color");
object value = Activator.CreateInstance(type3, new object[4] { r, g, b, alpha });
Set(obj2, "color", value);
if (emission > 0f)
{
Call(obj2, "EnableKeyword", "_EMISSION");
object obj3 = Activator.CreateInstance(type3, new object[4]
{
r * emission,
g * emission,
b * emission,
1f
});
Call(obj2, "SetColor", "_EmissionColor", obj3);
}
if (transparent)
{
Call(obj2, "SetFloat", "_Mode", 2f);
Call(obj2, "SetFloat", "_Metallic", 0f);
Call(obj2, "SetFloat", "_Glossiness", 0.05f);
Call(obj2, "SetInt", "_SrcBlend", 5);
Call(obj2, "SetInt", "_DstBlend", 10);
Call(obj2, "SetInt", "_ZWrite", 0);
Call(obj2, "EnableKeyword", "_ALPHABLEND_ON");
Set(obj2, "renderQueue", 3000);
}
materialCache[text] = obj2;
return obj2;
}
private static void ApplyMaterial(object obj, float r, float g, float b, float alpha, float emission, bool transparent)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
object unityComponent = GetUnityComponent(obj, FindType("UnityEngine.Renderer"));
if (unityComponent == null)
{
throw new InvalidOperationException("Realism effect primitive has no MeshRenderer.");
}
Set(unityComponent, "enabled", true);
Set(unityComponent, "material", MakeMaterial(r, g, b, alpha, emission, transparent));
}
private static void Set(object o, string name, object value)
{
if (o == null)
{
return;
}
PropertyInfo property = o.GetType().GetProperty(name, (BindingFlags)52);
if (property != (PropertyInfo)null && property.CanWrite)
{
property.SetValue(o, value);
return;
}
FieldInfo field = o.GetType().GetField(name, (BindingFlags)52);
if (field != null)
{
field.SetValue(o, value);
}
}
private static void Destroy(object obj, float delay)
{
if (obj == null || unityObject == (System.Type)null)
{
return;
}
try
{
MethodInfo method = unityObject.GetMethod("Destroy", new System.Type[2]
{
unityObject,
typeof(float)
});
if (method != (MethodInfo)null)
{
((MethodBase)method).Invoke((object)null, new object[2] { obj, delay });
return;
}
MethodInfo method2 = unityObject.GetMethod("Destroy", new System.Type[1] { unityObject });
if (method2 != null)
{
((MethodBase)method2).Invoke((object)null, new object[1] { obj });
}
}
catch
{
try
{
MethodInfo method3 = unityObject.GetMethod("Destroy", new System.Type[1] { unityObject });
if (method3 != null)
{
((MethodBase)method3).Invoke((object)null, new object[1] { obj });
}
}
catch
{
}
}
}
private static void RemovePrimitiveCollider(object obj)
{
object unityComponent = GetUnityComponent(obj, FindType("UnityEngine.Collider"));
if (unityComponent != null)
{
Set(unityComponent, "enabled", false);
Destroy(unityComponent, 0f);
}
}
private static void DisableShadows(object obj)
{
object unityComponent = GetUnityComponent(obj, FindType("UnityEngine.Renderer"));
System.Type type = FindType("UnityEngine.Rendering.ShadowCastingMode");
if (unityComponent != null && !(type == (System.Type)null))
{
Set(unityComponent, "shadowCastingMode", System.Enum.Parse(type, "Off"));
Set(unityComponent, "receiveShadows", false);
}
}
private static object FindMuzzleTransform(object root)
{
if (root == null)
{
return null;
}
int num = Convert.ToInt32(Get(root, "childCount") ?? ((object)0));
for (int i = 0; i < num; i++)
{
object obj = Call(root, "GetChild", i);
string text = Convert.ToString(Get(obj, "name")) ?? "";
if (text.IndexOf("muzzle", (StringComparison)5) >= 0 || text.IndexOf("barrel", (StringComparison)5) >= 0 || text.IndexOf("muzzlepoint", (StringComparison)5) >= 0)
{
return obj;
}
object obj2 = FindMuzzleTransform(obj);
if (obj2 != null)
{
return obj2;
}
}
return null;
}
private static void UpdateTracers()
{
//IL_00c9: 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_0314: Unknown result type (might be due to invalid IL or missing references)
//IL_0319: Unknown result type (might be due to invalid IL or missing references)
MethodInfo val = vector3Type?.GetMethod("op_Addition", (BindingFlags)24);
MethodInfo val2 = vector3Type?.GetMethod("op_Subtraction", (BindingFlags)24);
MethodInfo val3 = vector3Type?.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
MethodInfo val4 = vector3Type?.GetMethod("Distance", (BindingFlags)24, (Binder)null, new System.Type[2] { vector3Type, vector3Type }, (ParameterModifier[])null);
for (int num = tracers.Count - 1; num >= 0; num--)
{
TracerEffect tracerEffect = tracers[num];
try
{
System.DateTime utcNow = System.DateTime.UtcNow;
TimeSpan val5 = utcNow - tracerEffect.Started;
float num2 = (float)((TimeSpan)(ref val5)).TotalSeconds;
object obj;
float num3;
float num4;
if (tracerEffect.TrackingProjectile)
{
bool flag = IsUnityObjectAlive(tracerEffect.ProjectileTransform) && IsUnityObjectAlive(tracerEffect.ProjectileBody);
object o = Get(tracerEffect.ProjectileTransform, "gameObject");
if (flag && Convert.ToBoolean(Get(o, "activeInHierarchy") ?? ((object)true)))
{
obj = Get(tracerEffect.ProjectileTransform, "position") ?? tracerEffect.LastPosition;
object o2 = Get(tracerEffect.ProjectileBody, "velocity");
object obj2 = Get(o2, "normalized");
if (obj2 == null || Convert.ToSingle(Get(o2, "magnitude") ?? ((object)0f)) < 0.01f)
{
object o3 = ((MethodBase)val2).Invoke((object)null, new object[2] { obj, tracerEffect.LastPosition });
obj2 = Get(o3, "normalized") ?? tracerEffect.Direction;
}
tracerEffect.Direction = obj2;
tracerEffect.LastPosition = obj;
num3 = ((val4 == (MethodInfo)null) ? (tracerEffect.Speed * num2) : Convert.ToSingle(((MethodBase)val4).Invoke((object)null, new object[2] { tracerEffect.Origin, obj })));
if (Convert.ToBoolean(Get(tracerEffect.Projectile, "isFinished") ?? ((object)false)))
{
tracerEffect.TrackingProjectile = false;
tracerEffect.HasFinishedAt = true;
tracerEffect.FinishedAt = utcNow;
}
num4 = 0f;
}
else
{
tracerEffect.TrackingProjectile = false;
tracerEffect.HasFinishedAt = true;
tracerEffect.FinishedAt = utcNow;
obj = tracerEffect.LastPosition;
num3 = ((val4 == (MethodInfo)null) ? (tracerEffect.Speed * num2) : Convert.ToSingle(((MethodBase)val4).Invoke((object)null, new object[2] { tracerEffect.Origin, obj })));
num4 = 0f;
}
goto IL_048d;
}
if (tracerEffect.HasFinishedAt)
{
val5 = utcNow - tracerEffect.FinishedAt;
float num5 = (float)((TimeSpan)(ref val5)).TotalSeconds;
if (!(num5 >= 0.12f))
{
obj = tracerEffect.LastPosition;
num3 = ((val4 == (MethodInfo)null) ? (tracerEffect.Speed * num2) : Convert.ToSingle(((MethodBase)val4).Invoke((object)null, new object[2] { tracerEffect.Origin, obj })));
num4 = num5 / 0.12f;
goto IL_048d;
}
Destroy(tracerEffect.GameObject, 0f);
Destroy(tracerEffect.OuterLineGameObject, 0f);
Destroy(tracerEffect.CoreLineGameObject, 0f);
tracers.RemoveAt(num);
}
else
{
if (!(num2 >= tracerEffect.Life))
{
obj = ((MethodBase)val).Invoke((object)null, new object[2]
{
tracerEffect.Origin,
((MethodBase)val3).Invoke((object)null, new object[2]
{
tracerEffect.Direction,
tracerEffect.Speed * num2
})
});
num3 = tracerEffect.Speed * num2;
num4 = num2 / tracerEffect.Life;
goto IL_048d;
}
Destroy(tracerEffect.GameObject, 0f);
Destroy(tracerEffect.OuterLineGameObject, 0f);
Destroy(tracerEffect.CoreLineGameObject, 0f);
tracers.RemoveAt(num);
}
goto end_IL_00b8;
IL_048d:
float num6 = Math.Min(tracerEffect.Length, num3) * (1f - 0.2f * num4);
object tail = ((MethodBase)val).Invoke((object)null, new object[2]
{
obj,
((MethodBase)val3).Invoke((object)null, new object[2]
{
tracerEffect.Direction,
0f - num6
})
});
float num7 = 1f - 0.35f * num4;
Set(tracerEffect.Transform, "position", obj);
Set(tracerEffect.Transform, "localScale", NewVector(tracerEffect.HeadSize * num7, tracerEffect.HeadSize * num7, tracerEffect.HeadSize * num7));
SetTracerLinePoints(tracerEffect.OuterLine, tail, obj);
SetTracerLinePoints(tracerEffect.CoreLine, tail, obj);
Set(tracerEffect.OuterLine, "startWidth", tracerEffect.OuterStartWidth * num7);
Set(tracerEffect.OuterLine, "endWidth", tracerEffect.OuterEndWidth * num7);
Set(tracerEffect.CoreLine, "startWidth", tracerEffect.CoreStartWidth * num7);
Set(tracerEffect.CoreLine, "endWidth", tracerEffect.CoreEndWidth * num7);
if (!tracerUpdateLogged)
{
tracerUpdateLogged = true;
Mod mod = instance;
if (mod != null)
{
((MelonBase)mod).LoggerInstance.Msg("Updated the first tapered additive tracer streak in the scene.");
}
}
end_IL_00b8:;
}
catch (System.Exception error)
{
Destroy(tracerEffect.GameObject, 0f);
Destroy(tracerEffect.OuterLineGameObject, 0f);
Destroy(tracerEffect.CoreLineGameObject, 0f);
tracers.RemoveAt(num);
LogEffectError(ref visualErrorLogged, "tracer animation", error);
}
}
}
private static void UpdateSparks()
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
MethodInfo val = vector3Type?.GetMethod("op_Addition", (BindingFlags)24);
MethodInfo val2 = vector3Type?.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
for (int num = sparks.Count - 1; num >= 0; num--)
{
SparkEffect sparkEffect = sparks[num];
TimeSpan val3 = System.DateTime.UtcNow - sparkEffect.Started;
float num2 = (float)((TimeSpan)(ref val3)).TotalSeconds;
if (num2 >= sparkEffect.Life)
{
Destroy(sparkEffect.GameObject, 0f);
Destroy(sparkEffect.TailGameObject, 0f);
sparks.RemoveAt(num);
}
else
{
try
{
object obj = ((MethodBase)val2).Invoke((object)null, new object[2]
{
sparkEffect.Direction,
sparkEffect.Speed * num2
});
object obj2 = NewVector(0f, -4.9f * num2 * num2, 0f);
object obj3 = ((MethodBase)val).Invoke((object)null, new object[2]
{
sparkEffect.Origin,
((MethodBase)val).Invoke((object)null, new object[2] { obj, obj2 })
});
float num3 = num2 / sparkEffect.Life;
object value = ((MethodBase)val).Invoke((object)null, new object[2]
{
obj3,
((MethodBase)val2).Invoke((object)null, new object[2]
{
sparkEffect.Direction,
(0f - sparkEffect.Length) * 0.22f
})
});
Set(sparkEffect.Transform, "position", obj3);
Set(sparkEffect.TailTransform, "position", value);
float num4 = sparkEffect.HeadSize * (1f - 0.52f * num3);
float z = sparkEffect.Length * 0.66f * (1f - 0.4f * num3);
Set(sparkEffect.Transform, "localScale", NewVector(num4, num4, num4));
Set(sparkEffect.TailTransform, "localScale", NewVector(sparkEffect.TailWidth, sparkEffect.TailWidth, z));
}
catch (System.Exception error)
{
Destroy(sparkEffect.GameObject, 0f);
Destroy(sparkEffect.TailGameObject, 0f);
sparks.RemoveAt(num);
LogEffectError(ref visualErrorLogged, "spark animation", error);
}
}
}
}
private static void UpdateSmoke()
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
MethodInfo val = vector3Type?.GetMethod("op_Addition", (BindingFlags)24);
MethodInfo val2 = vector3Type?.GetMethod("op_Multiply", new System.Type[2]
{
vector3Type,
typeof(float)
});
for (int num = smokePuffs.Count - 1; num >= 0; num--)
{
SmokePuff smokePuff = smokePuffs[num];
TimeSpan val3 = System.DateTime.UtcNow - smokePuff.Started;
float num2 = (float)((TimeSpan)(ref val3)).TotalSeconds;
if (num2 >= smokePuff.Life)
{
Destroy(smokePuff.GameObject, 0f);
smokePuffs.RemoveAt(num);
}
else
{
try
{
float num3 = num2 / smokePuff.Life;
object value = ((MethodBase)val).Invoke((object)null, new object[2]
{
smokePuff.Origin,
((MethodBase)val2).Invoke((object)null, new object[2] { smokePuff.Velocity, num2 })
});
Set(smokePuff.Transform, "position", value);
float num4 = smokePuff.Size * (1f + 0.9f * num3);
Set(smokePuff.Transform, "localScale", NewVector(num4, num4, num4));
float alpha = smokePuff.Alpha * (float)Math.Pow((double)(1f - num3), 1.3);
SetMaterialColor(smokePuff.Material, 0.4f, 0.4f, 0.4f, alpha);
}
catch (System.Exception error)
{
Destroy(smokePuff.GameObject, 0f);
smokePuffs.RemoveAt(num);
LogEffectError(ref visualErrorLogged, "smoke animation", error);
}
}
}
}
private static void SetMaterialColor(object material, float r, float g, float b, float alpha)
{
if (material != null)
{
object value = Activator.CreateInstance(FindType("UnityEngine.Color"), new object[4] { r, g, b, alpha });
Set(material, "color", value);
}
}
private static void RaiseRinging()
{
EnsureRingingAudio();
ringingLevel = Math.Min(0.6f, ringingLevel + 0.1f);
if (ringingUpdated == System.DateTime.MinValue)
{
ringingUpdated = System.DateTime.UtcNow;
}
System.Type type = FindType("UnityEngine.AudioSource");
if (!Convert.ToBoolean(Get(ringingSource, "isPlaying") ?? ((object)false)))
{
Call(ringingSource, "Play");
}
}
private static void EnsureRingingAudio()
{
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_0240: Unknown result type (might be due to invalid IL or missing references)
if (!IsUnityObjectAlive(ringingSource) || !IsUnityObjectAlive(ringingClip))
{
ResetRingingAudio();
gameObjectType = FindType("UnityEngine.GameObject");
unityObject = FindType("UnityEngine.Object");
System.Type type = FindType("UnityEngine.AudioSource");
System.Type type2 = FindType("UnityEngine.AudioClip");
if (gameObjectType == (System.Type)null || type == (System.Type)null || type2 == (System.Type)null)
{
throw new InvalidOperationException("Unity audio types were unavailable.");
}
ringingGameObject = Activator.CreateInstance(gameObjectType, new object[1] { "[Realism] ear ring" });
MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)unityObject.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "DontDestroyOnLoad" && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType.IsInstanceOfType(ringingGameObject)));
if (val != null)
{
((MethodBase)val).Invoke((object)null, new object[1] { ringingGameObject });
}
ringingSource = AddUnityComponent(ringingGameObject, type);
if (ringingSource == null)
{
throw new InvalidOperationException("Unity could not create the tinnitus AudioSource.");
}
MethodInfo val2 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type2.GetMethods((BindingFlags)24), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "Create" && ((MethodBase)m).GetParameters().Length == 5));
ringingClip = ((val2 != null) ? ((MethodBase)val2).Invoke((object)null, new object[5] { "Realism continuous 900 Hz ring", 44100, 1, 88200, false }) : null);
if (ringingClip == null)
{
throw new InvalidOperationException("Unity did not create the 900 Hz audio clip.");
}
float[] array = new float[88200];
for (int num = 0; num < array.Length; num++)
{
array[num] = 0.46f * (float)Math.Sin(Math.PI * 1800.0 * (double)num / 44100.0);
}
MethodInfo val3 = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type2.GetMethods(), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "SetData" && ((MethodBase)m).GetParameters().Length == 2));
if (val3 == (MethodInfo)null)
{
throw new InvalidOperationException("Unity AudioClip.SetData was unavailable.");
}
((MethodBase)val3).Invoke(ringingClip, new object[2]
{
ConvertArrayForRuntime(((MethodBase)val3).GetParameters()[0].ParameterType, array),
0
});
PropertyInfo property = type.GetProperty("spatialBlend");
if (property != null)
{
property.SetValue(ringingSource, (object)0f);
}
PropertyInfo property2 = type.GetProperty("loop");
if (property2 != null)
{
property2.SetValue(ringingSource, (object)true);
}
PropertyInfo property3 = type.GetProperty("playOnAwake");
if (property3 != null)
{
property3.SetValue(ringingSource, (object)false);
}
PropertyInfo property4 = type.GetProperty("priority");
if (property4 != null)
{
property4.SetValue(ringingSource, (object)0);
}
PropertyInfo property5 = type.GetProperty("clip");
if (property5 != null)
{
property5.SetValue(ringingSource, ringingClip);
}
PropertyInfo property6 = type.GetProperty("volume");
if (property6 != null)
{
property6.SetValue(ringingSource, (object)0f);
}
}
}
private static void UpdateRinging()
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
if (ringingSource == null)
{
return;
}
if (!IsUnityObjectAlive(ringingSource) || !IsUnityObjectAlive(ringingClip))
{
ResetRingingAudio();
return;
}
System.DateTime utcNow = System.DateTime.UtcNow;
float num;
if (!(ringingUpdated == System.DateTime.MinValue))
{
TimeSpan val = utcNow - ringingUpdated;
num = Math.Max(0f, (float)((TimeSpan)(ref val)).TotalSeconds);
}
else
{
num = 0f;
}
float num2 = num;
if (ringingUpdated != System.DateTime.MinValue)
{
ringingLevel *= (float)Math.Exp((double)((0f - num2) / 8f));
}
ringingUpdated = utcNow;
if (!earRingingEnabled)
{
ringingLevel = 0f;
}
try
{
float num3 = ((ringingLevel > ringingVolume) ? 0.06f : 0.32f);
float num4 = ((num2 <= 0f) ? 0f : (1f - (float)Math.Exp((double)((0f - num2) / num3))));
ringingVolume += (ringingLevel - ringingVolume) * num4;
if (ringingLevel < 0.0005f && ringingVolume < 0.0005f)
{
ringingLevel = (ringingVolume = 0f);
}
System.Type type = FindType("UnityEngine.AudioSource");
if (type != null)
{
PropertyInfo property = type.GetProperty("volume");
if (property != null)
{
property.SetValue(ringingSource, (object)(ringingVolume * (ringingVolumeSetting / 100f)));
}
}
if (!Convert.ToBoolean(Get(ringingSource, "isPlaying") ?? ((object)false)) && (ringingLevel > 0.001f || ringingVolume > 0.001f))
{
Call(ringingSource, "Play");
}
}
catch (System.Exception error)
{
LogEffectError(ref audioErrorLogged, "ringing update", error);
}
}
private static object GetFiringHand(object gun)
{
object o = Get(gun, "triggerGrip");
return Call(o, "GetHand");
}
private static bool IsRemoteFiringHand(object hand)
{
if (hand == null)
{
return false;
}
object manager = Get(hand, "manager");
System.Type type = FindType("LabFusion.Entities.NetworkPlayerManager");
if (manager == null || type == (System.Type)null)
{
return false;
}
MethodInfo val = Enumerable.FirstOrDefault<MethodInfo>((System.Collections.Generic.IEnumerable<MethodInfo>)type.GetMethods((BindingFlags)56), (Func<MethodInfo, bool>)((MethodInfo m) => ((MemberInfo)m).Name == "HasExternalPlayer" && ((MethodBase)m).GetParameters().Length == 1 && ((MethodBase)m).GetParameters()[0].ParameterType.IsInstanceOfType(manager)));
if (val == (MethodInfo)null)
{
return false;
}
try
{
return Convert.ToBoolean(((MethodBase)val).Invoke((object)null, new object[1] { manager }));
}
catch
{
return false;
}
}
private static object ConvertArrayForRuntime(System.Type expectedType, float[] values)
{
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
if (expectedType.IsInstanceOfType((object)values))
{
return values;
}
if (expectedType.IsGenericType && expectedType.GetGenericArguments().Length == 1 && expectedType.GetGenericArguments()[0] == typeof(float))
{
ConstructorInfo constructor = expectedType.GetConstructor(new System.Type[1] { typeof(float[]) });
if (constructor != (ConstructorInfo)null)
{
return constructor.Invoke(new object[1] { values });
}
ConstructorInfo constructor2 = expectedType.GetConstructor(new System.Type[1] { typeof(int) });
if (constructor2 != (ConstructorInfo)null)
{
object obj = constructor2.Invoke(new object[1] { values.Length });
PropertyInfo property = expectedType.GetProperty("Item");
if (property != (PropertyInfo)null)
{
for (int i = 0; i < values.Length; i++)
{
property.SetValue(obj, (object)values[i], new object[1] { i });
}
}
return obj;
}
}
throw new InvalidOperationException("Can't pass audio samples to " + expectedType.FullName + ".");
}
}
}