Decompiled source of BoneyCam v0.1.3
Mods/BoneyCam.dll
Decompiled 5 days 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.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BoneLib; using BoneLib.BoneMenu; using BoneyCam; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Combat; using Il2CppSLZ.Data; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.AI; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Interaction; using Il2CppSLZ.Marrow.PuppetMasta; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.VRMK; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(Mod), "BoneyCam", "0.1.3", "Geozek", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0")] [assembly: AssemblyVersion("0.0.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 BoneyCam { public sealed class Mod : MelonMod { internal static Mod Instance; internal Settings S; internal Blood Blood; internal SoundEffects Sounds; private ChestCamera bodycam; private bool menuReady; private float nextMenu; private float nextError; public static event Action<Vector3, Vector3, Color> DropletEmitted; public static void ReceiveDroplet(Vector3 position, Vector3 velocity, Color color) { //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) Mod instance = Instance; if (instance != null && instance.S.Enabled.Value) { try { instance.Blood.Receive(position, velocity, color); } catch (Exception e) { instance.Error(e); } } } internal static void ShareDroplet(Vector3 position, Vector3 velocity, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) try { Mod.DropletEmitted?.Invoke(position, velocity, color); } catch (Exception e) { Instance?.Error(e); } } public override void OnInitializeMelon() { Instance = this; S = new Settings(); Blood = new Blood(this); bodycam = new ChestCamera(this); Sounds = new SoundEffects(this); ((MelonBase)this).LoggerInstance.Msg("BoneyCam 0.1.3: directional low-poly splashes, separate splash limits; 31 recorded blood drips and optional explosion ringing. Author: Geozek."); } public override void OnUpdate() { try { Sounds.Tick(); } catch (Exception e) { Sounds.Clear(); Error(e); } try { if (!menuReady && Time.unscaledTime >= nextMenu) { nextMenu = Time.unscaledTime + 2f; if (Page.Root != null) { S.Menu(this); menuReady = true; } } if (!S.Camera.Value && !S.Headcam.Value) { bodycam.Release(); } } catch (Exception e2) { Error(e2); } } internal void AfterRigLateUpdate(RigManager rig) { if ((Object)(object)rig != (Object)(object)Player.RigManager) { return; } try { bodycam.Tick(); } catch (Exception e) { bodycam.Release(); Error(e); } } public override void OnLateUpdate() { try { Blood.Tick(Mathf.Min(Time.deltaTime, 0.05f)); } catch (Exception e) { Error(e); } } public override void OnFixedUpdate() { try { Blood.CheckNoseImpact(); } catch (Exception e) { Error(e); } } public override void OnSceneWasUnloaded(int index, string name) { Sounds.Clear(); Blood.Clear(); bodycam.Release(); } public override void OnDeinitializeMelon() { Sounds.Clear(); Blood.Dispose(); bodycam.Release(); S.Category.SaveToFile(false); Instance = null; } internal void Error(Exception e) { if (!(Time.unscaledTime < nextError)) { nextError = Time.unscaledTime + 5f; ((MelonBase)this).LoggerInstance.Warning(e.ToString()); } } internal void Log(string text) { ((MelonBase)this).LoggerInstance.Msg(text); } internal void Status() { Log(Blood.Status + "; camera=" + bodycam.Status); } } internal sealed class Settings { internal readonly MelonPreferences_Category Category = MelonPreferences.CreateCategory("BoneyCam"); private readonly List<Action> resetControls = new List<Action>(); internal MelonPreferences_Entry<bool> Enabled; internal MelonPreferences_Entry<bool> Drips; internal MelonPreferences_Entry<bool> Pools; internal MelonPreferences_Entry<bool> Melee; internal MelonPreferences_Entry<bool> DeadOnly; internal MelonPreferences_Entry<bool> Camera; internal MelonPreferences_Entry<bool> Debug; internal MelonPreferences_Entry<bool> Shine; internal MelonPreferences_Entry<bool> ReplaceVanilla; internal MelonPreferences_Entry<bool> NpcColors; internal MelonPreferences_Entry<bool> VariedShapes; internal MelonPreferences_Entry<float> SurfaceTrailLength; internal MelonPreferences_Entry<float> SurfaceTrailChance; internal MelonPreferences_Entry<bool> Headcam; internal MelonPreferences_Entry<float> HeadFov; internal MelonPreferences_Entry<float> HeadX; internal MelonPreferences_Entry<float> HeadY; internal MelonPreferences_Entry<float> HeadZ; internal MelonPreferences_Entry<float> HeadPitch; internal MelonPreferences_Entry<float> HeadYaw; internal MelonPreferences_Entry<float> HeadRoll; internal MelonPreferences_Entry<float> HeadSmooth; internal MelonPreferences_Entry<bool> SurfaceTrails; internal MelonPreferences_Entry<bool> Ringing; internal MelonPreferences_Entry<bool> DripSounds; internal MelonPreferences_Entry<float> RingVolume; internal MelonPreferences_Entry<float> RingDuration; internal MelonPreferences_Entry<float> RingRange; internal MelonPreferences_Entry<float> DripVolume; internal MelonPreferences_Entry<float> RingDelayMs; internal MelonPreferences_Entry<float> RingFadeDownMs; internal MelonPreferences_Entry<bool> Nosebleeds; internal MelonPreferences_Entry<float> NoseSpeed; internal MelonPreferences_Entry<float> NoseDuration; internal MelonPreferences_Entry<float> WallStainScale; internal MelonPreferences_Entry<bool> CeilingDrips; internal MelonPreferences_Entry<float> Duration; internal MelonPreferences_Entry<float> Rate; internal MelonPreferences_Entry<float> DropSize; internal MelonPreferences_Entry<float> PoolGrowth; internal MelonPreferences_Entry<float> PoolRadius; internal MelonPreferences_Entry<float> Lifetime; internal MelonPreferences_Entry<float> DryTime; internal MelonPreferences_Entry<float> Red; internal MelonPreferences_Entry<float> Green; internal MelonPreferences_Entry<float> Blue; internal MelonPreferences_Entry<float> Opacity; internal MelonPreferences_Entry<float> Fov; internal MelonPreferences_Entry<float> X; internal MelonPreferences_Entry<float> Y; internal MelonPreferences_Entry<float> Z; internal MelonPreferences_Entry<float> Pitch; internal MelonPreferences_Entry<float> Yaw; internal MelonPreferences_Entry<float> Roll; internal MelonPreferences_Entry<float> Smooth; internal MelonPreferences_Entry<float> WetGloss; internal MelonPreferences_Entry<float> DryGloss; internal MelonPreferences_Entry<int> Wounds; internal MelonPreferences_Entry<int> Drops; internal MelonPreferences_Entry<int> Stains; internal MelonPreferences_Entry<int> SplashStains; internal MelonPreferences_Entry<int> SprayDrops; internal MelonPreferences_Entry<int> SprayExtraDrops; internal MelonPreferences_Entry<bool> ExitSpray; internal MelonPreferences_Entry<bool> PlayerBleeding; internal MelonPreferences_Entry<float> SprayChance; internal MelonPreferences_Entry<float> SpraySpeed; internal MelonPreferences_Entry<float> SpraySpread; internal MelonPreferences_Entry<float> SprayFloorShare; internal Settings() { Ringing = B("ExplosionRinging", v: true); DripSounds = B("BloodImpactSounds", v: true); RingVolume = F("RingingVolume", 0.15f); RingDuration = F("RingingSeconds", 12f); RingRange = F("RingingDistance", 12f); RingDelayMs = F("RingingDelayMilliseconds", 25f); RingFadeDownMs = F("RingingFadeDownMilliseconds", 40f); MelonPreferences_Entry<bool> val = B("FastRingingApplied", v: false); if (!val.Value) { RingDelayMs.Value = 25f; RingFadeDownMs.Value = 40f; val.Value = true; Category.SaveToFile(false); } DripVolume = F("BloodImpactVolume", 0.35f); SurfaceTrails = B("SurfaceBloodTrails", v: true); SurfaceTrailLength = F("SurfaceBloodTrailLength", 1f); SurfaceTrailChance = F("SurfaceBloodTailChance", 0.5f); WallStainScale = F("WallStainScale", 0.6f); CeilingDrips = B("CeilingBloodDrips", v: true); bool value = B("WallImpactNosebleeds", v: false).Value; bool value2 = B("NpcBluntFaceNosebleeds", v: true).Value; Nosebleeds = B("NosebleedsEnabled", value || value2); Nosebleeds.DefaultValue = true; NoseSpeed = F("NosebleedMinimumSpeed", 2.5f); NoseDuration = F("NosebleedSeconds", 8f); PlayerBleeding = B("PlayerBleeding", v: true); Enabled = B("BloodEnabled", v: true); Drips = B("DripsEnabled", v: true); Pools = B("PoolsEnabled", v: true); ReplaceVanilla = B("SuppressVanillaBloodImpacts", v: true); NpcColors = B("UseNpcBloodColors", v: true); VariedShapes = B("VariedStainShapes", v: true); ExitSpray = B("GunshotExitSpray", v: true); SprayChance = F("ExitSprayChance", 0.8f); SprayDrops = I("ExitSprayDroplets", 6); SpraySpeed = F("ExitSpraySpeed", 4f); SpraySpread = F("ExitSprayConeDegrees", 18f); SprayFloorShare = F("ExitSprayFloorShare", 0.5f); SprayExtraDrops = I("ExitSprayExtraHitDroplets", 4); Melee = B("SharpMeleeBleeding", v: true); DeadOnly = B("BleedOnlyWhenDead", v: false); Camera = B("BodycamEnabled", v: false); Debug = B("VerboseLogging", v: false); Duration = F("BleedSeconds", 15f); Rate = F("DropsPerSecond", 5f); DropSize = F("DropDiameter", 0.009f); PoolGrowth = F("AreaPerDrop", 0.0018f); PoolRadius = F("MaximumPoolRadius", 0.35f); Lifetime = F("StainLifetimeSeconds", 300f); DryTime = F("DryingSeconds", 60f); MelonPreferences_Entry<bool> val2 = B("FiveMinuteLifetimeApplied", v: false); if (!val2.Value) { Lifetime.Value = 300f; val2.Value = true; Category.SaveToFile(false); } Red = F("BloodRed", 0.3f); Green = F("BloodGreen", 0.012f); Blue = F("BloodBlue", 0.018f); Opacity = F("Opacity", 1f); Shine = B("WetBloodShine", v: true); WetGloss = F("WetSmoothness", 0.95f); DryGloss = F("DrySmoothness", 0.15f); Wounds = I("MaxWounds", 32); Drops = I("MaxDrops", 96); Stains = I("MaxStains", 200); SplashStains = I("MaxSmallSplashMarks", 256); Fov = F("BodycamFov", 100f); X = F("CameraRight", 0f); Y = F("CameraUp", 0.11f); Z = F("CameraForward", 0.2f); Pitch = F("CameraPitch", 12f); Yaw = F("CameraYaw", 0f); Roll = F("CameraRoll", 0f); Smooth = F("CameraSmoothing", 0f); Headcam = B("HeadcamEnabled", v: false); HeadFov = F("HeadcamFov", 100f); HeadX = F("HeadcamRight", 0.19f); HeadY = F("HeadcamUp", 0.16f); HeadZ = F("HeadcamForward", 0.17f); HeadPitch = F("HeadcamPitch", 0f); HeadYaw = F("HeadcamYaw", 0f); HeadRoll = F("HeadcamRoll", 0f); HeadSmooth = F("HeadcamSmoothing", 0f); } private MelonPreferences_Entry<bool> B(string n, bool v) { return Category.CreateEntry<bool>(n, v, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); } private MelonPreferences_Entry<float> F(string n, float v) { return Category.CreateEntry<float>(n, v, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); } private MelonPreferences_Entry<int> I(string n, int v) { return Category.CreateEntry<int>(n, v, (string)null, (string)null, false, false, (ValueValidator)null, (string)null); } internal static float V(MelonPreferences_Entry<float> e, float min, float max, float fallback) { if (!float.IsFinite(e.Value)) { return fallback; } return Math.Clamp(e.Value, min, max); } internal void Menu(Mod mod) { //IL_0038: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_06f1: Unknown result type (might be due to invalid IL or missing references) //IL_07f9: Unknown result type (might be due to invalid IL or missing references) //IL_081f: Unknown result type (might be due to invalid IL or missing references) //IL_08b3: 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_08fe: Unknown result type (might be due to invalid IL or missing references) //IL_0926: Unknown result type (might be due to invalid IL or missing references) resetControls.Clear(); Page obj = Page.Root.CreatePage("BoneyCam", new Color(0.8f, 0.12f, 0.16f), 8, true); Page p = obj.CreatePage("Blood & Wounds", Color.red, 8, true); Toggle(p, "Blood enabled", Enabled); Toggle(p, "Player bleeding", PlayerBleeding); Toggle(p, "Visible droplets", Drips); Toggle(p, "Pools grow and merge", Pools); Toggle(p, "Sharp melee bleeding", Melee); Toggle(p, "Only bleed after death", DeadOnly); Toggle(p, "Suppress vanilla blood impacts", ReplaceVanilla); Slider(p, "Bleed duration (seconds)", Duration, 1f, 2f, 120f); Slider(p, "Drops per second", Rate, 0.5f, 0.5f, 12f); Slider(p, "Drop diameter (m)", DropSize, 0.002f, 0.003f, 0.03f); Page p2 = obj.CreatePage("Gunshot Exit Spray", Color.red, 8, true); Toggle(p2, "Exit spray enabled", ExitSpray); Slider(p2, "Chance (0 to 1)", SprayChance, 0.1f, 0f, 1f); Integer(p2, "Spray amount (droplets)", SprayDrops, 1, 3, 64); Slider(p2, "Speed (m/s)", SpraySpeed, 0.5f, 1f, 8f); Slider(p2, "Cone angle (degrees)", SpraySpread, 2f, 2f, 35f); Slider(p2, "Floor share (0 to 1)", SprayFloorShare, 0.1f, 0f, 1f); Integer(p2, "Extra droplets per additional hit", SprayExtraDrops, 1, 0, 32); Page p3 = obj.CreatePage("Pools & Appearance", Color.red, 8, true); Toggle(p3, "Use NPC blood colours", NpcColors); Toggle(p3, "Varied stain shapes", VariedShapes); Toggle(p3, "Scattered splash droplets", SurfaceTrails); Slider(p3, "Splash spread multiplier", SurfaceTrailLength, 0.1f, 0.2f, 2f); Slider(p3, "Splash chance (0 to 1)", SurfaceTrailChance, 0.05f, 0f, 1f); Toggle(p3, "Ceiling drips (10 seconds)", CeilingDrips); Slider(p3, "Wall stain scale (relative to floor)", WallStainScale, 0.1f, 0.2f, 1f); Slider(p3, "Pool area per drop", PoolGrowth, 0.0003f, 0.0003f, 0.008f); Slider(p3, "Maximum pool radius (m)", PoolRadius, 0.05f, 0.05f, 1f); Slider(p3, "Stain lifetime (seconds)", Lifetime, 30f, 10f, 900f); Slider(p3, "Drying time (seconds)", DryTime, 5f, 5f, 300f); Slider(p3, "Red", Red, 0.025f, 0f, 1f); Slider(p3, "Green", Green, 0.01f, 0f, 1f); Slider(p3, "Blue", Blue, 0.01f, 0f, 1f); Slider(p3, "Opacity", Opacity, 0.05f, 0.1f, 1f); Toggle(p3, "Wet blood shine", Shine); Slider(p3, "Wet smoothness", WetGloss, 0.05f, 0f, 1f); Slider(p3, "Dry smoothness", DryGloss, 0.05f, 0f, 1f); Page p4 = obj.CreatePage("Bodycam", Color.cyan, 10, true); Toggle(p4, "Enable bodycam", Camera); Slider(p4, "Field of view", Fov, 5f, 50f, 130f); Slider(p4, "Right offset (m)", X, 0.01f, -0.5f, 0.5f); Slider(p4, "Up offset (m)", Y, 0.01f, -0.5f, 0.5f); Slider(p4, "Forward offset (m)", Z, 0.01f, 0.05f, 0.6f); Slider(p4, "Pitch down (degrees)", Pitch, 2f, -60f, 60f); Slider(p4, "Yaw (degrees)", Yaw, 2f, -90f, 90f); Slider(p4, "Roll (degrees)", Roll, 2f, -45f, 45f); Slider(p4, "Smoothing (seconds)", Smooth, 0.01f, 0f, 0.5f); Page p5 = obj.CreatePage("Helmetcam", Color.cyan, 10, true); Toggle(p5, "Enable helmetcam", Headcam); Slider(p5, "Field of view", HeadFov, 5f, 50f, 130f); Slider(p5, "Right offset (m)", HeadX, 0.01f, -0.5f, 0.5f); Slider(p5, "Up offset (m)", HeadY, 0.01f, -0.5f, 0.5f); Slider(p5, "Forward offset (m)", HeadZ, 0.01f, -0.5f, 0.6f); Slider(p5, "Pitch down (degrees)", HeadPitch, 2f, -60f, 60f); Slider(p5, "Yaw (degrees)", HeadYaw, 2f, -90f, 90f); Slider(p5, "Roll (degrees)", HeadRoll, 2f, -45f, 45f); Slider(p5, "Smoothing (seconds)", HeadSmooth, 0.01f, 0f, 0.5f); Toggle(p, "Nosebleeds", Nosebleeds); Slider(p, "Minimum head impact speed (m/s)", NoseSpeed, 0.25f, 0.5f, 10f); Slider(p, "Nosebleed duration (seconds)", NoseDuration, 1f, 1f, 30f); Page val = obj.CreatePage("Sound Effects", Color.cyan, 10, true); Toggle(val, "Blood impact sounds", DripSounds); Slider(val, "Blood impact volume", DripVolume, 0.05f, 0f, 1f); Toggle(val, "Explosion ringing", Ringing); Slider(val, "Ringing volume", RingVolume, 0.01f, 0f, 0.35f); Slider(val, "Ringing duration (seconds)", RingDuration, 1f, 1f, 15f); Slider(val, "Ringing distance (m)", RingRange, 1f, 2f, 30f); Slider(val, "Explosion audio delay (ms)", RingDelayMs, 5f, 0f, 500f); Slider(val, "Game audio fade-down (ms)", RingFadeDownMs, 5f, 0f, 500f); val.CreateFunction("Preview ringing (when enabled)", Color.yellow, (Action)mod.Sounds.Preview); Page val2 = obj.CreatePage("Limits & Diagnostics", Color.white, 10, true); Integer(val2, "Maximum wounds", Wounds, 4, 4, 64); Integer(val2, "Maximum droplets", Drops, 16, 16, 256); Integer(val2, "Maximum surface stains", Stains, 20, 20, 400); Toggle(val2, "Verbose logs", Debug); Integer(val2, "Maximum small splash marks", SplashStains, 32, 32, 1024); val2.CreateFunction("Print status to log", Color.white, (Action)mod.Status); val2.CreateFunction("Clear all BoneyCam blood", Color.white, (Action)mod.Blood.Clear); val2.CreateFunction("Test drips in front of player", Color.yellow, (Action)mod.Blood.Test); val2.CreateFunction("Reset all settings to defaults", Color.yellow, (Action)delegate { ResetDefaults(mod); }); mod.Log("BoneMenu ready. Use Limits & Diagnostics / Test drips to test rendering without shooting an NPC."); } private void ResetDefaults(Mod mod) { foreach (Action resetControl in resetControls) { resetControl(); } Category.SaveToFile(false); mod.Log("All BoneyCam settings reset to defaults and saved."); } private void Toggle(Page p, string n, MelonPreferences_Entry<bool> e) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) BoolElement control = p.CreateBool(n, Color.white, e.Value, (Action<bool>)delegate(bool v) { e.Value = v; Category.SaveToFile(false); }); resetControls.Add(delegate { ((MelonPreferences_Entry)e).ResetToDefault(); control.Value = e.Value; }); } private void Slider(Page p, string n, MelonPreferences_Entry<float> e, float step, float min, float max) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) FloatElement control = p.CreateFloat(n, Color.white, V(e, min, max, min), step, min, max, (Action<float>)delegate(float v) { e.Value = v; Category.SaveToFile(false); }); resetControls.Add(delegate { ((MelonPreferences_Entry)e).ResetToDefault(); control.Value = V(e, min, max, min); }); } private void Integer(Page p, string n, MelonPreferences_Entry<int> e, int step, int min, int max) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) IntElement control = p.CreateInt(n, Color.white, Math.Clamp(e.Value, min, max), step, min, max, (Action<int>)delegate(int v) { e.Value = v; Category.SaveToFile(false); }); resetControls.Add(delegate { ((MelonPreferences_Entry)e).ResetToDefault(); control.Value = Math.Clamp(e.Value, min, max); }); } } [HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")] internal static class PlayerBloodHook { private static void Prefix(PlayerDamageReceiver __instance, Attack attack) { try { Mod.Instance?.Blood.PlayerHit(__instance, attack); } catch (Exception e) { Mod.Instance?.Error(e); } } } [HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")] internal static class DamageHook { private static void Prefix(SubBehaviourHealth __instance, int m, Attack attack) { try { Mod.Instance?.Blood.Hit(__instance, m, attack); } catch (Exception e) { Mod.Instance?.Error(e); } } } [HarmonyPatch(typeof(RigManager), "LateUpdate")] internal static class RigLateHook { private static void Postfix(RigManager __instance) { Mod.Instance?.AfterRigLateUpdate(__instance); } } [HarmonyPatch(typeof(Projectile), "ExecuteEventCallback")] internal static class ProjectileHook { internal sealed class Shot { internal Vector3 Origin; internal Vector3 Direction; internal Collider Collider; private readonly HashSet<int> sprayOwners = new HashSet<int>(); internal bool ClaimSpray(int owner) { return sprayOwners.Add(owner); } internal bool Matches(Attack a) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000d: 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_001d: 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_0042: 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_004a: 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) if (a != null && (int)a.attackType == 1) { Vector3 val = a.origin - Origin; if (((Vector3)(ref val)).sqrMagnitude < 0.0004f) { val = a.direction; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { val = a.direction; return Vector3.Dot(((Vector3)(ref val)).normalized, ((Vector3)(ref Direction)).normalized) > 0.99f; } } } return false; } } [ThreadStatic] internal static Shot ActiveAttack; internal static Shot Match(Attack a) { if (ActiveAttack == null || !ActiveAttack.Matches(a)) { return null; } return ActiveAttack; } private static void Prefix(Projectile __instance, out Shot __state) { //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_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) __state = ActiveAttack; Attack attack = __instance._attack; ActiveAttack = ((attack != null) ? new Shot { Origin = attack.origin, Direction = attack.direction, Collider = attack.collider } : null); } private static Exception Finalizer(Exception __exception, Shot __state) { ActiveAttack = __state; return __exception; } } [HarmonyPatch(typeof(ImpactProperties), "ReceiveAttack")] internal static class NativeBloodHook { private static int suppressed; private static bool Prefix(ImpactProperties __instance) { Mod instance = Mod.Instance; if (instance == null || !instance.S.Enabled.Value || !instance.S.ReplaceVanilla.Value || !Object.op_Implicit((Object)(object)__instance)) { return true; } try { DataCardReference<SurfaceDataCard> surfaceDataCard = __instance.SurfaceDataCard; object obj; if (surfaceDataCard == null) { obj = null; } else { Barcode barcode = ((ScannableReference)surfaceDataCard).Barcode; obj = ((barcode != null) ? barcode.ID : null); } string id = (string)obj; SurfaceData surfaceData = __instance.surfaceData; if ((!BloodPalette.IsHydraulic(id) || !Object.op_Implicit((Object)(object)((Component)__instance).GetComponentInParent<PuppetMaster>())) && !BloodPalette.IsBloodSurface(id) && (!Object.op_Implicit((Object)(object)surfaceData) || ((Object)surfaceData).name != "Blood Surface")) { return true; } if (suppressed++ < 6 || instance.S.Debug.Value) { instance.Log("Suppressed native Blood surface impact VFX; BoneyCam damage hook remains separate."); } return false; } catch (Exception e) { instance.Error(e); return true; } } } internal static class BloodLayers { internal static int FindFree(int occupied) { for (int i = 0; i < 16; i++) { if ((occupied & (1 << i)) == 0) { return i; } } return -1; } internal static float Offset(int layer) { return 0.002f + (float)layer * 0.0005f; } } internal static class BloodPalette { internal static bool IsHydraulic(string id) { return id == "SLZ.Backlot.SurfaceDataCard.Hydraulic"; } internal static bool IsBloodSurface(string id) { switch (id) { default: return id == "SLZ.BONELAB.Content.SurfaceDataCard.ZapperPurple"; case "SLZ.Backlot.SurfaceDataCard.Blood": case "SLZ.Backlot.SurfaceDataCard.Bioluminescent": case "SLZ.BONELAB.Content.SurfaceDataCard.ZapperOrange": case "SLZ.BONELAB.Content.SurfaceDataCard.ZapperGreen": return true; } } internal static Color Normalize(Color c, Color fallback) { //IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_002f: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!float.IsFinite(c.r) || !float.IsFinite(c.g) || !float.IsFinite(c.b)) { return fallback; } float num = Mathf.Max(c.r, Mathf.Max(c.g, c.b)); if (num <= 0f) { return new Color(0f, 0f, 0f, 1f); } float num2 = ((num > 1f) ? (1f / num) : 1f); return new Color(Mathf.Max(0f, c.r) * num2, Mathf.Max(0f, c.g) * num2, Mathf.Max(0f, c.b) * num2, 1f); } internal static Color Fallback(string id, Color fallback) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_008f: 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) //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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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) return (Color)(id switch { "SLZ.Backlot.SurfaceDataCard.Hydraulic" => new Color(0.03773582f, 0.03773582f, 0.03773582f, 1f), "SLZ.BONELAB.Content.SurfaceDataCard.ZapperOrange" => Normalize(new Color(2.251858f, 0.643388f, 0.266229f), fallback), "SLZ.BONELAB.Content.SurfaceDataCard.ZapperGreen" => Normalize(new Color(0.700217f, 2.065593f, 0.14615f), fallback), "SLZ.BONELAB.Content.SurfaceDataCard.ZapperPurple" => Normalize(new Color(0.3f, 0f, 1.584314f), fallback), "SLZ.Backlot.SurfaceDataCard.Bioluminescent" => Normalize(new Color(0f, 0.707035f, 2.113208f), fallback), _ => fallback, }); } internal static Color Mix(Color a, float areaA, Color b, float areaB) { //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_0011: Unknown result type (might be due to invalid IL or missing references) return Color.Lerp(a, b, areaB / Mathf.Max(1E-06f, areaA + areaB)); } } [HarmonyPatch(typeof(AIBrain), "OnPoolDeInitialize")] internal static class DespawnHook { private static void Prefix(AIBrain __instance) { Mod.Instance?.Blood.Forget(__instance.puppetMaster); } } [HarmonyPatch(typeof(AIBrain), "OnResurrection")] internal static class ReviveHook { private static void Prefix(AIBrain __instance) { Mod.Instance?.Blood.Forget(__instance.puppetMaster); } } internal static class BloodImpact { internal static float Footprint(float speed, float strength) { if (!float.IsFinite(speed)) { speed = 2f; } if (!float.IsFinite(strength)) { strength = 1f; } float num = 0.8f + 0.1f * Math.Clamp(speed, 0f, 12f); return Math.Clamp(1f + (num - 1f) * Math.Clamp(strength, 0f, 2f), 0.5f, 3f); } } internal sealed class ExitSprayBurst { internal float Until; internal bool Passed; internal int Attempts; internal int Emitted; internal int Qualified; internal int Take(int first, int extra, int available) { int num = Math.Min((Qualified++ == 0) ? Math.Clamp(first, 3, 64) : Math.Clamp(extra, 0, 32), Math.Min(Math.Max(0, available), 64 - Emitted)); Emitted += num; return num; } } internal sealed class Blood { private sealed class Wound { internal bool Nose; internal bool BluntNose; internal Color Color; internal PuppetMaster Owner; internal RigManager PlayerOwner; internal Health PlayerHealth; internal int AvatarId; internal bool WasDead; internal Transform Anchor; internal Rigidbody Body; internal Vector3 Local; internal float End; internal float Next; internal float LastHit; } private sealed class Drop { internal Color Color; internal Renderer Renderer; internal GameObject Go; internal Vector3 Position; internal Vector3 Velocity; internal float Age; } private sealed class Stain { internal Stain TrailSource; internal float TrailReveal; internal float CeilingEnd; internal float NextCeilingDrip; internal Color Color; internal GameObject Go; internal Collider Surface; internal Vector3 LocalPoint; internal Vector3 LocalNormal; internal Vector3 LocalTangent; internal int Layer; internal int Shape; internal bool TrailMark; internal bool SmallSurface; internal float ReservedRadius; internal float Area; internal float Radius; internal float Last; internal float Created; internal Renderer Renderer; internal MaterialPropertyBlock Block = new MaterialPropertyBlock(); } private readonly Mod mod; private readonly List<Wound> wounds = new List<Wound>(); private readonly List<Drop> drops = new List<Drop>(); private readonly Stack<Drop> spareDrops = new Stack<Drop>(); private readonly MaterialPropertyBlock dropBlock = new MaterialPropertyBlock(); private readonly List<Stain> stains = new List<Stain>(); private int mainStainCount; private int splashStainCount; private Material material; private Material wetMaterial; private bool triedWetShader; private Mesh[] stainMeshes; private Mesh[] splashMeshes; private Texture2D[] masTextures; private float lastWet = -1f; private float lastDry = -1f; private Texture2D texture; private int received; private int emitted; private int landed; private readonly Dictionary<int, ExitSprayBurst> sprayTimes = new Dictionary<int, ExitSprayBurst>(); private float nextSpray; private int sprayed; private int sprayReports; private int confirmedShots; private string sprayResult = "no shot received"; private double tickMs; private double maxTickMs; private float nextStainUpdate; private float lastStainUpdate; private readonly Il2CppStructArray<RaycastHit> rayHits = new Il2CppStructArray<RaycastHit>(32L); private Transform noseTrackedHead; private Vector3 noseLastPosition; private Vector3 noseLastVelocity; private float noseCooldown; private readonly Il2CppStructArray<RaycastHit> noseHits = new Il2CppStructArray<RaycastHit>(8L); private readonly Dictionary<int, float> noseRollTimes = new Dictionary<int, float>(); private bool meshDiagnosticLogged; private int trailQueries; private int trailMarks; private float trailCredit = 40f; private bool directionDiagnosticLogged; private Settings S => mod.S; internal string Status => $"wounds={wounds.Count}, drops={drops.Count}, stains={mainStainCount}, small splashes={splashStainCount}, hits={received}, confirmed bullets={confirmedShots}, exit bursts={sprayed}, spray={sprayResult}, emitted={emitted}, landed={landed}, blood CPU ms={tickMs:F2}, peak={maxTickMs:F2}"; private void RemoveStain(int index) { Stain stain = stains[index]; if (stain.TrailMark) { splashStainCount--; } else { mainStainCount--; } DestroyStain(stain); stains.RemoveAt(index); } private void TrimStains(bool small, int limit) { int num = (small ? splashStainCount : mainStainCount) - limit; int num2 = 0; while (num > 0 && num2 < stains.Count) { if (stains[num2].TrailMark == small) { RemoveStain(num2); num--; } else { num2++; } } } private static void DestroyStain(Stain p) { if (Object.op_Implicit((Object)(object)p.Go)) { Object.Destroy((Object)(object)p.Go); } } internal Blood(Mod mod) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown this.mod = mod; } internal void CheckNoseImpact() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //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_00e0: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_012c: 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) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: 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_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) RigManager rigManager = Player.RigManager; Transform val = ((Object.op_Implicit((Object)(object)rigManager) && Object.op_Implicit((Object)(object)rigManager.physicsRig)) ? ((Rig)rigManager.physicsRig).m_head : null); if (!S.Enabled.Value || !S.PlayerBleeding.Value || !S.Nosebleeds.Value || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)rigManager.avatar) || !Object.op_Implicit((Object)(object)rigManager.health) || !rigManager.health.alive) { noseTrackedHead = null; noseLastVelocity = Vector3.zero; return; } Vector3 position = val.position; if ((Object)(object)val != (Object)(object)noseTrackedHead) { noseTrackedHead = val; noseLastPosition = position; noseLastVelocity = Vector3.zero; return; } Vector3 val2 = position - noseLastPosition; noseLastPosition = position; Rigidbody componentInParent = ((Component)val).GetComponentInParent<Rigidbody>(); Vector3 val3 = (Object.op_Implicit((Object)(object)componentInParent) ? componentInParent.GetPointVelocity(position) : (val2 / Mathf.Max(0.001f, Time.fixedDeltaTime))); Vector3 val4 = ((((Vector3)(ref val3)).sqrMagnitude >= ((Vector3)(ref noseLastVelocity)).sqrMagnitude) ? val3 : noseLastVelocity); noseLastVelocity = val3; if (!Finite(position) || !Finite(val4) || ((Vector3)(ref val2)).sqrMagnitude > 1f || ((Vector3)(ref val4)).sqrMagnitude > 400f || Time.time < noseCooldown) { return; } float num = Settings.V(S.NoseSpeed, 0.5f, 10f, 2.5f); if (((Vector3)(ref val4)).sqrMagnitude < num * num) { return; } Vector3 normalized = ((Vector3)(ref val4)).normalized; Transform head = Player.Head; if (!Object.op_Implicit((Object)(object)head) || Vector3.Dot(head.forward, normalized) < 0.4f) { return; } int num2 = Physics.RaycastNonAlloc(position, normalized, noseHits, 0.18f, -5, (QueryTriggerInteraction)1); bool flag = false; for (int i = 0; i < num2; i++) { RaycastHit val5 = ((Il2CppArrayBase<RaycastHit>)(object)noseHits)[i]; Collider collider = ((RaycastHit)(ref val5)).collider; if (Object.op_Implicit((Object)(object)collider) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<RigManager>()) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<PuppetMaster>()) && !Object.op_Implicit((Object)(object)collider.attachedRigidbody) && !(Mathf.Abs(((RaycastHit)(ref val5)).normal.y) > 0.5f) && !(0f - Vector3.Dot(val4, ((RaycastHit)(ref val5)).normal) < num)) { flag = true; break; } } if (flag) { Animator animator = rigManager.avatar.animator; Transform val6 = ((Object.op_Implicit((Object)(object)animator) && animator.isHuman) ? animator.GetBoneTransform((HumanBodyBones)10) : val); if (!Object.op_Implicit((Object)(object)val6)) { val6 = val; } Vector3 val7 = val6.position + head.forward * 0.09f - head.up * 0.025f; while (wounds.Count >= Math.Clamp(S.Wounds.Value, 4, 64)) { wounds.RemoveAt(0); } wounds.Add(new Wound { Nose = true, PlayerOwner = rigManager, PlayerHealth = rigManager.health, AvatarId = ((Object)rigManager.avatar).GetInstanceID(), Anchor = val6, Body = componentInParent, Color = CustomColor(), Local = val6.InverseTransformPoint(val7), End = Time.time + Settings.V(S.NoseDuration, 1f, 30f, 8f), Next = Time.time, LastHit = Time.time }); noseCooldown = Time.time + 5f; if (S.Debug.Value) { mod.Log("Wall impact nosebleed: head approach speed=" + ((Vector3)(ref val4)).magnitude.ToString("F2") + " m/s"); } } } private bool WoundValid(Wound wound) { if (wound.BluntNose && !S.Nosebleeds.Value) { return false; } if (wound.Nose && !S.Nosebleeds.Value) { return false; } if (Object.op_Implicit((Object)(object)wound.PlayerOwner)) { RigManager playerOwner = wound.PlayerOwner; if (!S.PlayerBleeding.Value || !Object.op_Implicit((Object)(object)wound.PlayerHealth) || !Object.op_Implicit((Object)(object)playerOwner.avatar) || ((Object)playerOwner.avatar).GetInstanceID() != wound.AvatarId) { return false; } bool flag = !wound.PlayerHealth.alive; if (wound.WasDead && !flag) { return false; } wound.WasDead = flag; return true; } return Object.op_Implicit((Object)(object)wound.Owner); } internal void PlayerHit(PlayerDamageReceiver receiver, Attack attack) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0053: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 //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_014e: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Invalid comparison between Unknown and I4 //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) if (!S.Enabled.Value || !S.PlayerBleeding.Value || !Object.op_Implicit((Object)(object)receiver) || attack == null || !(attack.damage > 0f) || !Finite(attack.origin)) { return; } AttackType attackType = attack.attackType; if ((int)attackType != 1 && (!S.Melee.Value || ((int)attackType != 16 && (int)attackType != 32))) { return; } Health health = receiver.health; RigManager val = (Object.op_Implicit((Object)(object)health) ? health._rigManager : null); if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)receiver).GetComponentInParent<RigManager>(); } if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)health) || !Object.op_Implicit((Object)(object)val.avatar)) { return; } ProjectileHook.Shot shot = ProjectileHook.Match(attack); Collider val2 = ((shot != null && Object.op_Implicit((Object)(object)shot.Collider)) ? shot.Collider : attack.collider); if (!Object.op_Implicit((Object)(object)val2) || (Object)(object)((Component)val2).GetComponentInParent<RigManager>() != (Object)(object)val) { val2 = ((Component)receiver).GetComponent<Collider>(); } if (!Object.op_Implicit((Object)(object)val2) || !val2.enabled || !((Component)val2).gameObject.activeInHierarchy || (Object)(object)((Component)val2).GetComponentInParent<RigManager>() != (Object)(object)val) { return; } Rigidbody attachedRigidbody = val2.attachedRigidbody; Transform transform = ((Component)val2).transform; Vector3 val3 = val2.ClosestPoint(attack.origin); if (!Finite(val3)) { return; } Color val4 = CustomColor(); ImpactProperties component = ((Component)val2).GetComponent<ImpactProperties>(); if (Object.op_Implicit((Object)(object)component)) { DataCardReference<SurfaceDataCard> surfaceDataCard = component.SurfaceDataCard; object obj; if (surfaceDataCard == null) { obj = null; } else { Barcode barcode = ((ScannableReference)surfaceDataCard).Barcode; obj = ((barcode != null) ? barcode.ID : null); } string id = (string)obj; if (BloodPalette.IsBloodSurface(id) || BloodPalette.IsHydraulic(id)) { val4 = BloodPalette.Fallback(id, val4); if (!BloodPalette.IsHydraulic(id) && Object.op_Implicit((Object)(object)component.surfaceData)) { val4 = BloodPalette.Normalize(component.surfaceData.ParicleColorTint, val4); } } } received++; float time = Time.time; if (S.ExitSpray.Value && (int)attackType == 1 && shot != null) { confirmedShots++; TryExitSpray(null, val2, val3, attack, val4, val); } foreach (Wound wound in wounds) { if (!((Object)(object)wound.PlayerOwner == (Object)(object)val) || !((Object)(object)wound.Anchor == (Object)(object)transform)) { continue; } Vector3 val5 = transform.TransformPoint(wound.Local) - val3; if (((Vector3)(ref val5)).sqrMagnitude < 0.0036f) { if (time - wound.LastHit > 0.08f) { wound.End = time + Settings.V(S.Duration, 2f, 120f, 15f); wound.LastHit = time; } return; } } while (wounds.Count >= Math.Clamp(S.Wounds.Value, 4, 64)) { wounds.RemoveAt(0); } wounds.Add(new Wound { PlayerOwner = val, PlayerHealth = health, AvatarId = ((Object)val.avatar).GetInstanceID(), WasDead = !health.alive, Anchor = transform, Body = attachedRigidbody, Color = val4, Local = transform.InverseTransformPoint(val3), End = time + Settings.V(S.Duration, 2f, 120f, 15f), Next = time + 0.12f, LastHit = time }); if (received <= 8 || S.Debug.Value) { mod.Log("Player wound on " + ((Object)transform).name + "; " + Status); } } internal unsafe void Hit(SubBehaviourHealth health, int muscleIndex, Attack attack) { //IL_002f: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 //IL_00be: 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) //IL_01ca: 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_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Invalid comparison between Unknown and I4 //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0227: 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_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0436: 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_04e8: Unknown result type (might be due to invalid IL or missing references) if (!S.Enabled.Value || health == null || attack == null || !health.isOrganic || !(attack.damage > 0f)) { return; } AttackType attackType = attack.attackType; bool flag = S.Nosebleeds.Value && (int)attackType == 2; if (!flag && (int)attackType != 1 && (!S.Melee.Value || ((int)attackType != 16 && (int)attackType != 32))) { return; } BehaviourBase behaviour = ((SubBehaviourBase)health).behaviour; PuppetMaster val = ((behaviour != null) ? behaviour.puppetMaster : null); ProjectileHook.Shot shot = ProjectileHook.Match(attack); Collider val2 = ((shot != null && Object.op_Implicit((Object)(object)shot.Collider)) ? shot.Collider : attack.collider); if (!Object.op_Implicit((Object)(object)val) || val.muscles == null || !Finite(attack.origin)) { return; } if (!Object.op_Implicit((Object)(object)val2)) { val2 = ResolveNetworkCollider(val, muscleIndex, attack.origin); } if (!Object.op_Implicit((Object)(object)val2) || !((Component)val2).gameObject.activeInHierarchy) { return; } Transform val3 = null; Rigidbody val4 = null; Muscle muscle = null; if (val.muscles == null) { return; } Rigidbody attachedRigidbody = val2.attachedRigidbody; if (!Object.op_Implicit((Object)(object)attachedRigidbody)) { return; } foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)val.muscles) { object obj; if (item == null) { obj = null; } else { MarrowBody marrowBody = item.marrowBody; obj = ((marrowBody != null) ? marrowBody._rigidbody : null); } Rigidbody val5 = (Rigidbody)obj; if (Object.op_Implicit((Object)(object)val5) && (Object)(object)attachedRigidbody == (Object)(object)val5) { val3 = ((Component)val5).transform; val4 = val5; muscle = item; break; } } if (!Object.op_Implicit((Object)(object)val3)) { return; } ImpactProperties val6 = ((Component)val2).GetComponent<ImpactProperties>(); if (!Object.op_Implicit((Object)(object)val6)) { val6 = ((Component)val3).GetComponent<ImpactProperties>(); } if (!Object.op_Implicit((Object)(object)val6)) { val6 = ((Component)val2).GetComponentInParent<ImpactProperties>(); } Color val7 = CustomColor(); if (Object.op_Implicit((Object)(object)val6)) { DataCardReference<SurfaceDataCard> surfaceDataCard = val6.SurfaceDataCard; object obj2; if (surfaceDataCard == null) { obj2 = null; } else { Barcode barcode = ((ScannableReference)surfaceDataCard).Barcode; obj2 = ((barcode != null) ? barcode.ID : null); } string text = (string)obj2; val7 = BloodPalette.Fallback(text, val7); if (!BloodPalette.IsHydraulic(text) && Object.op_Implicit((Object)(object)val6.surfaceData)) { val7 = BloodPalette.Normalize(val6.surfaceData.ParicleColorTint, val7); } if (received < 8 || S.Debug.Value) { Mod obj3 = mod; Color val8 = val7; obj3.Log("NPC blood surface=" + text + "; tint=" + ((object)(*(Color*)(&val8))/*cast due to .constrained prefix*/).ToString()); } } received++; Vector3 val9 = val2.ClosestPoint(attack.origin); if (!Finite(val9)) { return; } float time = Time.time; if (flag) { TryBluntNose(val, muscle, val2, val4, val9, val7, time); return; } if (S.ExitSpray.Value && (int)attackType == 1) { if (shot != null) { confirmedShots++; TryExitSpray(val, val2, val9, attack, val7); } else { SprayNote("no matching projectile callback"); } } val3 = ((Component)val2).transform; Vector3 val10; foreach (Wound wound in wounds) { if (!((Object)(object)wound.Owner == (Object)(object)val) || !((Object)(object)wound.Anchor == (Object)(object)val3)) { continue; } val10 = val3.TransformPoint(wound.Local) - val9; if (((Vector3)(ref val10)).sqrMagnitude < 0.0036f) { if (time - wound.LastHit > 0.08f) { wound.End = time + Settings.V(S.Duration, 2f, 120f, 15f); wound.LastHit = time; } return; } } while (wounds.Count >= Math.Clamp(S.Wounds.Value, 4, 64)) { wounds.RemoveAt(0); } wounds.Add(new Wound { Color = val7, Owner = val, Anchor = val3, Body = val4, Local = val3.InverseTransformPoint(val9), End = time + Settings.V(S.Duration, 2f, 120f, 15f), Next = time + 0.12f, LastHit = time }); if (received <= 8 || S.Debug.Value) { Mod obj4 = mod; string[] obj5 = new string[10] { "Wound registered: collider=", ((Object)val2).name, "; physics=", ((Object)val4).name, "; anchor=", ((Object)val3).name, "; hit=", null, null, null }; val10 = val9; obj5[7] = ((object)(*(Vector3*)(&val10))/*cast due to .constrained prefix*/).ToString(); obj5[8] = "; "; obj5[9] = Status; obj4.Log(string.Concat(obj5)); } } private void TryBluntNose(PuppetMaster owner, Muscle muscle, Collider collider, Rigidbody body, Vector3 point, Color color, float now) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //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_00da: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) if (muscle == null || muscle.props == null || (int)muscle.props.group != 2 || !Object.op_Implicit((Object)(object)owner.targetRoot)) { return; } Vector3 val = owner.targetRoot.forward; Animator targetAnimator = owner.targetAnimator; if (Object.op_Implicit((Object)(object)targetAnimator) && targetAnimator.isHuman) { Transform boneTransform = targetAnimator.GetBoneTransform((HumanBodyBones)10); Transform boneTransform2 = targetAnimator.GetBoneTransform((HumanBodyBones)21); Transform boneTransform3 = targetAnimator.GetBoneTransform((HumanBodyBones)22); if (Object.op_Implicit((Object)(object)boneTransform) && Object.op_Implicit((Object)(object)boneTransform2) && Object.op_Implicit((Object)(object)boneTransform3)) { Vector3 val2 = Vector3.ProjectOnPlane((boneTransform2.position + boneTransform3.position) * 0.5f - boneTransform.position, owner.targetRoot.up); if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) { val = ((Vector3)(ref val2)).normalized; } } } Bounds bounds = collider.bounds; Vector3 val3 = point - ((Bounds)(ref bounds)).center; if (((Vector3)(ref val3)).sqrMagnitude < 1E-06f || Vector3.Dot(((Vector3)(ref val3)).normalized, val) < 0.25f) { return; } int instanceID = ((Object)owner).GetInstanceID(); if (noseRollTimes.TryGetValue(instanceID, out var value) && now - value < 0.35f) { return; } if (noseRollTimes.Count >= 128) { noseRollTimes.Clear(); } noseRollTimes[instanceID] = now; if (Random.value >= 0.5f) { return; } bounds = collider.bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 val4 = val; bounds = collider.bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; Vector3 val5 = collider.ClosestPoint(center + val4 * (((Vector3)(ref extents)).magnitude + 0.05f)); if (!Finite(val5)) { return; } foreach (Wound wound in wounds) { if (wound.BluntNose && (Object)(object)wound.Owner == (Object)(object)owner) { wound.End = now + Settings.V(S.NoseDuration, 1f, 30f, 8f); wound.LastHit = now; return; } } while (wounds.Count >= Math.Clamp(S.Wounds.Value, 4, 64)) { wounds.RemoveAt(0); } wounds.Add(new Wound { BluntNose = true, Owner = owner, Anchor = ((Component)collider).transform, Body = body, Color = color, Local = ((Component)collider).transform.InverseTransformPoint(val5), End = now + Settings.V(S.NoseDuration, 1f, 30f, 8f), Next = now, LastHit = now }); if (S.Debug.Value) { mod.Log("NPC face nosebleed: blunt hit passed 50% roll; collider=" + ((Object)collider).name); } } private static Collider NearestBodyCollider(Rigidbody body, Vector3 origin) { //IL_005c: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) if (!Object.op_Implicit((Object)(object)body)) { return null; } Collider result = null; float num = float.MaxValue; foreach (Collider componentsInChild in ((Component)body).GetComponentsInChildren<Collider>(true)) { if (Object.op_Implicit((Object)(object)componentsInChild) && componentsInChild.enabled && !componentsInChild.isTrigger && ((Component)componentsInChild).gameObject.activeInHierarchy && !((Object)(object)componentsInChild.attachedRigidbody != (Object)(object)body)) { Vector3 val = componentsInChild.ClosestPoint(origin) - origin; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = componentsInChild; } } } return result; } private static Collider ResolveNetworkCollider(PuppetMaster owner, int muscleIndex, Vector3 origin) { //IL_0033: 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_0088: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) Il2CppReferenceArray<Muscle> muscles = owner.muscles; if (muscleIndex >= 0 && muscleIndex < ((Il2CppArrayBase<Muscle>)(object)muscles).Length) { Muscle obj = ((Il2CppArrayBase<Muscle>)(object)muscles)[muscleIndex]; object body; if (obj == null) { body = null; } else { MarrowBody marrowBody = obj.marrowBody; body = ((marrowBody != null) ? marrowBody._rigidbody : null); } Collider val = NearestBodyCollider((Rigidbody)body, origin); if (Object.op_Implicit((Object)(object)val)) { return val; } } Collider result = null; float num = 0.0625f; foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)muscles) { object body2; if (item == null) { body2 = null; } else { MarrowBody marrowBody2 = item.marrowBody; body2 = ((marrowBody2 != null) ? marrowBody2._rigidbody : null); } Collider val2 = NearestBodyCollider((Rigidbody)body2, origin); if (Object.op_Implicit((Object)(object)val2)) { Vector3 val3 = val2.ClosestPoint(origin) - origin; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val2; } } } return result; } internal void Forget(PuppetMaster owner) { wounds.RemoveAll((Wound w) => (Object)(object)w.Owner == (Object)(object)owner); if (Object.op_Implicit((Object)(object)owner)) { sprayTimes.Remove(((Object)owner).GetInstanceID()); noseRollTimes.Remove(((Object)owner).GetInstanceID()); } } private void SprayNote(string reason) { sprayResult = reason; if (sprayReports++ < 16 || S.Debug.Value) { mod.Log("Exit spray: " + reason); } } private static bool OwnCollider(PuppetMaster owner, Collider c, RigManager player = null) { if (Object.op_Implicit((Object)(object)player)) { return (Object)(object)((Component)c).GetComponentInParent<RigManager>() == (Object)(object)player; } if (!Object.op_Implicit((Object)(object)owner)) { return false; } if ((Object)(object)((Component)c).GetComponentInParent<PuppetMaster>() == (Object)(object)owner) { return true; } Rigidbody attachedRigidbody = c.attachedRigidbody; if (!Object.op_Implicit((Object)(object)attachedRigidbody)) { return false; } foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)owner.muscles) { object obj; if (item == null) { obj = null; } else { MarrowBody marrowBody = item.marrowBody; obj = ((marrowBody != null) ? marrowBody._rigidbody : null); } if ((Object)obj == (Object)(object)attachedRigidbody) { return true; } } return false; } private void TryExitSpray(PuppetMaster owner, Collider collider, Vector3 point, Attack attack, Color color, RigManager player = null) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0167: 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_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: 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_022b: 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_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: 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_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) if (!attack.backFacing && Finite(attack.direction)) { Vector3 val = attack.direction; if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f)) { float time = Time.time; int num = (Object.op_Implicit((Object)(object)player) ? ((Object)player).GetInstanceID() : ((Object)owner).GetInstanceID()); ProjectileHook.Shot shot = ProjectileHook.Match(attack); if (shot == null || !shot.ClaimSpray(num)) { return; } if (!sprayTimes.TryGetValue(num, out var value) || time >= value.Until) { if (time < nextSpray) { SprayNote("global burst cooldown"); return; } if (sprayTimes.Count >= 64) { sprayTimes.Clear(); } value = new ExitSprayBurst { Until = time + 0.15f, Passed = (Random.value < Settings.V(S.SprayChance, 0f, 1f, 0.8f)) }; sprayTimes[num] = value; nextSpray = time + 0.04f; } if (!value.Passed) { SprayNote("burst chance skipped"); return; } if (value.Attempts++ >= 16 || value.Emitted >= 64) { SprayNote("burst budget reached"); return; } val = attack.direction; Vector3 normalized = ((Vector3)(ref val)).normalized; Bounds bounds = collider.bounds; val = ((Bounds)(ref bounds)).extents; float num2 = ((Vector3)(ref val)).magnitude * 2f + 0.05f; if (!float.IsFinite(num2) || num2 > 3f) { SprayNote("hit collider too large"); return; } RaycastHit val2 = default(RaycastHit); if (!collider.Raycast(new Ray(point + normalized * num2, -normalized), ref val2, num2)) { SprayNote("no far-side collider intersection"); return; } float num3 = Vector3.Dot(((RaycastHit)(ref val2)).point - point, normalized); if (!Finite(((RaycastHit)(ref val2)).point) || num3 < 0.015f || Vector3.Dot(((RaycastHit)(ref val2)).normal, normalized) < 0.05f) { SprayNote("glancing hit or no exit thickness"); return; } int num4 = Physics.RaycastNonAlloc(point + normalized * 0.002f, normalized, rayHits, num3 + 0.01f, -5, (QueryTriggerInteraction)1); if (num4 == ((Il2CppArrayBase<RaycastHit>)(object)rayHits).Length) { SprayNote("obstruction buffer full"); return; } for (int i = 0; i < num4; i++) { RaycastHit val3 = ((Il2CppArrayBase<RaycastHit>)(object)rayHits)[i]; Collider collider2 = ((RaycastHit)(ref val3)).collider; if (Object.op_Implicit((Object)(object)collider2) && (Object)(object)collider2 != (Object)(object)collider && !OwnCollider(owner, collider2, player)) { SprayNote("exit blocked by " + ((Object)collider2).name); return; } } val = Vector3.Cross(normalized, (Mathf.Abs(normalized.y) < 0.9f) ? Vector3.up : Vector3.right); Vector3 normalized2 = ((Vector3)(ref val)).normalized; Vector3 val4 = Vector3.Cross(normalized, normalized2); float num5 = Mathf.Tan(Settings.V(S.SpraySpread, 2f, 35f, 18f) * ((float)Math.PI / 180f)); int num6 = value.Take(S.SprayDrops.Value, S.SprayExtraDrops.Value, Math.Clamp(S.Drops.Value, 16, 256) - drops.Count); if (num6 == 0) { SprayNote("no additional droplet budget"); return; } int num7 = Math.Clamp((int)Math.Round((float)num6 * Settings.V(S.SprayFloorShare, 0f, 1f, 0.5f)), 0, num6); for (int j = 0; j < num6; j++) { Vector2 val5 = Random.insideUnitCircle * num5; val = normalized + normalized2 * val5.x + val4 * val5.y; Vector3 val6 = ((Vector3)(ref val)).normalized * Settings.V(S.SpraySpeed, 1f, 8f, 4f) * Random.Range(0.65f, 1.15f); if (j < num7) { val6 *= Random.Range(0.3f, 0.55f); val6.y = Mathf.Min(val6.y, 0f - Random.Range(0.6f, 1.4f)); } Emit(((RaycastHit)(ref val2)).point + normalized * 0.004f, color, val6, collider.attachedRigidbody); } if (value.Qualified == 1) { sprayed++; } SprayNote("exit hit " + value.Qualified + "; added=" + num6 + "; burst total=" + value.Emitted + "; source=" + ((Object)collider).name); return; } } SprayNote("back-facing or invalid direction"); } private static bool Finite(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (float.IsFinite(v.x) && float.IsFinite(v.y)) { return float.IsFinite(v.z); } return false; } private void Resources() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)material)) { return; } Shader val = Shader.Find("Sprites/Default"); if (!Object.op_Implicit((Object)(object)val)) { val = Shader.Find("Unlit/Transparent"); } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("No supported transparent blood shader found."); } material = new Material(val); ((Object)material).name = "BoneyCam blood"; ((Object)material).hideFlags = (HideFlags)32; material.renderQueue = 3000; texture = new Texture2D(64, 64, (TextureFormat)4, false); ((Object)texture).hideFlags = (HideFlags)32; ((Texture)texture).wrapMode = (TextureWrapMode)1; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num = ((float)j - 31.5f) / 31.5f; float num2 = ((float)i - 31.5f) / 31.5f; float num3 = Mathf.Atan2(num2, num); float num4 = Mathf.Clamp01((0.8f + 0.05f * Mathf.Sin(num3 * 7f) + 0.04f * Mathf.Sin(num3 * 11f + 1.7f) - Mathf.Sqrt(num * num + num2 * num2)) * 24f); texture.SetPixel(j, i, new Color(1f, 1f, 1f, num4)); } } texture.Apply(); material.mainTexture = (Texture)(object)texture; material.color = Color.white; mod.Log("Blood renderer initialized with " + ((Object)val).name); } private GameObject Visual(string name, PrimitiveType shape) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Resources(); GameObject obj = GameObject.CreatePrimitive(shape); ((Object)obj).name = name; obj.layer = 2; Collider component = obj.GetComponent<Collider>(); if (Object.op_Implicit((Object)(object)component)) { component.enabled = false; Object.Destroy((Object)(object)component); } Renderer component2 = obj.GetComponent<Renderer>(); component2.sharedMaterial = material; component2.shadowCastingMode = (ShadowCastingMode)0; component2.receiveShadows = false; return obj; } private Color CustomColor() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) return new Color(Settings.V(S.Red, 0f, 1f, 0.3f), Settings.V(S.Green, 0f, 1f, 0.012f), Settings.V(S.Blue, 0f, 1f, 0.018f), 1f); } private Color Tint(Color source, float dry, float alpha) { //IL_001a: 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_001b: 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_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references) Color val = (S.NpcColors.Value ? source : CustomColor()); float num = Mathf.Lerp(1f, 0.38f, dry); return new Color(val.r * num, val.g * num, val.b * num, alpha); } private Material SurfaceMaterial() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) if (!S.Shine.Value) { return material; } if (Object.op_Implicit((Object)(object)wetMaterial)) { return wetMaterial; } if (triedWetShader) { return material; } triedWetShader = true; Shader val = Shader.Find("SLZ/LitMAS/LitMAS Standard"); if (!Object.op_Implicit((Object)(object)val) || !val.isSupported) { mod.Log("LitMAS unavailable; using transparent unlit blood."); return material; } wetMaterial = new Material(val); ((Object)wetMaterial).name = "BoneyCam LitMAS blood"; ((Object)wetMaterial).hideFlags = (HideFlags)32; if (!wetMaterial.HasProperty("_BaseMap") || !wetMaterial.HasProperty("_BaseColor") || !wetMaterial.HasProperty("_MetallicGlossMap") || !wetMaterial.HasProperty("_Surface") || !wetMaterial.HasProperty("_BlendSrc") || !wetMaterial.HasProperty("_BlendDst") || !wetMaterial.HasProperty("_ZWrite")) { Object.Destroy((Object)(object)wetMaterial); wetMaterial = null; mod.Log("LitMAS fade inputs unavailable; using transparent unlit blood."); return material; } wetMaterial.SetTexture("_BaseMap", (Texture)(object)Texture2D.whiteTexture); wetMaterial.SetColor("_BaseColor", Color.white); wetMaterial.SetFloat("_Normals", 0f); wetMaterial.SetFloat("_Emission", 0f); wetMaterial.SetFloat("_Details", 0f); wetMaterial.SetFloat("_Surface", 2f); wetMaterial.SetFloat("_BlendSrc", 5f); wetMaterial.SetFloat("_BlendDst", 10f); wetMaterial.SetFloat("_ZWrite", 0f); wetMaterial.SetFloat("_Cull", 2f); wetMaterial.SetFloat("_SSROff", 1f); wetMaterial.EnableKeyword("_NO_SSR"); wetMaterial.SetOverrideTag("RenderType", "Transparent"); wetMaterial.renderQueue = 3000; mod.Log("Wet sheen initialized: LitMAS Fade; opacity and expiry fade preserve stain dimensions."); return wetMaterial; } private void BuildWetMesh() { //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Expected O, but got Unknown //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) bool flag = !meshDiagnosticLogged; meshDiagnosticLogged = true; if (flag) { mod.Log("DIAG combined: starting mesh generation."); } for (int i = 0; i < 2; i++) { bool flag2 = i == 1; bool flag3 = (flag2 ? splashMeshes : stainMeshes) != null; if (flag2) { if (splashMeshes == null) { splashMeshes = (Mesh[])(object)new Mesh[8]; } } else if (stainMeshes == null) { stainMeshes = (Mesh[])(object)new Mesh[8]; } Mesh[] array = (flag2 ? splashMeshes : stainMeshes); int num = (flag2 ? 8 : 64); for (int j = 0; j < array.Length; j++) { if (Object.op_Implicit((Object)(object)array[j])) { continue; } if (flag3) { mod.Log("Rebuilding missing " + (flag2 ? "splash" : "stain") + " mesh variant " + j); } Vector3[] array2 = (Vector3[])(object)new Vector3[num + 1]; Vector3[] array3 = (Vector3[])(object)new Vector3[num + 1]; Vector4[] array4 = (Vector4[])(object)new Vector4[num + 1]; Vector2[] array5 = (Vector2[])(object)new Vector2[num + 1]; int[] array6 = new int[num * 3]; for (int k = 0; k <= num; k++) { array4[k] = new Vector4(1f, 0f, 0f, -1f); } array3[0] = Vector3.back; array5[0] = new Vector2(0.5f, 0.5f); for (int l = 0; l < num; l++) { float num2 = (float)(l * 2) * (float)Math.PI / (float)num; float num3 = 0.37f + 0.045f * Mathf.Sin(num2 * (float)(3 + j) + (float)j * 0.71f) + 0.025f * Mathf.Sin(num2 * (float)(9 + j) + 1.7f + (float)j); if (flag2) { num3 = 0.37f + 0.025f * Mathf.Sin(num2 * 3f + (float)j * 0.71f) + 0.012f * Mathf.Sin(num2 * 2f + (float)j); } float num4 = 1f - (float)(j % 4) * 0.055f; array2[l + 1] = new Vector3(Mathf.Cos(num2) * num3 * num4, Mathf.Sin(num2) * num3, 0f); array3[l + 1] = Vector3.back; array5[l + 1] = new Vector2(0.5f, 0.5f); array6[l * 3] = 0; array6[l * 3 + 1] = (l + 1) % num + 1; array6[l * 3 + 2] = l + 1; } Mesh val = new Mesh(); ((Object)val).name = "BoneyCam " + (flag2 ? "low-poly splash" : "stain") + " variant " + j; ((Object)val).hideFlags = (HideFlags)32; val.vertices = Il2CppStructArray<Vector3>.op_Implicit(array2); val.normals = Il2CppStructArray<Vector3>.op_Implicit(array3); val.tangents = Il2CppStructArray<Vector4>.op_Implicit(array4); val.uv = Il2CppStructArray<Vector2>.op_Implicit(array5); val.triangles = Il2CppStructArray<int>.op_Implicit(array6); val.RecalculateBounds(); array[j] = val; } } if (flag) { mod.Log("DIAG combined: mesh generation completed, main=64 triangles, splash=8."); } } private Texture2D Mas(float dry) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) if (masTextures == null) { masTextures = (Texture2D[])(object)new Texture2D[16]; } float num = Settings.V(S.WetGloss, 0f, 1f, 0.95f); float num2 = Settings.V(S.DryGloss, 0f, 1f, 0.15f); bool flag = num != lastWet || num2 != lastDry; for (int i = 0; i < 16; i++) { if (!Object.op_Implicit((Object)(object)masTextures[i])) { Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false, true); ((Object)val).name = "BoneyCam wetness " + i; ((Object)val).hideFlags = (HideFlags)32; val.SetPixel(0, 0, new Color(0f, 1f, Mathf.Lerp(num, num2, (float)i / 15f), 1f)); val.Apply(); masTextures[i] = val; } else if (flag) { masTextures[i].SetPixel(0, 0, new Color(0f, 1f, Mathf.Lerp(num, num2, (float)i / 15f), 1f)); masTextures[i].Apply(); } } lastWet = num; lastDry = num2; return masTextures[Math.Clamp((int)(dry * 15f), 0, 15)]; } private void Emit(Vector3 position, Color color, Vector3? velocity = null, Rigidbody sourceBody = null, bool share = true) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_0161: 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_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: 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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) if (drops.Count >= Math.Clamp(S.Drops.Value, 16, 256)) { return; } Drop drop = ((spareDrops.Count > 0) ? spareDrops.Pop() : new Drop()); if (!Object.op_Implicit((Object)(object)drop.Go)) { drop.Go = Visual("BoneyCam droplet", (PrimitiveType)0); drop.Renderer = drop.Go.GetComponent<Renderer>(); } GameObject go = drop.Go; go.SetActive(true); float num = Settings.V(S.DropSize, 0.003f, 0.03f, 0.009f); go.transform.localScale = new Vector3(num, num * 1.5f, num); go.transform.position = position; dropBlock.SetColor("_Color", Tint(color, 0f, 1f)); drop.Renderer.SetPropertyBlock(dropBlock); go.GetComponent<Renderer>().enabled = S.Drips.Value; drop.Color = color; drop.Position = position; drop.Age = 0f; drop.Velocity = (Vector3)(((??)velocity) ?? new Vector3(Random.Range(-0.03f, 0.03f), -0.08f, Random.Range(-0.03f, 0.03f))); drops.Add(drop); emitted++; if (Object.op_Implicit((Object)(object)sourceBody)) { Vector3 pointVelocity = sourceBody.GetPointVelocity(position); if (Finite(pointVelocity)) { drop.Velocity += Vector3.ClampMagnitude(pointVelocity, 20f); } } if (share) { Mod.ShareDroplet(drop.Position, drop.Velocity, drop.Color); } } internal void Receive(Vector3 position, Vector3 velocity, Color color) { //IL_0000: 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) //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) if (Finite(position) && Finite(velocity) && !(((Vector3)(ref velocity)).sqrMagnitude > 10000f)) { Emit(position, color, velocity, null, share: false); } } internal void Test() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_008f: 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) //IL_009d: 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_00a8: Unknown result type (might be due to invalid IL or missing references) if (!S.Enabled.Value) { mod.Log("Enable blood before running the test."); return; } RigManager rigManager = Player.RigManager; object obj; if (rigManager == null) { obj = null; } else { ControllerRig controllerRig = rigManager.controllerRig; obj = ((controllerRig != null) ? ((Rig)controllerRig).m_head : null); } Transform val = (Transform)obj; if (!Object.op_Implicit((Object)(object)val)) { mod.Log("Test unavailable: player head not ready."); return; } Vector3 val2 = val.position + val.forward * 0.65f - Vector3.up * 0.3f; for (int i = 0; i < 12; i++) { Emit(val2 + Vector3.up * ((float)i * 0.025f), CustomColor()); } mod.Log("Emitted 12 test drops in front of the player. " + Status); } internal void Tick(float dt) { long timestamp = Stopwatch.GetTimestamp(); try { TickBlood(dt); } finally { tickMs = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; maxTickMs = Math.Max(maxTickMs, tickMs); } } private void TickBlood(float dt) { //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_048e: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing
Mods/BoneyCamFusion.dll
Decompiled 5 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BoneyCam; using BoneyCamFusion; using LabFusion.Network; using LabFusion.Network.Serialization; using LabFusion.Player; using LabFusion.SDK.Modules; using LabFusion.Scene; using MelonLoader; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(/*Could not decode attribute arguments.*/)] [assembly: MelonInfo(typeof(Bridge), "BoneyCam Fusion Blood Sync", "0.1.21", "Geozek", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : System.Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(/*Could not decode attribute arguments.*/)] internal sealed class RefSafetyRulesAttribute : System.Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BoneyCamFusion { public class BloodData : INetSerializable { public const int Size = 294; public byte Protocol = 1; public byte Count; public uint Sequence; public float[] Values = new float[72]; public int? GetSize() { return 294; } public void Serialize(INetSerializer s) { s.SerializeValue(ref Protocol); s.SerializeValue(ref Sequence); s.SerializeValue(ref Count); for (int i = 0; i < 72; i++) { s.SerializeValue(ref Values[i]); } } public bool Valid() { if (Protocol != 1 || Count < 1 || Count > 8 || Values == null || Values.Length != 72) { return false; } for (int i = 0; i < Count; i++) { for (int j = 0; j < 9; j++) { float num = Values[i * 9 + j]; if (!float.IsFinite(num) || Math.Abs(num) > (float)((j < 3) ? 100000 : ((j >= 6) ? 1 : 100)) || (j >= 6 && num < 0f)) { return false; } } } return true; } public static bool Newer(uint a, uint b) { return (int)(a - b) > 0; } } public class BloodMessage : ModuleMessageHandler { protected override void OnHandleMessage(ReceivedMessage received) { if (((ReceivedMessage)(ref received)).Sender.HasValue && ((ReceivedMessage)(ref received)).Bytes != null && ((ReceivedMessage)(ref received)).Bytes.Length == 294) { BloodData bloodData = ((ReceivedMessage)(ref received)).ReadData<BloodData>(); if (bloodData.Valid()) { Bridge.Queue(((ReceivedMessage)(ref received)).Sender.Value, bloodData); } } } } public class Bridge : MelonMod { private struct Incoming { internal byte Sender; internal BloodData Data; } private struct Drop { internal Vector3 Position; internal Vector3 Velocity; internal Color Color; } private static readonly object gate = new object(); private static readonly Queue<Incoming> incoming = new Queue<Incoming>(); private readonly Queue<Drop> outgoing = new Queue<Drop>(); private readonly Dictionary<byte, uint> sequences = new Dictionary<byte, uint>(); private bool ready; private bool connected; private uint sequence; private float nextSend; private float nextLog; private float nextError; private int sent; private int receivedCount; private int applied; private int dropped; public override void OnInitializeMelon() { } internal static void Queue(byte sender, BloodData data) { lock (gate) { if (incoming.Count < 64) { incoming.Enqueue(new Incoming { Sender = sender, Data = data }); } } } private void Capture(Vector3 position, Vector3 velocity, Color color) { //IL_0048: 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_0056: 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_005e: Unknown result type (might be due to invalid IL or missing references) if (ready && NetworkInfo.HasServer && PlayerIDManager.HasOtherPlayers) { if (outgoing.Count >= 256) { dropped++; return; } outgoing.Enqueue(new Drop { Position = NetworkTransformManager.EncodePosition(position), Velocity = velocity, Color = color }); } } public override void OnUpdate() { //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) try { if (!ready) { if (ModuleMessageManager.GetHandlerByType(typeof(BloodMessage)) == null) { ModuleMessageManager.RegisterHandler<BloodMessage>(); } Mod.DropletEmitted += Capture; ready = true; ((MelonBase)this).LoggerInstance.Msg("Fusion blood sharing ready. Both peers require BoneyCam and BoneyCamFusion 0.1.21."); } if (!NetworkInfo.HasServer) { if (connected) { Clear(); sequences.Clear(); } connected = false; return; } connected = true; uint b = default(uint); for (int num = 0; num < 16; num++) { Incoming incoming; lock (gate) { if (Bridge.incoming.Count == 0) { break; } incoming = Bridge.incoming.Dequeue(); goto IL_00bd; } IL_00bd: if (incoming.Sender != PlayerIDManager.LocalSmallID && PlayerIDManager.HasPlayerID(incoming.Sender)) { BloodData data = incoming.Data; if (!sequences.TryGetValue(incoming.Sender, ref b) || BloodData.Newer(data.Sequence, b)) { sequences[incoming.Sender] = data.Sequence; receivedCount++; for (int i = 0; i < data.Count; i++) { int num2 = i * 9; Vector3 val = NetworkTransformManager.DecodePosition(new Vector3(data.Values[num2], data.Values[num2 + 1], data.Values[num2 + 2])); if (NetworkTransformManager.IsInBounds(val)) { Mod.ReceiveDroplet(val, new Vector3(data.Values[num2 + 3], data.Values[num2 + 4], data.Values[num2 + 5]), new Color(data.Values[num2 + 6], data.Values[num2 + 7], data.Values[num2 + 8], 1f)); applied++; } } } } } if (Time.unscaledTime >= nextSend) { nextSend = Time.unscaledTime + 0.05f; for (int j = 0; j < 4; j++) { if (outgoing.Count <= 0) { break; } BloodData bloodData = new BloodData { Sequence = ++sequence }; while (bloodData.Count < 8 && outgoing.Count > 0) { Drop drop = outgoing.Dequeue(); int num3 = bloodData.Count * 9; bloodData.Values[num3] = drop.Position.x; bloodData.Values[num3 + 1] = drop.Position.y; bloodData.Values[num3 + 2] = drop.Position.z; bloodData.Values[num3 + 3] = drop.Velocity.x; bloodData.Values[num3 + 4] = drop.Velocity.y; bloodData.Values[num3 + 5] = drop.Velocity.z; bloodData.Values[num3 + 6] = Math.Clamp(drop.Color.r, 0f, 1f); bloodData.Values[num3 + 7] = Math.Clamp(drop.Color.g, 0f, 1f); bloodData.Values[num3 + 8] = Math.Clamp(drop.Color.b, 0f, 1f); bloodData.Count++; } if (bloodData.Valid()) { MessageRelay.RelayModule<BloodMessage, BloodData>(bloodData, new MessageRoute((RelayType)3, (NetworkChannel)1)); sent++; } } } if (Time.unscaledTime >= nextLog) { nextLog = Time.unscaledTime + 15f; ((MelonBase)this).LoggerInstance.Msg($"Blood sync: sent packets={sent}, received={receivedCount}, applied droplets={applied}, queued={outgoing.Count}, overflow={dropped}"); } } catch (System.Exception ex) { if (Time.unscaledTime >= nextError) { nextError = Time.unscaledTime + 5f; ((MelonBase)this).LoggerInstance.Warning(((object)ex).ToString()); } } } private void Clear() { outgoing.Clear(); lock (gate) { incoming.Clear(); } } public override void OnSceneWasUnloaded(int index, string name) { Clear(); } public override void OnDeinitializeMelon() { if (ready) { Mod.DropletEmitted -= Capture; } Clear(); } } }