Decompiled source of TracerFXX v1.3.0
Mods/TracerFX.dll
Decompiled 16 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BoneLib; using BoneLib.BoneMenu; using BoneLib.Notifications; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Data; using LabFusion.Entities; using LabFusion.Network; using LabFusion.Network.Serialization; using LabFusion.Player; using LabFusion.SDK.Modules; using LabFusion.Utilities; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using TracerFX; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(Core), "TracerFX", "1.3.0", "abbigail", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })] [assembly: MelonOptionalDependencies(new string[] { "LabFusion" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("TracerFX")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.0.0")] [assembly: AssemblyInformationalVersion("1.3.0")] [assembly: AssemblyProduct("TracerFX")] [assembly: AssemblyTitle("TracerFX")] [assembly: AssemblyVersion("1.3.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TracerFX { public class Core : MelonMod { public static Instance Log; private static int _shotCounter; public override void OnInitializeMelon() { Log = ((MelonBase)this).LoggerInstance; Settings.Init(); Menu.Build(); Hooking.OnLevelLoaded += delegate { Mats.EnsureBase(); OrangeTips.ScanScene(); }; Hooking.OnLevelUnloaded += delegate { TracerManager.ClearAll(); OrangeTips.OnLevelUnloaded(); }; Hooking.OnGripAttached += delegate(Grip grip, Hand _) { try { if ((Object)(object)grip != (Object)null) { OrangeTips.Register(((Component)grip).GetComponentInParent<Gun>()); } } catch { } }; Log.Msg($"TracerFX loaded - airsoft tracers ready. Performance profile: {Perf.Resolved}" + (Perf.IsStandaloneDevice ? " (standalone device detected)" : "")); } public override void OnLateInitializeMelon() { FusionCompat.Init(); } public override void OnUpdate() { try { TracerManager.Tick(); } catch (Exception ex) { Log.Error("Tick: " + ex); } try { OrangeTips.Tick(); } catch (Exception ex2) { Log.Error("OrangeTips: " + ex2); } FusionCompat.Tick(); } public static bool SafeRaycast(Vector3 from, Vector3 dir, float dist, Transform ignA, Transform ignB, out RaycastHit hit) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) int maxRayHops = Perf.MaxRayHops; for (int i = 0; i < maxRayHops; i++) { if (!Physics.Raycast(from, dir, ref hit, dist, -5, (QueryTriggerInteraction)1)) { return false; } Transform val = (((Object)(object)((RaycastHit)(ref hit)).collider != (Object)null) ? ((Component)((RaycastHit)(ref hit)).collider).transform : null); if (!((Object)(object)val != (Object)null) || ((!((Object)(object)ignA != (Object)null) || !val.IsChildOf(ignA)) && (!((Object)(object)ignB != (Object)null) || !val.IsChildOf(ignB)))) { return true; } float num = ((RaycastHit)(ref hit)).distance + 0.002f; from += dir * num; dist -= num; if (dist <= 0f) { break; } } hit = default(RaycastHit); return false; } private static RigManager Holder(Gun gun, out int hand) { hand = -1; try { Grip triggerGrip = gun.triggerGrip; if ((Object)(object)triggerGrip != (Object)null && triggerGrip.attachedHands != null && triggerGrip.attachedHands.Count > 0) { Hand val = triggerGrip.attachedHands[0]; if ((Object)(object)val != (Object)null && (Object)(object)val.manager != (Object)null) { PhysicsRig physicsRig = val.manager.physicsRig; if ((Object)(object)physicsRig != (Object)null && (Object)(object)physicsRig.leftHand != (Object)null && ((Il2CppObjectBase)physicsRig.leftHand).Pointer == ((Il2CppObjectBase)val).Pointer) { hand = 0; } else if ((Object)(object)physicsRig != (Object)null && (Object)(object)physicsRig.rightHand != (Object)null && ((Il2CppObjectBase)physicsRig.rightHand).Pointer == ((Il2CppObjectBase)val).Pointer) { hand = 1; } return val.manager; } } if (Player.HandsExist) { Gun componentInHand = Player.GetComponentInHand<Gun>(Player.LeftHand); if ((Object)(object)componentInHand != (Object)null && ((Il2CppObjectBase)componentInHand).Pointer == ((Il2CppObjectBase)gun).Pointer) { hand = 0; return Player.RigManager; } Gun componentInHand2 = Player.GetComponentInHand<Gun>(Player.RightHand); if ((Object)(object)componentInHand2 != (Object)null && ((Il2CppObjectBase)componentInHand2).Pointer == ((Il2CppObjectBase)gun).Pointer) { hand = 1; return Player.RigManager; } } } catch { } return null; } internal static Transform GunRoot(Gun gun) { if ((Object)(object)gun == (Object)null) { return null; } try { return ((Object)(object)gun.entity != (Object)null) ? ((Component)gun.entity).transform : ((Component)gun).transform.root; } catch { return ((Component)gun).transform.root; } } internal static void OnGunFired(Gun gun) { //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gun == (Object)null) { return; } OrangeTips.Register(gun); int hand; RigManager val = Holder(gun, out hand); RigManager rigManager = Player.RigManager; bool flag = (Object)(object)val != (Object)null && (Object)(object)rigManager != (Object)null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)rigManager).Pointer; if (((Object)(object)val != (Object)null && !flag && FusionCompat.IsRemotePlayerWithMod(val)) || !Settings.Enabled.Value || (Settings.PlayerGunsOnly.Value && !flag)) { return; } _shotCounter++; if (_shotCounter % Mathf.Max(1, Settings.EveryNthShot.Value) != 0) { return; } Transform val2 = (((Object)(object)gun.firePointTransform != (Object)null) ? gun.firePointTransform : ((Component)gun).transform); int num = 1; float num2 = 0f; try { ProjectileData val3 = (((Object)(object)gun.chamberedCartridge != (Object)null) ? gun.chamberedCartridge.projectile : null); if ((Object)(object)val3 == (Object)null && (Object)(object)gun.defaultCartridge != (Object)null) { val3 = gun.defaultCartridge.projectile; } if ((Object)(object)val3 != (Object)null && Settings.Pellets.Value) { num = Mathf.Clamp(val3.count, 1, 12); num2 = ((num > 1) ? Mathf.Clamp(val3.angle, 1f, 20f) : 0f); } } catch { } TracerStyle style = TracerStyle.FromSettings(); Color color = Settings.PickColor(flag ? hand : (-1)); Vector3 origin = val2.position + val2.forward * 0.02f; FireShots(origin, val2.forward, val2.up, color, num, num2, style, GunRoot(gun), ((Object)(object)val != (Object)null) ? ((Component)val).transform : null); if (flag) { FusionCompat.SendShot(origin, val2.forward, val2.up, color, hand, num, num2, style); } } internal static void FireShots(Vector3 origin, Vector3 fwd, Vector3 up, Color color, int pellets, float coneDeg, TracerStyle style, Transform ignA, Transform ignB) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) fwd = ((Vector3)(ref fwd)).normalized; Vector3 val = Vector3.Cross(up, fwd); Vector3 normalized = ((Vector3)(ref val)).normalized; if (((Vector3)(ref normalized)).sqrMagnitude < 0.01f) { val = Vector3.Cross(Vector3.up, fwd); normalized = ((Vector3)(ref val)).normalized; } Vector3 up2 = Vector3.Cross(fwd, normalized); pellets = Mathf.Clamp(pellets, 1, Perf.PelletCap); float deg = style.Spread + coneDeg * 0.5f; for (int i = 0; i < pellets; i++) { TracerManager.Fire(new ShotInfo { Origin = origin, Direction = Jitter(fwd, up2, normalized, deg), GunUp = up, Color = color, IgnoreA = ignA, IgnoreB = ignB, Style = style }); } } private static Vector3 Jitter(Vector3 fwd, Vector3 up, Vector3 right, float deg) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (deg <= 0f) { return fwd; } Vector2 val = Random.insideUnitCircle * Mathf.Tan(deg * ((float)Math.PI / 180f)); Vector3 val2 = fwd + up * val.y + right * val.x; return ((Vector3)(ref val2)).normalized; } public static void TestShot() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) Transform head = Player.Head; if (!((Object)(object)head == (Object)null)) { TracerStyle style = TracerStyle.FromSettings(); Color color = Settings.PickColor(1); Vector3 origin = head.position + head.forward * 0.4f - head.up * 0.1f; FireShots(ignB: ((Object)(object)Player.RigManager != (Object)null) ? ((Component)Player.RigManager).transform : null, origin: origin, fwd: head.forward, up: head.up, color: color, pellets: 1, coneDeg: 0f, style: style, ignA: null); FusionCompat.SendShot(origin, head.forward, head.up, color, -1, 1, 0f, style); } } } [HarmonyPatch(typeof(Gun), "Awake")] internal static class GunAwakePatch { private static void Postfix(Gun __instance) { try { OrangeTips.Register(__instance); } catch { } } } [HarmonyPatch(typeof(Gun), "OnFire")] internal static class GunOnFirePatch { private static void Prefix(Gun __instance) { try { Core.OnGunFired(__instance); } catch (Exception ex) { Core.Log.Error("OnFire: " + ex); } } } internal static class FusionBridge { private class PeerState { public bool TracersOn; public bool TipOn; public Color TipColor; public float LastSeen; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ServerEvent <>9__6_0; public static ServerEvent <>9__6_1; public static PlayerUpdate <>9__6_2; internal void <Init>b__6_0() { _peers.Clear(); _nextPresence = 0f; } internal void <Init>b__6_1() { _peers.Clear(); } internal void <Init>b__6_2(PlayerID _) { _nextPresence = 0f; } } private static readonly Dictionary<byte, PeerState> _peers = new Dictionary<byte, PeerState>(); private static readonly List<RemoteTipHolder> _tipHolders = new List<RemoteTipHolder>(); private static float _nextPresence; private const float PresenceInterval = 4f; private const float PeerTimeout = 15f; public static void Init() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown ModuleManager.RegisterModule<TracerFXModule>(); object obj = <>c.<>9__6_0; if (obj == null) { ServerEvent val = delegate { _peers.Clear(); _nextPresence = 0f; }; <>c.<>9__6_0 = val; obj = (object)val; } MultiplayerHooking.OnJoinedServer += (ServerEvent)obj; object obj2 = <>c.<>9__6_1; if (obj2 == null) { ServerEvent val2 = delegate { _peers.Clear(); }; <>c.<>9__6_1 = val2; obj2 = (object)val2; } MultiplayerHooking.OnDisconnected += (ServerEvent)obj2; object obj3 = <>c.<>9__6_2; if (obj3 == null) { PlayerUpdate val3 = delegate { _nextPresence = 0f; }; <>c.<>9__6_2 = val3; obj3 = (object)val3; } MultiplayerHooking.OnPlayerJoined += (PlayerUpdate)obj3; } public static bool InServer() { return NetworkInfo.HasServer; } public static int ModdedPlayerCount() { Prune(); return _peers.Count; } public static bool IsRemotePlayerWithMod(RigManager rig) { if (!NetworkInfo.HasServer) { return false; } NetworkPlayer val = default(NetworkPlayer); if (!NetworkPlayerManager.TryGetPlayer(rig, ref val) || val == null || val.PlayerID == null) { return false; } if (val.PlayerID.IsMe) { return false; } if (_peers.TryGetValue(val.PlayerID.SmallID, out var value)) { return Time.unscaledTime - value.LastSeen < 15f; } return false; } public static void SendShot(Vector3 o, Vector3 d, Vector3 u, Color c, int hand, int pellets, float cone, TracerStyle s) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (NetworkInfo.HasServer) { MessageRelay.RelayModule<TracerShotMessage, TracerShotData>(new TracerShotData { Origin = o, Direction = d, Up = u, Color = c, Hand = (byte)((hand < 0) ? 255u : ((uint)hand)), Pellets = (byte)Mathf.Clamp(pellets, 1, 12), Cone = cone, Style = s }, CommonMessageRoutes.UnreliableToOtherClients); } } public static void AnnounceNow() { _nextPresence = 0f; } public static void Tick() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) if (NetworkInfo.HasServer && !(Time.unscaledTime < _nextPresence)) { _nextPresence = Time.unscaledTime + 4f; MessageRelay.RelayModule<TracerPresenceMessage, TracerPresenceData>(new TracerPresenceData { TracersOn = (Settings.Enabled.Value && Settings.FusionSync.Value), TipOn = (Settings.OrangeTip.Value && Settings.FusionSync.Value), TipColor = OrangeTips.LocalTipColor }, CommonMessageRoutes.ReliableToOtherClients); Prune(); } } private static void Prune() { List<byte> list = null; foreach (KeyValuePair<byte, PeerState> peer in _peers) { if (Time.unscaledTime - peer.Value.LastSeen > 15f) { (list ?? (list = new List<byte>())).Add(peer.Key); } } if (list == null) { return; } foreach (byte item in list) { _peers.Remove(item); } } private static PeerState Peer(byte id) { if (!_peers.TryGetValue(id, out var value)) { value = new PeerState(); _peers[id] = value; } value.LastSeen = Time.unscaledTime; return value; } internal static void OnPresence(byte sender, TracerPresenceData d) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) PeerState peerState = Peer(sender); peerState.TracersOn = d.TracersOn; peerState.TipOn = d.TipOn; peerState.TipColor = d.TipColor; } internal static void OnShot(byte sender, TracerShotData d) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Peer(sender).TracersOn = true; if (!Settings.Enabled.Value || !Settings.FusionShowOthers.Value) { return; } Transform ignA = null; Transform ignB = null; NetworkPlayer val = default(NetworkPlayer); if (NetworkPlayerManager.TryGetPlayer(sender, ref val) && val != null && val.HasRig && val.RigRefs != null) { RigManager rigManager = val.RigRefs.RigManager; if ((Object)(object)rigManager != (Object)null) { ignB = ((Component)rigManager).transform; } Hand val2 = ((d.Hand == 0) ? val.RigRefs.LeftHand : ((d.Hand == 1) ? val.RigRefs.RightHand : null)); if ((Object)(object)val2 != (Object)null) { try { ignA = Core.GunRoot(Player.GetComponentInHand<Gun>(val2)); } catch { } } } TracerStyle style = d.Style; style.Clamp(); Core.FireShots(d.Origin, d.Direction, d.Up, d.Color, d.Pellets, Mathf.Clamp(d.Cone, 0f, 20f), style, ignA, ignB); } public static List<RemoteTipHolder> RemoteTipHolders() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) _tipHolders.Clear(); if (!NetworkInfo.HasServer || !Settings.FusionShowOthersTips.Value) { return _tipHolders; } Prune(); NetworkPlayer val = default(NetworkPlayer); foreach (KeyValuePair<byte, PeerState> peer in _peers) { if (peer.Value.TipOn && NetworkPlayerManager.TryGetPlayer(peer.Key, ref val) && val != null && val.HasRig && val.RigRefs != null) { _tipHolders.Add(new RemoteTipHolder { Left = val.RigRefs.LeftHand, Right = val.RigRefs.RightHand, Color = peer.Value.TipColor }); } } return _tipHolders; } } public class TracerFXModule : Module { public override string Name => "TracerFX"; public override string Author => "abbigail"; public override Version Version => new Version(1, 3, 0); public override ConsoleColor Color => ConsoleColor.Green; protected override void OnModuleRegistered() { ModuleMessageManager.RegisterHandler<TracerShotMessage>(); ModuleMessageManager.RegisterHandler<TracerPresenceMessage>(); } } public class TracerShotData : INetSerializable { public Vector3 Origin; public Vector3 Direction; public Vector3 Up; public Color Color; public byte Hand; public byte Pellets; public float Cone; public TracerStyle Style; public int? GetSize() { return null; } public void Serialize(INetSerializer s) { NetSerializerUnityExtensions.SerializeValue(s, ref Origin); NetSerializerUnityExtensions.SerializeValue(s, ref Direction); NetSerializerUnityExtensions.SerializeValue(s, ref Up); NetSerializerUnityExtensions.SerializeValue(s, ref Color); s.SerializeValue(ref Hand); s.SerializeValue(ref Pellets); s.SerializeValue(ref Cone); s.SerializeValue(ref Style.Mode); s.SerializeValue(ref Style.SpeedMs); s.SerializeValue(ref Style.Gravity); s.SerializeValue(ref Style.HopUp); s.SerializeValue(ref Style.Drag); s.SerializeValue(ref Style.Spread); s.SerializeValue(ref Style.Bounces); s.SerializeValue(ref Style.Restitution); s.SerializeValue(ref Style.BBSize); s.SerializeValue(ref Style.TrailTime); s.SerializeValue(ref Style.TrailWidth); s.SerializeValue(ref Style.Intensity); s.SerializeValue(ref Style.LightRange); s.SerializeValue(ref Style.ImpactSize); s.SerializeValue(ref Style.GlowFade); s.SerializeValue(ref Style.Light); s.SerializeValue(ref Style.ImpactFlash); s.SerializeValue(ref Style.MuzzleFlash); } } public class TracerShotMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { byte? sender = ((ReceivedMessage)(ref received)).Sender; if (sender.HasValue) { TracerShotData d = ((ReceivedMessage)(ref received)).ReadData<TracerShotData>(); FusionBridge.OnShot(sender.Value, d); } } } public class TracerPresenceData : INetSerializable { public bool TracersOn; public bool TipOn; public Color TipColor; public int? GetSize() { return null; } public void Serialize(INetSerializer s) { s.SerializeValue(ref TracersOn); s.SerializeValue(ref TipOn); NetSerializerUnityExtensions.SerializeValue(s, ref TipColor); } } public class TracerPresenceMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { byte? sender = ((ReceivedMessage)(ref received)).Sender; if (sender.HasValue) { TracerPresenceData d = ((ReceivedMessage)(ref received)).ReadData<TracerPresenceData>(); FusionBridge.OnPresence(sender.Value, d); } } } public struct RemoteTipHolder { public Hand Left; public Hand Right; public Color Color; } public static class FusionCompat { private static bool _warnedSend; private static readonly List<RemoteTipHolder> _empty = new List<RemoteTipHolder>(); public static bool Present { get; private set; } public static bool InServer { get { if (!Present) { return false; } try { return BridgeInServer(); } catch { return false; } } } public static int ModdedPlayerCount { get { if (!Present) { return 0; } try { return BridgeCount(); } catch { return 0; } } } public static void Init() { Present = MelonBase.RegisteredMelons.Any((MelonBase m) => m.Info != null && m.Info.Name == "LabFusion"); if (!Present) { Core.Log.Msg("LabFusion not found - running in singleplayer mode."); return; } try { InitBridge(); Core.Log.Msg("LabFusion detected - tracers and orange tips will sync to other TracerFX players."); } catch (Exception ex) { Present = false; Core.Log.Warning("LabFusion found but its API didn't match; Fusion sync is off. " + ex.Message); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void InitBridge() { FusionBridge.Init(); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool BridgeInServer() { return FusionBridge.InServer(); } [MethodImpl(MethodImplOptions.NoInlining)] private static int BridgeCount() { return FusionBridge.ModdedPlayerCount(); } public static bool IsRemotePlayerWithMod(RigManager rig) { if (!Present || (Object)(object)rig == (Object)null) { return false; } try { return BridgeIsRemote(rig); } catch { return false; } } [MethodImpl(MethodImplOptions.NoInlining)] private static bool BridgeIsRemote(RigManager rig) { return FusionBridge.IsRemotePlayerWithMod(rig); } public static void SendShot(Vector3 origin, Vector3 dir, Vector3 up, Color color, int hand, int pellets, float cone, TracerStyle style) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!Present || !Settings.FusionSync.Value) { return; } try { BridgeSend(origin, dir, up, color, hand, pellets, cone, style); } catch (Exception ex) { if (!_warnedSend) { Core.Log.Warning("Fusion shot sync failed: " + ex.Message); _warnedSend = true; } } } [MethodImpl(MethodImplOptions.NoInlining)] private static void BridgeSend(Vector3 o, Vector3 d, Vector3 u, Color c, int h, int p, float cone, TracerStyle s) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) FusionBridge.SendShot(o, d, u, c, h, p, cone, s); } public static void AnnounceNow() { if (!Present) { return; } try { BridgeAnnounce(); } catch { } } [MethodImpl(MethodImplOptions.NoInlining)] private static void BridgeAnnounce() { FusionBridge.AnnounceNow(); } public static List<RemoteTipHolder> RemoteTipHolders() { if (!Present) { return _empty; } try { return BridgeTips(); } catch { return _empty; } } [MethodImpl(MethodImplOptions.NoInlining)] private static List<RemoteTipHolder> BridgeTips() { return FusionBridge.RemoteTipHolders(); } public static void Tick() { if (!Present) { return; } try { BridgeTick(); } catch { } } [MethodImpl(MethodImplOptions.NoInlining)] private static void BridgeTick() { FusionBridge.Tick(); } } public static class Menu { private static Page _root; private static readonly Color Accent = new Color(0.2f, 1f, 0.35f); private static readonly Color Sub = new Color(0.75f, 0.95f, 1f); private static readonly Color Warn = new Color(1f, 0.45f, 0.35f); public static void Build() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) _root = Page.Root.CreatePage("TracerFX", Accent, 0, true); Populate(); } private static void Rebuild() { _root.RemoveAll(); Populate(); } private static void Populate() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_049d: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Unknown result type (might be due to invalid IL or missing references) //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_05c8: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) //IL_06a3: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_0729: Unknown result type (might be due to invalid IL or missing references) //IL_0772: Unknown result type (might be due to invalid IL or missing references) //IL_07bb: Unknown result type (might be due to invalid IL or missing references) //IL_0804: Unknown result type (might be due to invalid IL or missing references) //IL_0834: Unknown result type (might be due to invalid IL or missing references) //IL_0864: Unknown result type (might be due to invalid IL or missing references) //IL_0893: Unknown result type (might be due to invalid IL or missing references) //IL_08d6: Unknown result type (might be due to invalid IL or missing references) //IL_08e8: Unknown result type (might be due to invalid IL or missing references) //IL_0931: Unknown result type (might be due to invalid IL or missing references) //IL_097a: Unknown result type (might be due to invalid IL or missing references) //IL_09c3: Unknown result type (might be due to invalid IL or missing references) //IL_09fd: Unknown result type (might be due to invalid IL or missing references) //IL_0a37: Unknown result type (might be due to invalid IL or missing references) //IL_0a70: Unknown result type (might be due to invalid IL or missing references) //IL_0acc: Unknown result type (might be due to invalid IL or missing references) //IL_0ade: Unknown result type (might be due to invalid IL or missing references) //IL_0b18: Unknown result type (might be due to invalid IL or missing references) //IL_0b60: Unknown result type (might be due to invalid IL or missing references) //IL_0bad: Unknown result type (might be due to invalid IL or missing references) //IL_0bbf: Unknown result type (might be due to invalid IL or missing references) //IL_0bf9: Unknown result type (might be due to invalid IL or missing references) //IL_0c33: Unknown result type (might be due to invalid IL or missing references) //IL_0c6c: Unknown result type (might be due to invalid IL or missing references) //IL_0caf: Unknown result type (might be due to invalid IL or missing references) //IL_0cc1: Unknown result type (might be due to invalid IL or missing references) //IL_0d00: Unknown result type (might be due to invalid IL or missing references) //IL_0d30: Unknown result type (might be due to invalid IL or missing references) //IL_0d6a: Unknown result type (might be due to invalid IL or missing references) //IL_0da8: Unknown result type (might be due to invalid IL or missing references) //IL_0de2: Unknown result type (might be due to invalid IL or missing references) //IL_0e25: Unknown result type (might be due to invalid IL or missing references) //IL_0e6e: Unknown result type (might be due to invalid IL or missing references) //IL_0ea7: Unknown result type (might be due to invalid IL or missing references) //IL_0edb: Unknown result type (might be due to invalid IL or missing references) //IL_0f0f: Unknown result type (might be due to invalid IL or missing references) _root.CreateBool("Tracers Enabled", Accent, Settings.Enabled.Value, (Action<bool>)delegate(bool v) { Set(Settings.Enabled, v); if (!v) { TracerManager.ClearAll(); } FusionCompat.AnnounceNow(); Notify(v ? "Tracers ON" : "Tracers OFF", (NotificationType)((!v) ? 1 : 3)); }); _root.CreateEnum("Mode", Sub, (Enum)Settings.CurrentMode, (Action<Enum>)delegate(Enum v) { Set(Settings.Mode, (int)(TracerMode)(object)v); }); _root.CreateEnum("Color", Sub, (Enum)(TracerColor)Settings.Preset.Value, (Action<Enum>)delegate(Enum v) { Set(Settings.Preset, (int)(TracerColor)(object)v); OrangeTips.ApplyColor(); if (Settings.CurrentColorMode != ColorMode.Preset && Settings.CurrentColorMode != ColorMode.PerHand) { Set(Settings.ColorModeE, 0); } }); _root.CreateFunction("Test Shot", Color.white, (Action)Core.TestShot); _root.CreateBool("Orange Tip", OrangeTips.BlazeOrange, Settings.OrangeTip.Value, (Action<bool>)delegate(bool v) { Set(Settings.OrangeTip, v); OrangeTips.Refresh(); Notify(v ? "Orange tips ON" : "Orange tips OFF", (NotificationType)((!v) ? 1 : 3)); }); Page obj = _root.CreatePage("Orange Tip", OrangeTips.BlazeOrange, 0, true); obj.CreateBool("Orange Tip", OrangeTips.BlazeOrange, Settings.OrangeTip.Value, (Action<bool>)delegate(bool v) { Set(Settings.OrangeTip, v); OrangeTips.Refresh(); }); obj.CreateFloat("Tip Diameter (cm)", Sub, Settings.TipDiameterCm.Value, 0.25f, 0.5f, 10f, (Action<float>)delegate(float v) { Set(Settings.TipDiameterCm, v); OrangeTips.Refresh(); }); obj.CreateFloat("Tip Length (cm)", Sub, Settings.TipLengthCm.Value, 0.25f, 0.25f, 10f, (Action<float>)delegate(float v) { Set(Settings.TipLengthCm, v); OrangeTips.Refresh(); }); obj.CreateFloat("Tip Offset (cm)", Sub, Settings.TipOffsetCm.Value, 0.25f, -10f, 10f, (Action<float>)delegate(float v) { Set(Settings.TipOffsetCm, v); OrangeTips.Refresh(); }); obj.CreateBool("Match Tracer Color", Sub, Settings.TipMatchTracer.Value, (Action<bool>)delegate(bool v) { Set(Settings.TipMatchTracer, v); OrangeTips.Refresh(); }); Page obj2 = _root.CreatePage("Color", new Color(1f, 0.8f, 0.2f), 0, true); obj2.CreateEnum("Color Mode", Sub, (Enum)Settings.CurrentColorMode, (Action<Enum>)delegate(Enum v) { Set(Settings.ColorModeE, (int)(ColorMode)(object)v); }); obj2.CreateEnum("Preset", Sub, (Enum)(TracerColor)Settings.Preset.Value, (Action<Enum>)delegate(Enum v) { Set(Settings.Preset, (int)(TracerColor)(object)v); OrangeTips.ApplyColor(); }); obj2.CreateFloat("Custom Red", Color.red, Settings.CustomR.Value, 0.05f, 0f, 1f, (Action<float>)delegate(float v) { Set(Settings.CustomR, v); }); obj2.CreateFloat("Custom Green", Color.green, Settings.CustomG.Value, 0.05f, 0f, 1f, (Action<float>)delegate(float v) { Set(Settings.CustomG, v); }); obj2.CreateFloat("Custom Blue", new Color(0.3f, 0.5f, 1f), Settings.CustomB.Value, 0.05f, 0f, 1f, (Action<float>)delegate(float v) { Set(Settings.CustomB, v); }); obj2.CreateEnum("Left Hand Color", Sub, (Enum)(TracerColor)Settings.LeftPreset.Value, (Action<Enum>)delegate(Enum v) { Set(Settings.LeftPreset, (int)(TracerColor)(object)v); }); obj2.CreateEnum("Right Hand Color", Sub, (Enum)(TracerColor)Settings.RightPreset.Value, (Action<Enum>)delegate(Enum v) { Set(Settings.RightPreset, (int)(TracerColor)(object)v); }); obj2.CreateFloat("Rainbow Speed", Sub, Settings.RainbowSpeed.Value, 0.1f, 0.1f, 5f, (Action<float>)delegate(float v) { Set(Settings.RainbowSpeed, v); }); obj2.CreateFloat("Glow Intensity", Sub, Settings.Intensity.Value, 0.25f, 0.25f, 10f, (Action<float>)delegate(float v) { Set(Settings.Intensity, v); }); obj2.CreateFunction("Test Shot", Color.white, (Action)Core.TestShot); Page obj3 = _root.CreatePage("Ballistics", new Color(0.4f, 0.8f, 1f), 0, true); obj3.CreateFloat("BB Speed (FPS)", Sub, Settings.SpeedFps.Value, 25f, 100f, 700f, (Action<float>)delegate(float v) { Set(Settings.SpeedFps, v); }); obj3.CreateFloat("Gravity", Sub, Settings.GravityScale.Value, 0.1f, 0f, 3f, (Action<float>)delegate(float v) { Set(Settings.GravityScale, v); }); obj3.CreateFloat("Hop-Up", Sub, Settings.HopUp.Value, 0.1f, 0f, 2f, (Action<float>)delegate(float v) { Set(Settings.HopUp, v); }); obj3.CreateFloat("Air Drag", Sub, Settings.Drag.Value, 0.1f, 0f, 3f, (Action<float>)delegate(float v) { Set(Settings.Drag, v); }); obj3.CreateFloat("Spread (deg)", Sub, Settings.SpreadDeg.Value, 0.1f, 0f, 5f, (Action<float>)delegate(float v) { Set(Settings.SpreadDeg, v); }); obj3.CreateInt("Ricochets", Sub, Settings.Bounces.Value, 1, 0, 5, (Action<int>)delegate(int v) { Set(Settings.Bounces, v); }); obj3.CreateFloat("Bounciness", Sub, Settings.Restitution.Value, 0.05f, 0.05f, 0.9f, (Action<float>)delegate(float v) { Set(Settings.Restitution, v); }); obj3.CreateFloat("Tracer Time Scale", Sub, Settings.TracerTimeScale.Value, 0.05f, 0.05f, 1f, (Action<float>)delegate(float v) { Set(Settings.TracerTimeScale, v); }); obj3.CreateFloat("Bullet Mode Speed", Sub, Settings.BulletSpeed.Value, 25f, 50f, 1000f, (Action<float>)delegate(float v) { Set(Settings.BulletSpeed, v); }); obj3.CreateFunction("Preset: Stock AEG", Color.white, (Action)delegate { ApplyBallistics(330f, 1f, 1f, 1f, 0.6f, "Stock AEG"); }); obj3.CreateFunction("Preset: Sniper", Color.white, (Action)delegate { ApplyBallistics(500f, 1f, 1.1f, 0.7f, 0.1f, "Sniper"); }); obj3.CreateFunction("Preset: Pistol", Color.white, (Action)delegate { ApplyBallistics(280f, 1f, 0.8f, 1.2f, 1f, "Pistol"); }); obj3.CreateFunction("Preset: Moon Gravity", Color.white, (Action)delegate { ApplyBallistics(350f, 0.17f, 0.15f, 0.3f, 0.6f, "Moon Gravity"); }); Page obj4 = _root.CreatePage("Visuals", new Color(0.9f, 0.5f, 1f), 0, true); obj4.CreateFloat("BB Size", Sub, Settings.BBSize.Value, 0.25f, 0.5f, 10f, (Action<float>)delegate(float v) { Set(Settings.BBSize, v); }); obj4.CreateFloat("Trail Length (s)", Sub, Settings.TrailTime.Value, 0.05f, 0.02f, 2f, (Action<float>)delegate(float v) { Set(Settings.TrailTime, v); }); obj4.CreateFloat("Trail Width", Sub, Settings.TrailWidth.Value, 0.1f, 0.1f, 5f, (Action<float>)delegate(float v) { Set(Settings.TrailWidth, v); }); obj4.CreateBool("Glow-in-the-Dark Fade", Sub, Settings.GlowFade.Value, (Action<bool>)delegate(bool v) { Set(Settings.GlowFade, v); }); obj4.CreateBool("Tracer Unit Flash", Sub, Settings.MuzzleFlash.Value, (Action<bool>)delegate(bool v) { Set(Settings.MuzzleFlash, v); }); obj4.CreateBool("BB Casts Light", Sub, Settings.GlowLight.Value, (Action<bool>)delegate(bool v) { Set(Settings.GlowLight, v); }); obj4.CreateFloat("BB Light Range", Sub, Settings.LightRange.Value, 0.25f, 0.25f, 6f, (Action<float>)delegate(float v) { Set(Settings.LightRange, v); }); Page obj5 = _root.CreatePage("Impacts", new Color(1f, 0.6f, 0.3f), 0, true); obj5.CreateBool("Impact Flash", Sub, Settings.ImpactFlash.Value, (Action<bool>)delegate(bool v) { Set(Settings.ImpactFlash, v); }); obj5.CreateFloat("Impact Size", Sub, Settings.ImpactSize.Value, 0.1f, 0.1f, 5f, (Action<float>)delegate(float v) { Set(Settings.ImpactSize, v); }); obj5.CreateBool("Impact Light", Sub, Settings.ImpactLight.Value, (Action<bool>)delegate(bool v) { Set(Settings.ImpactLight, v); }); Page obj6 = _root.CreatePage("Fusion", new Color(0.55f, 0.6f, 1f), 0, true); obj6.CreateBool("Share My Tracers & Tip", Sub, Settings.FusionSync.Value, (Action<bool>)delegate(bool v) { Set(Settings.FusionSync, v); FusionCompat.AnnounceNow(); }); obj6.CreateBool("Show Others' Tracers", Sub, Settings.FusionShowOthers.Value, (Action<bool>)delegate(bool v) { Set(Settings.FusionShowOthers, v); }); obj6.CreateBool("Show Others' Orange Tips", Sub, Settings.FusionShowOthersTips.Value, (Action<bool>)delegate(bool v) { Set(Settings.FusionShowOthersTips, v); OrangeTips.Refresh(); }); obj6.CreateFunction("Fusion Status", Color.white, (Action)delegate { Notify((!FusionCompat.Present) ? "LabFusion is not installed" : ((!FusionCompat.InServer) ? "Not in a Fusion lobby" : $"{FusionCompat.ModdedPlayerCount} other player(s) running TracerFX"), (NotificationType)0, force: true); }); Page obj7 = _root.CreatePage("Filters & Performance", new Color(0.7f, 0.7f, 0.7f), 0, true); obj7.CreateEnum("Performance Profile", Accent, (Enum)(PerfProfile)Settings.Profile.Value, (Action<Enum>)delegate(Enum v) { Set(Settings.Profile, (int)(PerfProfile)(object)v); TracerManager.ClearAll(); Notify($"Profile: {Perf.Resolved}", (NotificationType)0); }); obj7.CreateFunction("Show Active Profile", Color.white, (Action)delegate { Notify($"{Perf.Resolved}{(Perf.IsStandaloneDevice ? " (standalone)" : " (PC)")} - max {Perf.MaxTracers} tracers, lights {(Perf.AllowLights ? "on" : "off")}", (NotificationType)0, force: true); }); obj7.CreateBool("Player Guns Only", Sub, Settings.PlayerGunsOnly.Value, (Action<bool>)delegate(bool v) { Set(Settings.PlayerGunsOnly, v); }); obj7.CreateInt("Tracer Every Nth Shot", Sub, Settings.EveryNthShot.Value, 1, 1, 10, (Action<int>)delegate(int v) { Set(Settings.EveryNthShot, v); }); obj7.CreateBool("Shotgun Pellet Tracers", Sub, Settings.Pellets.Value, (Action<bool>)delegate(bool v) { Set(Settings.Pellets, v); }); obj7.CreateInt("Max Tracers", Sub, Settings.MaxTracers.Value, 25, 25, 500, (Action<int>)delegate(int v) { Set(Settings.MaxTracers, v); }); obj7.CreateFloat("Max Lifetime (s)", Sub, Settings.MaxLifetime.Value, 0.5f, 0.5f, 15f, (Action<float>)delegate(float v) { Set(Settings.MaxLifetime, v); }); obj7.CreateBool("Notifications", Sub, Settings.Notifications.Value, (Action<bool>)delegate(bool v) { Set(Settings.Notifications, v); }); obj7.CreateFunction("Show Active Count", Color.white, (Action)delegate { Notify($"{TracerManager.ActiveCount} tracers in flight", (NotificationType)0, force: true); }); _root.CreateFunction("Clear All Tracers", Warn, (Action)delegate { TracerManager.ClearAll(); Notify("Tracers cleared", (NotificationType)0); }); _root.CreateFunction("Reset To Defaults", Warn, (Action)delegate { Menu_ResetDialog(); }); } private static void Menu_ResetDialog() { try { Menu.DisplayDialog("Reset TracerFX?", "All tracer settings will go back to default.", (Texture2D)null, (Action)delegate { Settings.ResetAll(); TracerManager.ClearAll(); OrangeTips.Refresh(); Rebuild(); Menu.OpenPage(_root); Notify("Settings reset", (NotificationType)3); }, (Action)null); } catch (Exception ex) { Core.Log.Warning("Dialog failed, resetting directly: " + ex.Message); Settings.ResetAll(); OrangeTips.Refresh(); Rebuild(); } } private static void ApplyBallistics(float fps, float grav, float hop, float drag, float spread, string name) { Settings.SpeedFps.Value = fps; Settings.GravityScale.Value = grav; Settings.HopUp.Value = hop; Settings.Drag.Value = drag; Settings.SpreadDeg.Value = spread; Settings.Save(); Rebuild(); Notify("Ballistics: " + name, (NotificationType)3); } private static void Set<T>(MelonPreferences_Entry<T> entry, T value) { entry.Value = value; Settings.Save(); } private static void Notify(string msg, NotificationType type, bool force = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if (!force && !Settings.Notifications.Value) { return; } try { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("TracerFX"), Message = NotificationText.op_Implicit(msg), ShowTitleOnPopup = true, PopupLength = 1.5f, Type = type }); } catch { } } } public static class OrangeTips { private class Tip { public GameObject Go; public MeshRenderer R; } private const string TipName = "TracerFX_OrangeTip"; public static readonly Color BlazeOrange = new Color(1f, 0.36f, 0.02f); private static readonly Dictionary<IntPtr, Tip> _tips = new Dictionary<IntPtr, Tip>(); private static readonly Dictionary<IntPtr, Gun> _known = new Dictionary<IntPtr, Gun>(); private static bool _layoutDirty = true; private static readonly Dictionary<IntPtr, Color> _remote = new Dictionary<IntPtr, Color>(); private static readonly HashSet<IntPtr> _failed = new HashSet<IntPtr>(); private static readonly List<IntPtr> _dead = new List<IntPtr>(); private static readonly Dictionary<int, Material> _mats = new Dictionary<int, Material>(); private static Material _template; private static float _nextScan; public static Color LocalTipColor { get { //IL_001c: 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) if (!Settings.TipMatchTracer.Value) { return BlazeOrange; } return Settings.PresetToColor((TracerColor)Settings.Preset.Value); } } public static void Register(Gun gun) { if (!((Object)(object)gun == (Object)null)) { _known[((Il2CppObjectBase)gun).Pointer] = gun; } } public static void ScanScene() { try { foreach (Gun item in Object.FindObjectsOfType<Gun>()) { Register(item); } } catch (Exception ex) { Core.Log.Warning("Gun scan failed: " + ex.Message); } _nextScan = 0f; } public static void OnLevelUnloaded() { _known.Clear(); _tips.Clear(); _failed.Clear(); } public static void Tick() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextScan) { return; } _nextScan = Time.unscaledTime + 1f; _dead.Clear(); foreach (KeyValuePair<IntPtr, Tip> tip in _tips) { if ((Object)(object)tip.Value.Go == (Object)null) { _dead.Add(tip.Key); } } foreach (IntPtr item in _dead) { _tips.Remove(item); } _dead.Clear(); foreach (KeyValuePair<IntPtr, Gun> item2 in _known) { if ((Object)(object)item2.Value == (Object)null) { _dead.Add(item2.Key); } } foreach (IntPtr item3 in _dead) { _known.Remove(item3); } _remote.Clear(); foreach (RemoteTipHolder item4 in FusionCompat.RemoteTipHolders()) { AddRemote(item4.Left, item4.Color); AddRemote(item4.Right, item4.Color); } bool value = Settings.OrangeTip.Value; if (value) { foreach (Gun value2 in _known.Values) { Ensure(value2); } } foreach (KeyValuePair<IntPtr, Tip> tip2 in _tips) { Apply(tip2.Key, tip2.Value, value); } _layoutDirty = false; } private static void AddRemote(Hand hand, Color c) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hand == (Object)null)) { Gun val = null; try { val = Player.GetComponentInHand<Gun>(hand); } catch { } if (!((Object)(object)val == (Object)null)) { _remote[((Il2CppObjectBase)val).Pointer] = c; Ensure(val); } } } private static void Ensure(Gun gun) { if ((Object)(object)gun == (Object)null || _tips.ContainsKey(((Il2CppObjectBase)gun).Pointer) || _failed.Contains(((Il2CppObjectBase)gun).Pointer)) { return; } try { _tips[((Il2CppObjectBase)gun).Pointer] = Attach(gun); } catch (Exception ex) { Core.Log.Warning("Orange tip attach failed: " + ex.Message); _failed.Add(((Il2CppObjectBase)gun).Pointer); } } private static void Apply(IntPtr gun, Tip tip, bool localOn) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tip.Go == (Object)null) { return; } Color value; bool flag = _remote.TryGetValue(gun, out value); bool flag2 = flag || localOn; if (flag2) { if (_layoutDirty || !tip.Go.activeSelf) { Layout(tip.Go); } Material val = MaterialFor(flag ? value : LocalTipColor); if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)tip.R).sharedMaterial != (Object)(object)val) { ((Renderer)tip.R).sharedMaterial = val; } } if (tip.Go.activeSelf != flag2) { tip.Go.SetActive(flag2); } } private static Tip Attach(Gun gun) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown Transform val = (((Object)(object)gun.firePointTransform != (Object)null) ? gun.firePointTransform : ((Component)gun).transform); EnsureTemplate(gun); Transform val2 = val.Find("TracerFX_OrangeTip"); GameObject val3; if ((Object)(object)val2 != (Object)null) { val3 = ((Component)val2).gameObject; } else { val3 = new GameObject("TracerFX_OrangeTip"); val3.transform.SetParent(val, false); val3.AddComponent<MeshFilter>().sharedMesh = LowPoly.Cylinder; val3.AddComponent<MeshRenderer>(); } MeshRenderer component = val3.GetComponent<MeshRenderer>(); ((Renderer)component).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component).receiveShadows = !Perf.IsStandaloneDevice; ((Renderer)component).reflectionProbeUsage = (ReflectionProbeUsage)0; Layout(val3); val3.SetActive(false); return new Tip { Go = val3, R = component }; } private static void Layout(GameObject tip) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) Transform transform = tip.transform; Transform parent = transform.parent; float num = Settings.TipDiameterCm.Value * 0.01f; float num2 = Settings.TipLengthCm.Value * 0.01f; float num3 = Settings.TipOffsetCm.Value * 0.01f; Vector3 val = (((Object)(object)parent != (Object)null) ? parent.lossyScale : Vector3.one); float num4 = ((Mathf.Abs(val.x) > 0.0001f) ? Mathf.Abs(val.x) : 1f); float num5 = ((Mathf.Abs(val.y) > 0.0001f) ? Mathf.Abs(val.y) : 1f); float num6 = ((Mathf.Abs(val.z) > 0.0001f) ? Mathf.Abs(val.z) : 1f); transform.localRotation = Quaternion.Euler(90f, 0f, 0f); transform.localScale = new Vector3(num / num4, num2 * 0.5f / num6, num / num5); transform.localPosition = new Vector3(0f, 0f, (num3 - num2 * 0.5f) / num6); } private static void EnsureTemplate(Gun gun) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown if ((Object)(object)_template != (Object)null) { return; } string[] array = new string[4] { "Universal Render Pipeline/Lit", "Universal Render Pipeline/Simple Lit", "SLZ/SLZ Standard", "Universal Render Pipeline/Unlit" }; for (int i = 0; i < array.Length; i++) { Shader val = Shader.Find(array[i]); if ((Object)(object)val != (Object)null) { _template = new Material(val); break; } } if ((Object)(object)_template == (Object)null) { MeshRenderer componentInChildren = ((Component)gun).GetComponentInChildren<MeshRenderer>(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)null) { _template = new Material(((Renderer)componentInChildren).sharedMaterial); array = new string[8] { "_BaseMap", "_MainTex", "_BumpMap", "_MetallicGlossMap", "_OcclusionMap", "_EmissionMap", "_DetailAlbedoMap", "_DetailNormalMap" }; foreach (string text in array) { if (_template.HasProperty(text)) { _template.SetTexture(text, (Texture)null); } } } } if ((Object)(object)_template == (Object)null && Mats.EnsureBase()) { _template = Mats.New(); } if (!((Object)(object)_template == (Object)null)) { ((Object)_template).hideFlags = (HideFlags)32; if (_template.HasProperty("_Metallic")) { _template.SetFloat("_Metallic", 0f); } if (_template.HasProperty("_Smoothness")) { _template.SetFloat("_Smoothness", 0.35f); } if (_template.HasProperty("_Glossiness")) { _template.SetFloat("_Glossiness", 0.35f); } Core.Log.Msg("Orange tip shader: " + ((Object)_template.shader).name); } } private static Material MaterialFor(Color c) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //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_005d: Expected O, but got Unknown //IL_005e: 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_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_template == (Object)null) { return null; } Color32 val = Color32.op_Implicit(c); int key = (val.r << 16) | (val.g << 8) | val.b; if (_mats.TryGetValue(key, out var value) && (Object)(object)value != (Object)null) { return value; } value = new Material(_template) { hideFlags = (HideFlags)32 }; value.color = c; if (value.HasProperty("_BaseColor")) { value.SetColor("_BaseColor", c); } if (value.HasProperty("_EmissionColor")) { value.SetColor("_EmissionColor", Color.black); } _mats[key] = value; return value; } public static void Refresh() { _nextScan = 0f; _layoutDirty = true; bool value = Settings.OrangeTip.Value; foreach (KeyValuePair<IntPtr, Tip> tip in _tips) { Apply(tip.Key, tip.Value, value); } _layoutDirty = false; FusionCompat.AnnounceNow(); } public static void ApplyColor() { Refresh(); } } public enum PerfProfile { Auto, High, Standalone, Low } public static class Perf { public static bool IsStandaloneDevice { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)Application.platform != 11) { return Application.isMobilePlatform; } return true; } } public static PerfProfile Resolved { get { PerfProfile perfProfile = (PerfProfile)Mathf.Clamp(Settings.Profile.Value, 0, 3); if (perfProfile == PerfProfile.Auto) { perfProfile = ((!IsStandaloneDevice) ? PerfProfile.High : PerfProfile.Standalone); } return perfProfile; } } private static bool High => Resolved == PerfProfile.High; private static bool Low => Resolved == PerfProfile.Low; public static int MaxTracers => Mathf.Min(Settings.MaxTracers.Value, High ? 500 : (Low ? 24 : 60)); public static int PoolCap { get { if (!High) { if (!Low) { return 32; } return 12; } return 128; } } public static bool AllowLights => High; public static int MaxSubsteps { get { if (!High) { if (!Low) { return 3; } return 2; } return 8; } } public static float StepLength { get { if (!High) { if (!Low) { return 1.25f; } return 2f; } return 0.5f; } } public static int MaxRayHops { get { if (!High) { return 3; } return 6; } } public static int PelletCap { get { if (!High) { if (!Low) { return 4; } return 2; } return 12; } } public static float TrailMinVertexDistance { get { if (!High) { if (!Low) { return 0.06f; } return 0.12f; } return 0.02f; } } public static int TrailCapVertices { get { if (!High) { return 0; } return 2; } } public static float MaxTrailTime { get { if (!High) { if (!Low) { return 0.4f; } return 0.2f; } return 2f; } } public static float GlowInterval { get { if (!High) { return 0.1f; } return 0f; } } public static bool AllowMuzzleFlash => !Low; public static float LaserRange { get { if (!High) { return 120f; } return 300f; } } } public enum TracerMode { Airsoft, Bullet, Laser } public enum ColorMode { Preset, Custom, Rainbow, RandomPerShot, PerHand } public enum TracerColor { Green, Red, Orange, Yellow, Lime, Cyan, Blue, Purple, Pink, White } public static class Settings { private static MelonPreferences_Category _cat; private static readonly List<MelonPreferences_Entry> _all = new List<MelonPreferences_Entry>(); public static MelonPreferences_Entry<bool> Enabled; public static MelonPreferences_Entry<int> Mode; public static MelonPreferences_Entry<bool> PlayerGunsOnly; public static MelonPreferences_Entry<int> EveryNthShot; public static MelonPreferences_Entry<bool> Pellets; public static MelonPreferences_Entry<bool> Notifications; public static MelonPreferences_Entry<int> ColorModeE; public static MelonPreferences_Entry<int> Preset; public static MelonPreferences_Entry<int> LeftPreset; public static MelonPreferences_Entry<int> RightPreset; public static MelonPreferences_Entry<float> CustomR; public static MelonPreferences_Entry<float> CustomG; public static MelonPreferences_Entry<float> CustomB; public static MelonPreferences_Entry<float> RainbowSpeed; public static MelonPreferences_Entry<float> Intensity; public static MelonPreferences_Entry<float> SpeedFps; public static MelonPreferences_Entry<float> GravityScale; public static MelonPreferences_Entry<float> HopUp; public static MelonPreferences_Entry<float> Drag; public static MelonPreferences_Entry<float> SpreadDeg; public static MelonPreferences_Entry<int> Bounces; public static MelonPreferences_Entry<float> Restitution; public static MelonPreferences_Entry<float> TracerTimeScale; public static MelonPreferences_Entry<float> BulletSpeed; public static MelonPreferences_Entry<float> BBSize; public static MelonPreferences_Entry<float> TrailTime; public static MelonPreferences_Entry<float> TrailWidth; public static MelonPreferences_Entry<bool> GlowFade; public static MelonPreferences_Entry<bool> GlowLight; public static MelonPreferences_Entry<float> LightRange; public static MelonPreferences_Entry<bool> MuzzleFlash; public static MelonPreferences_Entry<bool> ImpactFlash; public static MelonPreferences_Entry<float> ImpactSize; public static MelonPreferences_Entry<bool> ImpactLight; public static MelonPreferences_Entry<bool> OrangeTip; public static MelonPreferences_Entry<float> TipDiameterCm; public static MelonPreferences_Entry<float> TipLengthCm; public static MelonPreferences_Entry<float> TipOffsetCm; public static MelonPreferences_Entry<bool> TipMatchTracer; public static MelonPreferences_Entry<bool> FusionSync; public static MelonPreferences_Entry<bool> FusionShowOthers; public static MelonPreferences_Entry<bool> FusionShowOthersTips; public static MelonPreferences_Entry<int> Profile; public static MelonPreferences_Entry<int> MaxTracers; public static MelonPreferences_Entry<float> MaxLifetime; private static int _shotIndex; public static TracerMode CurrentMode => (TracerMode)Mathf.Clamp(Mode.Value, 0, 2); public static ColorMode CurrentColorMode => (ColorMode)Mathf.Clamp(ColorModeE.Value, 0, 4); public static void Init() { _cat = MelonPreferences.CreateCategory("TracerFX", "TracerFX - Airsoft Tracers"); Enabled = E("Enabled", def: true); Mode = E("Mode", 0); PlayerGunsOnly = E("PlayerGunsOnly", def: false); EveryNthShot = E("EveryNthShot", 1); Pellets = E("ShotgunPellets", def: true); Notifications = E("Notifications", def: true); ColorModeE = E("ColorMode", 0); Preset = E("Preset", 0); LeftPreset = E("LeftHandPreset", 1); RightPreset = E("RightHandPreset", 0); CustomR = E("CustomR", 0.2f); CustomG = E("CustomG", 1f); CustomB = E("CustomB", 0.3f); RainbowSpeed = E("RainbowSpeed", 0.5f); Intensity = E("Intensity", 2.5f); SpeedFps = E("SpeedFPS", 350f); GravityScale = E("GravityScale", 1f); HopUp = E("HopUp", 1f); Drag = E("Drag", 1f); SpreadDeg = E("SpreadDegrees", 0.6f); Bounces = E("Bounces", 1); Restitution = E("Restitution", 0.35f); TracerTimeScale = E("TracerTimeScale", 1f); BulletSpeed = E("BulletModeSpeed", 250f); BBSize = E("BBSizeMultiplier", 2f); TrailTime = E("TrailTime", 0.25f); TrailWidth = E("TrailWidthMultiplier", 1f); GlowFade = E("GlowInTheDarkFade", def: true); GlowLight = E("BBLight", def: false); LightRange = E("BBLightRange", 1.5f); MuzzleFlash = E("TracerUnitFlash", def: true); ImpactFlash = E("ImpactFlash", def: true); ImpactSize = E("ImpactSize", 1f); ImpactLight = E("ImpactLight", def: false); OrangeTip = E("OrangeTip", def: false); TipDiameterCm = E("TipDiameterCm", 2.5f); TipLengthCm = E("TipLengthCm", 2f); TipOffsetCm = E("TipOffsetCm", 0f); TipMatchTracer = E("TipMatchTracerColor", def: false); FusionSync = E("FusionShareMyTracers", def: true); FusionShowOthers = E("FusionShowOthersTracers", def: true); FusionShowOthersTips = E("FusionShowOthersTips", def: true); Profile = E("PerformanceProfile", 0); MaxTracers = E("MaxTracers", 200); MaxLifetime = E("MaxLifetime", 4f); } private static MelonPreferences_Entry<T> E<T>(string id, T def) { MelonPreferences_Entry<T> val = _cat.CreateEntry<T>(id, def, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); _all.Add((MelonPreferences_Entry)(object)val); return val; } public static void Save() { _cat.SaveToFile(false); } public static void ResetAll() { foreach (MelonPreferences_Entry item in _all) { item.ResetToDefault(); } Save(); } public static Color PresetToColor(TracerColor c) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00e8: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) return (Color)(c switch { TracerColor.Green => new Color(0.1f, 1f, 0.2f), TracerColor.Red => new Color(1f, 0.08f, 0.05f), TracerColor.Orange => new Color(1f, 0.45f, 0.05f), TracerColor.Yellow => new Color(1f, 0.92f, 0.1f), TracerColor.Lime => new Color(0.6f, 1f, 0.05f), TracerColor.Cyan => new Color(0.05f, 0.95f, 1f), TracerColor.Blue => new Color(0.1f, 0.3f, 1f), TracerColor.Purple => new Color(0.6f, 0.15f, 1f), TracerColor.Pink => new Color(1f, 0.25f, 0.75f), _ => Color.white, }); } public static Color PickColor(int hand) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) _shotIndex++; return (Color)(CurrentColorMode switch { ColorMode.Custom => new Color(CustomR.Value, CustomG.Value, CustomB.Value), ColorMode.Rainbow => Color.HSVToRGB((Time.unscaledTime * RainbowSpeed.Value + (float)_shotIndex * 0.03f) % 1f, 1f, 1f), ColorMode.RandomPerShot => Color.HSVToRGB(Random.value, 0.9f, 1f), ColorMode.PerHand => hand switch { 0 => PresetToColor((TracerColor)LeftPreset.Value), 1 => PresetToColor((TracerColor)RightPreset.Value), _ => PresetToColor((TracerColor)Preset.Value), }, _ => PresetToColor((TracerColor)Preset.Value), }); } } public struct TracerStyle { public byte Mode; public float SpeedMs; public float Gravity; public float HopUp; public float Drag; public float Spread; public byte Bounces; public float Restitution; public float BBSize; public float TrailTime; public float TrailWidth; public float Intensity; public float LightRange; public float ImpactSize; public bool GlowFade; public bool Light; public bool ImpactFlash; public bool MuzzleFlash; public TracerMode TMode => (TracerMode)Mathf.Clamp((int)Mode, 0, 2); public static TracerStyle FromSettings() { TracerMode currentMode = Settings.CurrentMode; return new TracerStyle { Mode = (byte)currentMode, SpeedMs = ((currentMode == TracerMode.Bullet) ? Settings.BulletSpeed.Value : (Settings.SpeedFps.Value * 0.3048f)), Gravity = Settings.GravityScale.Value, HopUp = Settings.HopUp.Value, Drag = Settings.Drag.Value, Spread = Settings.SpreadDeg.Value, Bounces = (byte)Mathf.Clamp(Settings.Bounces.Value, 0, 5), Restitution = Settings.Restitution.Value, BBSize = Settings.BBSize.Value, TrailTime = Settings.TrailTime.Value, TrailWidth = Settings.TrailWidth.Value, Intensity = Settings.Intensity.Value, LightRange = Settings.LightRange.Value, ImpactSize = Settings.ImpactSize.Value, GlowFade = Settings.GlowFade.Value, Light = Settings.GlowLight.Value, ImpactFlash = Settings.ImpactFlash.Value, MuzzleFlash = Settings.MuzzleFlash.Value }; } public void Clamp() { Mode = (byte)Mathf.Clamp((int)Mode, 0, 2); SpeedMs = Mathf.Clamp(SpeedMs, 1f, 1000f); Gravity = Mathf.Clamp(Gravity, 0f, 3f); HopUp = Mathf.Clamp(HopUp, 0f, 2f); Drag = Mathf.Clamp(Drag, 0f, 3f); Spread = Mathf.Clamp(Spread, 0f, 25f); Bounces = (byte)Mathf.Clamp((int)Bounces, 0, 5); Restitution = Mathf.Clamp(Restitution, 0.05f, 0.9f); BBSize = Mathf.Clamp(BBSize, 0.5f, 10f); TrailTime = Mathf.Clamp(TrailTime, 0.02f, 2f); TrailWidth = Mathf.Clamp(TrailWidth, 0.1f, 5f); Intensity = Mathf.Clamp(Intensity, 0.25f, 10f); LightRange = Mathf.Clamp(LightRange, 0.25f, 6f); ImpactSize = Mathf.Clamp(ImpactSize, 0.1f, 5f); } } public struct ShotInfo { public Vector3 Origin; public Vector3 Direction; public Vector3 GunUp; public Color Color; public Transform IgnoreA; public Transform IgnoreB; public TracerStyle Style; } internal class Tracer { public GameObject Root; public GameObject BB; private Material _bbMat; private Material _trailMat; private TrailRenderer _trail; private Light _light; public bool Active; private bool _flying; private Vector3 _pos; private Vector3 _vel; private Vector3 _lift; private float _v0; private float _age; private float _fadeLeft; private float _nextGlow; private int _bouncesLeft; private Color _color; private Transform _ignA; private Transform _ignB; private TracerStyle _st; public float Age => _age; public bool Alive => (Object)(object)Root != (Object)null; public Tracer() { Root = Build.Root("TracerFX_BB"); (GameObject, MeshRenderer, Material) tuple = Build.Sphere(Root.transform); BB = tuple.Item1; _bbMat = tuple.Item3; _trail = Root.AddComponent<TrailRenderer>(); _trailMat = Mats.New(); ((Renderer)_trail).sharedMaterial = _trailMat; ((Renderer)_trail).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_trail).receiveShadows = false; _trail.minVertexDistance = 0.02f; _trail.numCapVertices = 2; _trail.autodestruct = false; _light = Build.PointLight(Root); Root.SetActive(false); } public void Launch(in ShotInfo s) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) _st = s.Style; _v0 = Mathf.Max(1f, _st.SpeedMs); _pos = s.Origin; Vector3 val = s.Direction; _vel = ((Vector3)(ref val)).normalized * _v0; val = Vector3.ProjectOnPlane(s.GunUp, s.Direction); _lift = ((Vector3)(ref val)).normalized; if (((Vector3)(ref _lift)).sqrMagnitude < 0.01f) { _lift = Vector3.up; } _ignA = s.IgnoreA; _ignB = s.IgnoreB; _bouncesLeft = ((_st.TMode != TracerMode.Bullet) ? _st.Bounces : 0); _color = s.Color; _age = 0f; _flying = true; Active = true; float num = 0.006f * _st.BBSize; BB.transform.localScale = Vector3.one * num; BB.SetActive(true); Mats.SetColor(_bbMat, _color, _st.Intensity * 1.5f); float num2 = num * 0.9f * _st.TrailWidth; _trail.time = Mathf.Min(_st.TrailTime, Perf.MaxTrailTime); _trail.minVertexDistance = Perf.TrailMinVertexDistance; _trail.numCapVertices = Perf.TrailCapVertices; _nextGlow = 0f; _trail.startWidth = num2; _trail.endWidth = num2 * 0.15f; Color color = _color; color.a = 1f; Color color2 = _color; color2.a = 0f; _trail.startColor = color; _trail.endColor = color2; Mats.SetColor(_trailMat, Color.white, _st.Intensity); Root.transform.position = _pos; Root.SetActive(true); _trail.Clear(); _trail.emitting = true; ((Behaviour)_light).enabled = _st.Light && Perf.AllowLights; if (((Behaviour)_light).enabled) { _light.color = _color; _light.range = _st.LightRange; _light.intensity = 1.5f * _st.Intensity; } } public void Tick(float dt) { //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } _age += dt; if (!_flying) { _fadeLeft -= dt; if (_fadeLeft <= 0f) { Retire(); } return; } if (_age > Settings.MaxLifetime.Value || _pos.y < -500f) { Stop(); return; } if (_st.GlowFade && _st.TMode == TracerMode.Airsoft && _age >= _nextGlow) { _nextGlow = _age + Perf.GlowInterval; float num = Mathf.Lerp(1f, 0.35f, Mathf.Clamp01(_age / 1.5f)); Mats.SetColor(_bbMat, _color, _st.Intensity * 1.5f * num); if (((Behaviour)_light).enabled) { _light.intensity = 1.5f * _st.Intensity * num; } } int num2 = Mathf.Clamp(Mathf.CeilToInt(((Vector3)(ref _vel)).magnitude * dt / Perf.StepLength), 1, Perf.MaxSubsteps); float h = dt / (float)num2; for (int i = 0; i < num2; i++) { if (!_flying) { break; } Step(h); } Root.transform.position = _pos; } private void Step(float h) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_006e: 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_0079: 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) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; if (_st.TMode == TracerMode.Airsoft) { float magnitude = ((Vector3)(ref _vel)).magnitude; val += Physics.gravity * _st.Gravity; float num = magnitude / _v0; val += _lift * (_st.HopUp * 9.81f * 0.95f * num * num); val += -_vel * (0.012f * _st.Drag * magnitude); } Vector3 val2 = _vel + val * h; Vector3 val3 = val2 * h; float magnitude2 = ((Vector3)(ref val3)).magnitude; RaycastHit hit; if (magnitude2 < 1E-06f) { _vel = val2; } else if (Core.SafeRaycast(_pos, val3 / magnitude2, magnitude2, _ignA, _ignB, out hit)) { if (_bouncesLeft > 0 && _st.TMode == TracerMode.Airsoft) { _bouncesLeft--; Vector3 val4 = Vector3.Reflect(val2, ((RaycastHit)(ref hit)).normal) * _st.Restitution; _pos = ((RaycastHit)(ref hit)).point + ((RaycastHit)(ref hit)).normal * 0.003f; _vel = val4; Vector3 val5 = Vector3.ProjectOnPlane(_lift, val4); _lift = ((Vector3)(ref val5)).normalized; TracerManager.Impact(((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, _color, 0.45f, in _st); if (((Vector3)(ref _vel)).magnitude < 1.5f) { Stop(); } } else { _pos = ((RaycastHit)(ref hit)).point; TracerManager.Impact(((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, _color, 1f, in _st); Stop(); } } else { _pos += val3; _vel = val2; } } private void Stop() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) _flying = false; BB.SetActive(false); ((Behaviour)_light).enabled = false; _trail.emitting = false; Root.transform.position = _pos; _fadeLeft = _trail.time + 0.05f; } public void Retire() { Active = false; _flying = false; if (!((Object)(object)Root == (Object)null)) { _trail.emitting = false; _trail.Clear(); Root.SetActive(false); } } public void Destroy() { if ((Object)(object)Root != (Object)null) { Object.Destroy((Object)(object)Root); } if ((Object)(object)_bbMat != (Object)null) { Object.Destroy((Object)(object)_bbMat); } if ((Object)(object)_trailMat != (Object)null) { Object.Destroy((Object)(object)_trailMat); } } } internal class Beam { public GameObject Root; private LineRenderer _line; private Material _mat; public bool Active; private float _t; private float _life; private float _width; private Color _color; public bool Alive => (Object)(object)Root != (Object)null; public Beam() { Root = Build.Root("TracerFX_Beam"); _line = Root.AddComponent<LineRenderer>(); _mat = Mats.New(); ((Renderer)_line).sharedMaterial = _mat; _line.positionCount = 2; _line.useWorldSpace = true; _line.numCapVertices = 2; ((Renderer)_line).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_line).receiveShadows = false; Root.SetActive(false); } public void Show(Vector3 a, Vector3 b, Color c, in TracerStyle st) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) _color = c; _life = Mathf.Max(0.05f, st.TrailTime * 1.5f); _t = 0f; _width = 0.004f * st.BBSize * st.TrailWidth; _line.SetPosition(0, a); _line.SetPosition(1, b); Mats.SetColor(_mat, Color.white, st.Intensity); Apply(1f); Root.SetActive(true); Active = true; } private void Apply(float k) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Color color = _color; color.a = k; _line.startColor = color; _line.endColor = new Color(color.r, color.g, color.b, k * 0.6f); _line.startWidth = _width * k; _line.endWidth = _width * k * 0.7f; } public void Tick(float dt) { if (Active) { _t += dt; float num = 1f - _t / _life; if (num <= 0f) { Retire(); } else { Apply(num); } } } public void Retire() { Active = false; if ((Object)(object)Root != (Object)null) { Root.SetActive(false); } } public void Destroy() { if ((Object)(object)Root != (Object)null) { Object.Destroy((Object)(object)Root); } if ((Object)(object)_mat != (Object)null) { Object.Destroy((Object)(object)_mat); } } } internal class Flash { public GameObject Root; private GameObject _sphere; private Material _mat; private Light _light; public bool Active; private float _t; private float _life; private float _size; private float _intensity; private Color _color; public bool Alive => (Object)(object)Root != (Object)null; public Flash() { Root = Build.Root("TracerFX_Impact"); (GameObject, MeshRenderer, Material) tuple = Build.Sphere(Root.transform); _sphere = tuple.Item1; _mat = tuple.Item3; _light = Build.PointLight(Root); Root.SetActive(false); } public void Show(Vector3 p, Color c, float scale, in TracerStyle st) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) _color = c; _t = 0f; _life = 0.18f; _intensity = st.Intensity; _size = 0.035f * st.ImpactSize * scale * Mathf.Max(0.5f, st.BBSize * 0.5f); Root.transform.position = p; ((Behaviour)_light).enabled = Settings.ImpactLight.Value && Perf.AllowLights; if (((Behaviour)_light).enabled) { _light.color = c; _light.range = 1.2f * st.ImpactSize; } Apply(0f); Root.SetActive(true); Active = true; } private void Apply(float t) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) float num = 1f - t; _sphere.transform.localScale = Vector3.one * (_size * (0.4f + t)); Mats.SetColor(_mat, _color, _intensity * 2f * num * num); if (((Behaviour)_light).enabled) { _light.intensity = 3f * num; } } public void Tick(float dt) { if (Active) { _t += dt; float num = _t / _life; if (num >= 1f) { Retire(); } else { Apply(num); } } } public void Retire() { Active = false; if ((Object)(object)Root != (Object)null) { Root.SetActive(false); } } public void Destroy() { if ((Object)(object)Root != (Object)null) { Object.Destroy((Object)(object)Root); } if ((Object)(object)_mat != (Object)null) { Object.Destroy((Object)(object)_mat); } } } public static class TracerManager { private static readonly List<Tracer> _tracers = new List<Tracer>(); private static readonly List<Beam> _beams = new List<Beam>(); private static readonly List<Flash> _flashes = new List<Flash>(); public static int ActiveCount { get { int num = 0; foreach (Tracer tracer in _tracers) { if (tracer.Active) { num++; } } return num; } } public static void Fire(in ShotInfo s) { //IL_005f: 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) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if (!Mats.EnsureBase()) { return; } TracerStyle st = s.Style; if (st.MuzzleFlash && st.TMode == TracerMode.Airsoft && Perf.AllowMuzzleFlash) { Impact(s.Origin, -s.Direction, s.Color, 0.35f, in st, force: true); } if (st.TMode == TracerMode.Laser) { float laserRange = Perf.LaserRange; Vector3 b = s.Origin + s.Direction * laserRange; if (Core.SafeRaycast(s.Origin, s.Direction, laserRange, s.IgnoreA, s.IgnoreB, out var hit)) { b = ((RaycastHit)(ref hit)).point; Impact(((RaycastHit)(ref hit)).point, ((RaycastHit)(ref hit)).normal, s.Color, 1f, in st); } Get(_beams, () => new Beam(), (Beam x) => x.Active, (Beam x) => x.Alive)?.Show(s.Origin, b, s.Color, in st); } else { GetTracer()?.Launch(in s); } } private static Tracer GetTracer() { int num = 0; Tracer tracer = null; for (int num2 = _tracers.Count - 1; num2 >= 0; num2--) { Tracer tracer2 = _tracers[num2]; if (!tracer2.Alive) { _tracers.RemoveAt(num2); } else { if (!tracer2.Active) { return tracer2; } num++; if (tracer == null || tracer2.Age > tracer.Age) { tracer = tracer2; } } } if (num >= Perf.MaxTracers && tracer != null) { tracer.Retire(); return tracer; } Tracer tracer3 = new Tracer(); _tracers.Add(tracer3); return tracer3; } private static T Get<T>(List<T> list, Func<T> make, Func<T, bool> isActive, Func<T, bool> isAlive) where T : class { for (int num = list.Count - 1; num >= 0; num--) { if (!isAlive(list[num])) { list.RemoveAt(num); } else if (!isActive(list[num])) { return list[num]; } } if (list.Count >= Perf.PoolCap) { return null; } T val = make(); list.Add(val); return val; } internal static void Impact(Vector3 p, Vector3 n, Color c, float scale, in TracerStyle st, bool force = false) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if ((force || st.ImpactFlash) && Mats.Ready) { Get(_flashes, () => new Flash(), (Fl