Decompiled source of crimson v1.1.0
Mods/Crimson.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BoneLib; using BoneLib.BoneMenu; using Crimson; using Crimson.Core; using HarmonyLib; using Il2CppCysharp.Threading.Tasks; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Data; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Audio; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.PuppetMasta; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSLZ.VFX; using Il2CppSLZ.VRMK; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(CrimsonMod), "Crimson", "1.1.8", "Crimson Mod Project", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })] [assembly: InternalsVisibleTo("CrimsonFusion")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("Crimson")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.8.0")] [assembly: AssemblyInformationalVersion("1.1.8")] [assembly: AssemblyProduct("Crimson")] [assembly: AssemblyTitle("Crimson")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.8.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Crimson { public sealed class AudioEffects { private readonly AudioClip[] _drips = (AudioClip[])(object)new AudioClip[31]; private readonly AudioClip[] _cracks = (AudioClip[])(object)new AudioClip[8]; private readonly ShuffleBag _dripBag = new ShuffleBag(31, 7021); private readonly ShuffleBag _crackBag = new ShuffleBag(8, 1029); private readonly AudioSource[] _voices = (AudioSource[])(object)new AudioSource[12]; private GameObject? _root; private AudioClip? _ringClip; private AudioSource? _ring; private Audio3dManager? _manager; private float _trauma; private float _nextDrip; private float _lastBlast = -10f; private Vector3 _lastBlastPosition; private float _baselineCutoff = 22000f; private bool _writingCutoff; private bool _hasMuffled; internal int BlastCount { get; private set; } internal void Ensure() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //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) if (!Object.op_Implicit((Object)(object)_root)) { _root = new GameObject("Crimson audio"); Object.DontDestroyOnLoad((Object)(object)_root); for (int i = 0; i < 31; i++) { _drips[i] = Clip($"Crimson drip {i + 1:00}", SoundBank.Drip(i)); } for (int j = 0; j < 8; j++) { _cracks[j] = Clip($"Crimson crack {j + 1:00}", SoundBank.Crack(j)); } _ringClip = Clip("Crimson ringing", SoundBank.Ring()); for (int k = 0; k < _voices.Length; k++) { GameObject val = new GameObject($"Crimson voice {k}"); val.transform.SetParent(_root.transform, false); AudioSource val2 = val.AddComponent<AudioSource>(); val2.playOnAwake = false; val2.spatialBlend = 1f; val2.dopplerLevel = 0f; val2.rolloffMode = (AudioRolloffMode)0; val2.minDistance = 0.6f; val2.maxDistance = 12f; _voices[k] = val2; } _ring = _root.AddComponent<AudioSource>(); _ring.playOnAwake = false; _ring.spatialBlend = 0f; _ring.loop = true; _ring.clip = _ringClip; _ring.volume = 0f; _ring.priority = 100; } } private static AudioClip Clip(string name, float[] samples) { AudioClip obj = AudioClip.Create(name, samples.Length, 1, 24000, false); obj.SetData(Il2CppStructArray<float>.op_Implicit(samples), 0); Object.DontDestroyOnLoad((Object)(object)obj); return obj; } private void Play(AudioClip clip, Vector3 point, float volume) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) AudioSource[] voices = _voices; foreach (AudioSource val in voices) { if (Object.op_Implicit((Object)(object)val) && !val.isPlaying) { ((Component)val).transform.position = point; val.clip = clip; val.volume = volume; val.pitch = Random.Range(0.87f, 1.13f); val.outputAudioMixerGroup = Audio.SoftInteraction; val.Play(); break; } } } internal void Drip(Vector3 point) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (Settings.Sounds.Value && !(Time.unscaledTime < _nextDrip)) { Ensure(); _nextDrip = Time.unscaledTime + Random.Range(0.065f, 0.18f); Play(_drips[_dripBag.Next()], point, Settings.SoundVolume.Value * Random.Range(0.45f, 0.9f)); } } internal void Crack(Vector3 point) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (Settings.Sounds.Value) { Ensure(); Play(_cracks[_crackBag.Next()], point, Settings.SoundVolume.Value * Random.Range(0.7f, 1f)); } } internal void Explosion(Vector3 point, float radius) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!Settings.Enabled.Value || !Settings.Tinnitus.Value || !Object.op_Implicit((Object)(object)Player.Head)) { return; } float unscaledTime = Time.unscaledTime; if (unscaledTime - _lastBlast < 0.15f) { Vector3 val = point - _lastBlastPosition; if (((Vector3)(ref val)).sqrMagnitude < 1f) { return; } } _lastBlast = unscaledTime; _lastBlastPosition = point; float num = Mathf.Clamp(radius * 2f, 6f, 24f); float num2 = Mathf.Clamp01(1f - Vector3.Distance(Player.Head.position, point) / num); if (!(num2 <= 0f)) { Ensure(); _trauma = Mathf.Clamp01(_trauma + 0.25f + num2 * 0.65f); _manager = Object.FindObjectOfType<Audio3dManager>(); if (Object.op_Implicit((Object)(object)_ring)) { _ring.outputAudioMixerGroup = Audio.InHead; } if (Object.op_Implicit((Object)(object)_ring) && !_ring.isPlaying) { _ring.Play(); } BlastCount++; } } internal void ObserveCutoff(Audio3dManager manager, ref float cutoff) { if (!_writingCutoff) { _manager = manager; _baselineCutoff = cutoff; if (_trauma > 0f) { cutoff = Mathf.Min(cutoff, Mathf.Lerp(22000f, 900f, _trauma)); } } } internal void Update() { if (_trauma <= 0f) { return; } if (!Settings.Enabled.Value || !Settings.Tinnitus.Value) { ResetHearing(); return; } _trauma = Mathf.Max(0f, _trauma - Time.unscaledDeltaTime / 7f); if (Object.op_Implicit((Object)(object)_ring)) { _ring.volume = Settings.RingVolume.Value * _trauma * _trauma; } WriteCutoff(Mathf.Min(_baselineCutoff, Mathf.Lerp(22000f, 900f, _trauma))); if (_trauma <= 0.001f) { ResetHearing(); } } private void WriteCutoff(float value) { if (!Object.op_Implicit((Object)(object)_manager)) { return; } _writingCutoff = true; try { _manager.SetLowPassFilter(value); _hasMuffled = true; } finally { _writingCutoff = false; } } internal void ResetHearing() { _trauma = 0f; if (Object.op_Implicit((Object)(object)_ring)) { _ring.Stop(); } if (_hasMuffled) { WriteCutoff(_baselineCutoff); } _hasMuffled = false; } internal void Clear() { ResetHearing(); AudioSource[] voices = _voices; foreach (AudioSource val in voices) { if (Object.op_Implicit((Object)(object)val)) { val.Stop(); } } _manager = null; _baselineCutoff = 22000f; _lastBlast = -10f; } internal void Dispose() { Clear(); if (Object.op_Implicit((Object)(object)_root)) { Object.Destroy((Object)(object)_root); } AudioClip[] drips = _drips; foreach (AudioClip val in drips) { if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)val); } } drips = _cracks; foreach (AudioClip val2 in drips) { if (Object.op_Implicit((Object)(object)val2)) { Object.Destroy((Object)(object)val2); } } if (Object.op_Implicit((Object)(object)_ringClip)) { Object.Destroy((Object)(object)_ringClip); } } } internal static class BloodMaterial { internal static string ShaderName { get; private set; } = "not initialized"; internal static Material Create(Texture? texture = null, bool unlit = false) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_0247: 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) Shader val = null; string[] array = ((!unlit) ? new string[5] { "Universal Render Pipeline/Lit (PBR Workflow)", "Universal Render Pipeline/Lit", "Universal Render Pipeline/Particles/Unlit (Particles)", "Sprites/Default", "Unlit/Transparent" } : new string[4] { "Universal Render Pipeline/Particles/Unlit (Particles)", "Universal Render Pipeline/Particles/Unlit", "Sprites/Default", "Unlit/Transparent" }); for (int i = 0; i < array.Length; i++) { Shader val2 = Shader.Find(array[i]); if (Object.op_Implicit((Object)(object)val2) && val2.isSupported) { val = val2; break; } } if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("No supported transparent blood shader is loaded. Blood effects have been disabled; see README."); } ShaderName = ((Object)val).name; Material val3 = new Material(val) { name = "Crimson blood", renderQueue = 3001 }; val3.SetOverrideTag("RenderType", "Transparent"); Set(val3, "_Surface", 1f); Set(val3, "_Blend", 0f); Set(val3, "_Mode", 3f); Set(val3, "_SrcBlend", 5f); Set(val3, "_DstBlend", 10f); Set(val3, "_ZWrite", 0f); Set(val3, "_Cull", 0f); Set(val3, "_AlphaClip", 0f); Set(val3, "_Metallic", 0f); Set(val3, "_Smoothness", 0.54f); Set(val3, "_Glossiness", 0.54f); Set(val3, "_SmoothnessTextureChannel", 0f); Set(val3, "_ColorMode", 0f); Set(val3, "_OffsetFactor", -1f); Set(val3, "_OffsetUnits", -1f); Set(val3, "_SoftParticlesEnabled", 0f); Set(val3, "_CameraFadingEnabled", 0f); val3.EnableKeyword("_SURFACE_TYPE_TRANSPARENT"); val3.EnableKeyword("_ALPHABLEND_ON"); val3.DisableKeyword("_ALPHATEST_ON"); val3.DisableKeyword("_ALPHAPREMULTIPLY_ON"); val3.DisableKeyword("_ALPHAMODULATE_ON"); val3.DisableKeyword("_FADING_ON"); val3.SetShaderPassEnabled("ShadowCaster", false); if (val3.HasProperty("_BaseColor")) { val3.SetColor("_BaseColor", Color.white); } if (val3.HasProperty("_Color")) { val3.SetColor("_Color", Color.white); } if (Object.op_Implicit((Object)(object)texture)) { if (val3.HasProperty("_BaseMap")) { val3.SetTexture("_BaseMap", texture); } if (val3.HasProperty("_MainTex")) { val3.SetTexture("_MainTex", texture); } } return val3; } internal static Material SolidDroplet() { Material obj = Create(); ((Object)obj).name = "Crimson solid liquid"; obj.renderQueue = 2000; obj.SetOverrideTag("RenderType", "Opaque"); Set(obj, "_Surface", 0f); Set(obj, "_Mode", 0f); Set(obj, "_ZWrite", 1f); Set(obj, "_Cull", 2f); Set(obj, "_SrcBlend", 1f); Set(obj, "_DstBlend", 0f); Set(obj, "_OffsetFactor", 0f); Set(obj, "_OffsetUnits", 0f); Set(obj, "_Smoothness", 0.62f); Set(obj, "_Glossiness", 0.62f); obj.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); obj.DisableKeyword("_ALPHABLEND_ON"); return obj; } internal static void Set(Material mat, string property, float value) { if (mat.HasProperty(property)) { mat.SetFloat(property, value); } } internal static void Tint(Material mat, Color color) { //IL_0013: 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) if (mat.HasProperty("_BaseColor")) { mat.SetColor("_BaseColor", color); } if (mat.HasProperty("_Color")) { mat.SetColor("_Color", color); } } } public sealed class BloodSimulation { private struct Drop { internal Vector3 Position; internal Vector3 Velocity; internal float Size; internal float VisualSize; internal float Age; internal int Owner; internal BloodKind Kind; } private sealed class Pool { internal Collider Collider; internal Vector3 LocalPoint; internal Vector3 LocalNormal; internal float Volume; internal float Radius; internal float Touched; internal float Next; internal int Seed; internal BloodKind Kind; } private readonly List<Drop> _drops = new List<Drop>(360); private readonly List<Pool> _pools = new List<Pool>(64); private readonly Il2CppStructArray<RaycastHit> _hits = new Il2CppStructArray<RaycastHit>(24L); private readonly SurfaceBlood _surface; private readonly AudioEffects _audio; private GameObject? _go; private Mesh? _mesh; private readonly Material?[] _materials = (Material?[])(object)new Material[4]; private Il2CppStructArray<int>? _triangleBuffer; private readonly Vector3[] _vertices = (Vector3[])(object)new Vector3[360 * DropletShape.Vertices.Length]; private readonly Vector3[] _normals = (Vector3[])(object)new Vector3[360 * DropletShape.Vertices.Length]; private readonly int[] _indices = new int[360 * DropletShape.Indices.Length]; private readonly Vector3[] _dropVertices = new Vector3[DropletShape.Vertices.Length]; private readonly Vector3[] _dropNormals = new Vector3[DropletShape.Vertices.Length]; internal int DropCount => _drops.Count; internal int PoolCount => _pools.Count; internal BloodSimulation(SurfaceBlood surface, AudioEffects audio) { _surface = surface; _audio = audio; } internal void Spray(Vector3 point, Vector3 direction, Vector3 normal, float damage, int owner, int? seed = null, BloodKind kind = BloodKind.Red, float amountScale = 1f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) State state = Random.state; try { if (seed.HasValue) { Random.InitState(seed.Value); } SprayInternal(point, direction, normal, damage, owner, kind, amountScale); } finally { if (seed.HasValue) { Random.state = state; } } } private void SprayInternal(Vector3 point, Vector3 direction, Vector3 normal, float damage, int owner, BloodKind kind, float amountScale) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00c4: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (Settings.Blood.Value) { if (((Vector3)(ref direction)).sqrMagnitude < 0.001f) { direction = -normal; } ((Vector3)(ref direction)).Normalize(); int num = HitBleeding.SprayCount(damage, Settings.Amount.Value, amountScale); float num2 = Random.Range(0.14f, 0.38f); float num3 = Random.Range(0.9f, 1.15f); for (int i = 0; i < num; i++) { Vector3 val = ((i % 5 == 0) ? normal : direction); Vector3 val2 = val + Random.insideUnitSphere * num2; Vector3 velocity = ((Vector3)(ref val2)).normalized * Random.Range(1.6f, 7.2f) * num3; float size = Mathf.Lerp(0.004f, 0.023f, Random.value * Random.value); Add(point + val * 0.025f, velocity, size, owner, kind, 0.7f); } } } internal void Drip(Vector3 point, int owner, bool small = false, BloodKind kind = BloodKind.Red) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) //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) Add(point, Random.insideUnitSphere * 0.08f + Vector3.down * 0.1f, small ? 0.006f : Random.Range(0.009f, 0.016f), owner, kind); } internal void WoundSpray(Vector3 entry, Vector3? exit, Vector3 direction, Vector3 normal, float damage, int owner, int seed, BloodKind kind, Organ organ) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_004f: Unknown result type (might be due to invalid IL or missing references) float spray = HitBleeding.Profile(organ).Spray; Spray(entry, -direction, normal, damage, owner, seed, kind, spray); if (exit.HasValue) { Spray(exit.Value - direction * 0.003f, direction, direction, damage, owner, seed ^ 0x51A7, kind, spray); } } private void Add(Vector3 point, Vector3 velocity, float size, int owner, BloodKind kind, float visualScale = 1f) { //IL_0034: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (Settings.Blood.Value && _drops.Count < Settings.MaxDrops.Value) { _drops.Add(new Drop { Position = point, Velocity = velocity, Size = size, VisualSize = size * visualScale, Owner = owner, Kind = kind }); } } internal bool Trace(Vector3 from, Vector3 direction, float distance, int owner, out RaycastHit nearest) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) nearest = default(RaycastHit); float num = float.MaxValue; int num2 = Physics.RaycastNonAlloc(from, direction, _hits, distance, -5, (QueryTriggerInteraction)1); for (int i = 0; i < num2; i++) { RaycastHit val = ((Il2CppArrayBase<RaycastHit>)(object)_hits)[i]; Collider collider = ((RaycastHit)(ref val)).collider; if (Object.op_Implicit((Object)(object)collider) && !(((RaycastHit)(ref val)).distance >= num) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<RigManager>()) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<MuscleCollisionBroadcaster>()) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<PuppetMaster>())) { nearest = val; num = ((RaycastHit)(ref val)).distance; } } return num < float.MaxValue; } internal void Smear(Vector3 point, int owner, float remaining, ref RaycastHit previous, ref bool hasContact, BloodKind kind = BloodKind.Red) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) //IL_0016: 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_01bd: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_013c: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_019c: Unknown result type (might be due to invalid IL or missing references) if (!Trace(point + Vector3.up * 0.025f, Vector3.down, 0.16f, owner, out var nearest)) { hasContact = false; return; } if (hasContact && (Object)(object)((RaycastHit)(ref previous)).collider == (Object)(object)((RaycastHit)(ref nearest)).collider && Vector3.Dot(((RaycastHit)(ref nearest)).normal, ((RaycastHit)(ref previous)).normal) > 0.96f) { Vector3 along = ((RaycastHit)(ref nearest)).point - ((RaycastHit)(ref previous)).point; float magnitude = ((Vector3)(ref along)).magnitude; if (magnitude > 0.012f && magnitude < 0.6f) { float num = Mathf.Clamp01(Object.op_Implicit((Object)(object)((RaycastHit)(ref nearest)).collider.sharedMaterial) ? ((RaycastHit)(ref nearest)).collider.sharedMaterial.dynamicFriction : 0.6f); int num2 = Mathf.Clamp(Mathf.CeilToInt(magnitude / 0.025f), 1, 16); RaycastHit hit = default(RaycastHit); for (int i = 0; i <= num2; i++) { Vector3 val = Vector3.Lerp(((RaycastHit)(ref previous)).point, ((RaycastHit)(ref nearest)).point, (float)i / (float)num2); if (!(Mathf.PerlinNoise(val.x * 41f, val.z * 41f) < num * 0.35f) && ((RaycastHit)(ref nearest)).collider.Raycast(new Ray(val + ((RaycastHit)(ref nearest)).normal * 0.04f, -((RaycastHit)(ref nearest)).normal), ref hit, 0.08f)) { _surface.Paint(hit, Mathf.Lerp(0.012f, 0.045f, remaining) * (1f - 0.4f * num), 0.22f * remaining, along, 1.9f, owner, kind, BloodStampStyle.Smear); } } } } previous = nearest; hasContact = true; } internal void FixedUpdate() { //IL_0044: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00e1: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_0150: 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) float num = Mathf.Min(Time.fixedDeltaTime, 0.04f); for (int num2 = _drops.Count - 1; num2 >= 0; num2--) { Drop value = _drops[num2]; value.Age += num; ref Vector3 velocity = ref value.Velocity; velocity += Physics.gravity * num; ref Vector3 velocity2 = ref value.Velocity; velocity2 *= 1f - 0.15f * num; Vector3 val = value.Velocity * num; if (Trace(value.Position, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, value.Owner, out var nearest)) { _surface.Paint(nearest, value.Size * Random.Range(1.2f, 2.7f), 0.65f, Vector3.ProjectOnPlane(value.Velocity, ((RaycastHit)(ref nearest)).normal), StainShape.ImpactStretch(Vector3.Dot(((Vector3)(ref value.Velocity)).normalized, ((RaycastHit)(ref nearest)).normal)), Random.Range(0, 9000), value.Kind); if (Random.value < 0.35f) { _audio.Drip(((RaycastHit)(ref nearest)).point); } if (Settings.Pools.Value && Vector3.Dot(((RaycastHit)(ref nearest)).normal, Vector3.up) > 0.72f) { Accumulate(nearest, value.Size * 13f, value.Kind); } _drops.RemoveAt(num2); } else { ref Vector3 position = ref value.Position; position += val; if (value.Age > 3f || num2 >= Settings.MaxDrops.Value) { _drops.RemoveAt(num2); } else { _drops[num2] = value; } } } } private void Accumulate(RaycastHit hit, float amount, BloodKind kind) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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) Collider collider = ((RaycastHit)(ref hit)).collider; Vector3 localPoint = ((Component)collider).transform.InverseTransformPoint(((RaycastHit)(ref hit)).point); Pool pool = null; foreach (Pool pool2 in _pools) { if (pool2.Kind == kind && (Object)(object)pool2.Collider == (Object)(object)collider) { Vector3 val = ((Component)collider).transform.TransformPoint(pool2.LocalPoint) - ((RaycastHit)(ref hit)).point; if (((Vector3)(ref val)).sqrMagnitude < 0.025f) { pool = pool2; break; } } } if (pool == null) { if (_pools.Count >= 64) { _pools.RemoveAt(0); } pool = new Pool { Collider = collider, LocalPoint = localPoint, LocalNormal = ((Component)collider).transform.InverseTransformDirection(((RaycastHit)(ref hit)).normal), Seed = Random.Range(0, 9000), Kind = kind }; _pools.Add(pool); } pool.Volume = Mathf.Min(32f, pool.Volume + amount); pool.Touched = Time.time; } internal void Update() { //IL_00c2: 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_00cc: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00f1: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) RaycastHit hit = default(RaycastHit); for (int num = _pools.Count - 1; num >= 0; num--) { Pool pool = _pools[num]; if (!Object.op_Implicit((Object)(object)pool.Collider) || !((Component)pool.Collider).gameObject.activeInHierarchy || Time.time - pool.Touched > 12f || !Settings.Pools.Value) { _pools.RemoveAt(num); } else { pool.Radius = BloodField.Approach(pool.Radius, BloodField.PoolRadius(pool.Volume), 0.5f, Time.deltaTime); if (!(Time.time < pool.Next)) { pool.Next = Time.time + 0.3f; Vector3 val = ((Component)pool.Collider).transform.TransformDirection(pool.LocalNormal); Vector3 val2 = ((Component)pool.Collider).transform.TransformPoint(pool.LocalPoint); if (pool.Collider.Raycast(new Ray(val2 + val * 0.05f, -val), ref hit, 0.1f)) { _surface.Paint(hit, pool.Radius, 0.12f, Vector3.right, 1f, pool.Seed, pool.Kind, BloodStampStyle.Pool); } } } } DrawDrops(); } private void EnsureMesh() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_go)) { return; } _go = new GameObject("Crimson airborne blood"); _go.layer = 2; _mesh = new Mesh { name = "Crimson batched solid droplets" }; _mesh.MarkDynamic(); for (int i = 0; i < 4; i++) { _materials[i] = BloodMaterial.SolidDroplet(); BloodSample bloodSample = BloodAppearance.Sample(1f, 1f, 1f, BloodPalette.Color((BloodKind)i)); BloodMaterial.Tint(_materials[i], new Color(bloodSample.Red, bloodSample.Green, bloodSample.Blue)); } _go.AddComponent<MeshFilter>().sharedMesh = _mesh; MeshRenderer obj = _go.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterials = Il2CppReferenceArray<Material>.op_Implicit(_materials); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; for (int j = 0; j < 360; j++) { int num = j * DropletShape.Vertices.Length; int num2 = j * DropletShape.Indices.Length; for (int k = 0; k < DropletShape.Indices.Length; k++) { _indices[num2 + k] = num + DropletShape.Indices[k]; } } _triangleBuffer = Il2CppStructArray<int>.op_Implicit(_indices); _mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(_vertices); _mesh.subMeshCount = 4; } private void DrawDrops() { //IL_004b: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0147: 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_0179: Unknown result type (might be due to invalid IL or missing references) if (_drops.Count == 0) { if (Object.op_Implicit((Object)(object)_go)) { _go.SetActive(false); } return; } EnsureMesh(); _go.SetActive(true); Array.Fill(_vertices, _drops[0].Position); int num = 0; for (int i = 0; i < 4; i++) { int num2 = num; foreach (Drop drop in _drops) { if ((int)drop.Kind == i) { DropletShape.Transform(NetworkEffects.N(drop.Position), NetworkEffects.N(drop.Velocity), drop.VisualSize, _dropVertices, _dropNormals); int num3 = num++ * DropletShape.Vertices.Length; for (int j = 0; j < DropletShape.Vertices.Length; j++) { Vector3 vector = _dropVertices[j]; Vector3 vector2 = _dropNormals[j]; _vertices[num3 + j] = new Vector3 { x = vector.X, y = vector.Y, z = vector.Z }; _normals[num3 + j] = new Vector3 { x = vector2.X, y = vector2.Y, z = vector2.Z }; } } } _mesh.SetTriangles(_triangleBuffer, num2 * DropletShape.Indices.Length, (num - num2) * DropletShape.Indices.Length, i, false, 0); } _mesh.vertices = Il2CppStructArray<Vector3>.op_Implicit(_vertices); _mesh.normals = Il2CppStructArray<Vector3>.op_Implicit(_normals); _mesh.RecalculateBounds(); } internal void Clear() { _drops.Clear(); _pools.Clear(); if (Object.op_Implicit((Object)(object)_go)) { Object.Destroy((Object)(object)_go); } if (Object.op_Implicit((Object)(object)_mesh)) { Object.Destroy((Object)(object)_mesh); } for (int i = 0; i < _materials.Length; i++) { if (Object.op_Implicit((Object)(object)_materials[i])) { Object.Destroy((Object)(object)_materials[i]); } _materials[i] = null; } _go = null; _mesh = null; _triangleBuffer = null; } } public sealed class CrimsonMod : MelonMod { internal static CrimsonMod? Instance; public readonly SurfaceBlood Surfaces = new SurfaceBlood(); public readonly AudioEffects Audio = new AudioEffects(); public BloodSimulation Blood; public NpcInjuries Npcs; internal PlayerBleeding Players; private bool _ready; private bool _visualFault; private readonly HashSet<string> _errors = new HashSet<string>(); private readonly HashSet<(IntPtr Health, IntPtr Attack, int Muscle)> _seenHits = new HashSet<(IntPtr, IntPtr, int)>(); private int _hitFrame = -1; internal int HealthEvents; internal int ContactEvents; internal int BloodSurfaceEvents; internal bool Ready { get { if (_ready) { return !_visualFault; } return false; } } public override void OnInitializeMelon() { Instance = this; Blood = new BloodSimulation(Surfaces, Audio); Npcs = new NpcInjuries(Blood, Surfaces, Audio); Players = new PlayerBleeding(Blood); Settings.Initialize(); Hooking.OnLevelLoaded += LevelLoaded; Hooking.OnLevelLoading += LevelLoading; _ready = true; ((MelonBase)this).LoggerInstance.Msg("Crimson 1.1.8 initialized. NPC and player blood; stock Marrow blood suppression enabled by default."); string[] array = (from m in MelonTypeBase<MelonMod>.RegisteredMelons where (object)m != this && new string[4] { "Blood", "Injur", "Ragdoll", "NPCPhysics" }.Any((string s) => ((MelonBase)m).Info.Name.Contains(s, StringComparison.OrdinalIgnoreCase)) select ((MelonBase)m).Info.Name).ToArray(); if (array.Length != 0) { ((MelonBase)this).LoggerInstance.Warning("Overlapping effects/physics mods found: " + string.Join(", ", array) + ". Use Crimson feature toggles if effects conflict."); } } private void LevelLoading(LevelInfo info) { _ready = false; Clear(); } private void LevelLoaded(LevelInfo info) { _ready = true; _visualFault = false; } public override void OnUpdate() { if (!_ready) { return; } try { Audio.Update(); } catch (Exception error) { Report("audio update", error); Audio.ResetHearing(); } if (!Settings.Enabled.Value) { return; } try { Npcs.Update(); } catch (Exception error2) { Report("NPC injury update", error2); } try { Players.Update(); } catch (Exception error3) { Report("player blood update", error3); } try { VanillaBlood.Update(); } catch (Exception error4) { Report("stock blood removal", error4); } if (!Settings.Blood.Value || _visualFault) { return; } try { Blood.Update(); Surfaces.Update(); } catch (Exception error5) { _visualFault = true; Report("blood rendering (disabled until next level)", error5); ClearBlood(); } } public override void OnFixedUpdate() { if (!_ready || !Settings.Enabled.Value || !Settings.Blood.Value || _visualFault) { return; } try { Blood.FixedUpdate(); } catch (Exception error) { Report("droplet simulation", error); } } internal bool Hit(SubBehaviourHealth health, int index, Attack attack, bool hasBloodSurface = false, BloodKind? bloodKind = null) { if (!_ready || health == null || attack == null) { return false; } if (_hitFrame != Time.frameCount) { _seenHits.Clear(); _hitFrame = Time.frameCount; } (IntPtr, IntPtr, int) item = (((Il2CppObjectBase)health).Pointer, ((Il2CppObjectBase)attack).Pointer, index); if (_seenHits.Contains(item)) { return true; } try { if (!Npcs.Hit(health, index, attack, hasBloodSurface, remote: false, null, bloodKind)) { return false; } _seenHits.Add(item); return true; } catch (Exception error) { Report("damage hook", error); return false; } } internal bool Contact(MuscleCollisionBroadcaster broadcaster, Attack attack, bool hasBloodSurface = false, BloodKind? bloodKind = null) { ContactEvents++; if (!_ready || !Object.op_Implicit((Object)(object)broadcaster) || attack == null) { return false; } try { PuppetMaster puppetMaster = broadcaster.puppetMaster; if (!Object.op_Implicit((Object)(object)puppetMaster) || puppetMaster.behaviours == null) { return false; } foreach (BehaviourBase item in (Il2CppArrayBase<BehaviourBase>)(object)puppetMaster.behaviours) { BehaviourBaseNav val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<BehaviourBaseNav>() : null); if (((val != null) ? val.health : null) != null) { return Hit(val.health, broadcaster.muscleIndex, attack, hasBloodSurface, bloodKind); } } } catch (Exception error) { Report("NPC contact hook", error); } return false; } internal void BloodImpact(ImpactProperties impact, Attack attack) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: 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_016d: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: 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_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) if (!_ready || !Settings.Enabled.Value || !Settings.Blood.Value || attack == null || !VanillaBlood.IsBlood(impact)) { return; } BloodSurfaceEvents++; try { MuscleCollisionBroadcaster componentInParent = ((Component)impact).GetComponentInParent<MuscleCollisionBroadcaster>(); NpcBlood.TryImpact(impact, out var kind); if (Object.op_Implicit((Object)(object)componentInParent) && Contact(componentInParent, attack, hasBloodSurface: true, kind)) { return; } PlayerDamageReceiver componentInParent2 = ((Component)impact).GetComponentInParent<PlayerDamageReceiver>(); if (!Object.op_Implicit((Object)(object)componentInParent2) && Object.op_Implicit((Object)(object)attack.collider)) { componentInParent2 = ((Component)attack.collider).GetComponentInParent<PlayerDamageReceiver>(); } if (Object.op_Implicit((Object)(object)componentInParent2) && Players.Hit(componentInParent2, attack)) { return; } if (_hitFrame != Time.frameCount) { _seenHits.Clear(); _hitFrame = Time.frameCount; } if (!_seenHits.Add((((Il2CppObjectBase)impact).Pointer, ((Il2CppObjectBase)attack).Pointer, -1))) { return; } Vector3 val = attack.origin; if (!FaceFinite(val) || Vector3.Distance(val, ((Component)impact).transform.position) > 1f) { val = ((Component)impact).transform.position; } Vector3 val2; Vector3 val3; if (FaceFinite(attack.direction)) { val2 = attack.direction; if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { val2 = attack.direction; val3 = ((Vector3)(ref val2)).normalized; goto IL_016a; } } val3 = -((Component)impact).transform.forward; goto IL_016a; IL_01a7: Vector3 val4; Vector3 normal = (Vector3)val4; int num = Random.Shared.Next(); float damage = (float.IsFinite(attack.damage) ? Mathf.Max(1f, attack.damage) : 1f); Vector3 val5; Blood.Spray(val, val5, normal, damage, ((Object)impact).GetInstanceID(), num, kind); NetworkEffects.Splash(val, val5, normal, damage, num, kind); return; IL_016a: val5 = val3; if (FaceFinite(attack.normal)) { val2 = attack.normal; if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { val2 = attack.normal; val4 = ((Vector3)(ref val2)).normalized; goto IL_01a7; } } val4 = -val5; goto IL_01a7; } catch (Exception error) { Report("blood surface hook", error); } } private static bool FaceFinite(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; } internal void TestBlood() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) Transform head = Player.Head; if (!_ready || !Object.op_Implicit((Object)(object)head) || !Settings.Enabled.Value || !Settings.Blood.Value) { ((MelonBase)this).LoggerInstance.Msg("Test blood: enter a level and enable Crimson and Blood spray first."); return; } _visualFault = false; Blood.Spray(head.position + head.forward * 0.7f - head.up * 0.15f, Vector3.down, head.forward, 18f, 0); ((MelonBase)this).LoggerInstance.Msg("Test blood spawned in front of the headset. Use Print diagnostics after it lands."); } public void ClearBlood() { Blood.Clear(); Surfaces.Clear(); } public void Clear() { Npcs.Clear(); Players.Clear(); ClearBlood(); Audio.Clear(); VanillaBlood.Clear(); NetworkEffects.Clear(); _seenHits.Clear(); } internal void Diagnostics() { ((MelonBase)this).LoggerInstance.Msg($"ready={_ready}, enabled={Settings.Enabled.Value}, blood={Settings.Blood.Value}, playerBlood={Settings.PlayerBlood.Value}; healthEvents={HealthEvents}, contactEvents={ContactEvents}, bloodSurfaceEvents={BloodSurfaceEvents}, npcHits={Npcs.HitCount}, playerHits={Players.Hits}, fractures={Npcs.FractureCount}, blasts={Audio.BlastCount}; stockImpactsBlocked={VanillaBlood.ImpactsSuppressed}, stockWoundsBlocked={VanillaBlood.WoundsSuppressed}, stockDecalsBlocked={VanillaBlood.DecalsSuppressed}, stockPoolsBlocked={VanillaBlood.PooledEffectsSuppressed}; NPCs={Npcs.Count}, drops={Blood.DropCount}, pools={Blood.PoolCount}, tiles={Surfaces.Count}, queued={Surfaces.Queued}; shader={BloodMaterial.ShaderName}; visualFault={_visualFault}"); ((MelonBase)this).LoggerInstance.Msg("Fusion sharing=" + Settings.Fusion.Value + "; " + (NetworkEffects.Transport?.Status ?? "CrimsonFusion.dll not loaded")); ((MelonBase)this).LoggerInstance.Msg($"Wound zones: lastNpcOrgan={Npcs.LastOrgan}, lastPlayerOrgan={Players.LastOrgan}; npcExitHits={Npcs.ExitHits}, playerExitHits={Players.ExitHits}. Organ zones and exits are cosmetic approximations."); } internal static void Report(string context, Exception error) { if (Instance != null && Instance._errors.Add(context)) { ((MelonBase)Instance).LoggerInstance.Error(context + ": " + error); } } public override void OnDeinitializeMelon() { _ready = false; Hooking.OnLevelLoaded -= LevelLoaded; Hooking.OnLevelLoading -= LevelLoading; Clear(); Audio.Dispose(); Instance = null; } } public static class CrimsonApi { public static void NotifyExplosion(Vector3 position, float blastRadius = 8f) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) if (!float.IsFinite(position.x + position.y + position.z + blastRadius) || blastRadius <= 0f) { return; } try { NetworkEffects.LocalBlast(position, blastRadius); } catch (Exception error) { CrimsonMod.Report("explosion hook", error); } } } [HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")] internal static class DamagePatch { [HarmonyPriority(800)] private static void Prefix(SubBehaviourHealth __instance, int m, Attack attack) { if (CrimsonMod.Instance != null) { CrimsonMod.Instance.HealthEvents++; CrimsonMod.Instance.Hit(__instance, m, attack); } } } [HarmonyPatch(typeof(MuscleCollisionBroadcaster), "ReceiveAttack")] internal static class NpcContactPatch { [HarmonyPriority(800)] private static void Prefix(MuscleCollisionBroadcaster __instance, Attack attack) { CrimsonMod.Instance?.Contact(__instance, attack); } } [HarmonyPatch(typeof(PuppetMaster), "OnPoolSpawn")] internal static class RespawnPatch { private static void Prefix(PuppetMaster __instance) { CrimsonMod.Instance?.Npcs.Reset(__instance); } } [HarmonyPatch(typeof(PuppetMaster), "OnDisable")] internal static class DespawnPatch { private static void Prefix(PuppetMaster __instance) { CrimsonMod.Instance?.Npcs.Reset(__instance); } } [HarmonyPatch(typeof(BehaviourBaseNav), "Resurrect")] internal static class ResurrectPatch { private static void Prefix(BehaviourBaseNav __instance) { if (Object.op_Implicit((Object)(object)((BehaviourBase)__instance).puppetMaster)) { CrimsonMod.Instance?.Npcs.Reset(((BehaviourBase)__instance).puppetMaster); } } } [HarmonyPatch(typeof(Muscle), "MusclePdDrive")] internal static class JointDrivePatch { private static void Prefix(Muscle __instance, ref float muscleWeightMaster) { CrimsonMod? instance = CrimsonMod.Instance; if (instance != null && instance.Npcs.BrokenMuscles.Contains(((Il2CppObjectBase)__instance).Pointer) && Settings.Enabled.Value && Settings.Breaks.Value) { muscleWeightMaster = FractureRules.Drive(muscleWeightMaster); } } } [HarmonyPatch(typeof(SimpleExplosionForce), "OnEnable")] internal static class ExplosionPatch { private static void Postfix(SimpleExplosionForce __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) CrimsonApi.NotifyExplosion(((Component)__instance).transform.position, Mathf.Abs(__instance.radius)); } } [HarmonyPatch(typeof(Arena_Bomb), "ExplodeBomb")] internal static class ArenaExplosionPatch { private static void Prefix(Arena_Bomb __instance) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) CrimsonApi.NotifyExplosion(((Component)__instance).transform.position); } } [HarmonyPatch(typeof(Audio3dManager), "SetLowPassFilter")] internal static class MufflePatch { private static void Prefix(Audio3dManager __instance, ref float lpf) { CrimsonMod.Instance?.Audio.ObserveCutoff(__instance, ref lpf); } } internal static class HitAnatomy { internal static Organ Npc(PuppetMaster puppet, Muscle muscle, Vector3 entry, Vector3 end) { //IL_000e: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected I4, but got Unknown //IL_0095: 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) Group val = muscle.props.group; Animator animator; switch ((int)val) { case 2: return Organ.Brain; case 3: case 5: case 7: return Organ.SoftTissue; case 4: case 6: return Organ.Extremity; default: return Organ.Unknown; case 0: case 1: animator = puppet.targetAnimator; if (!Object.op_Implicit((Object)(object)animator) || !animator.isHuman) { return Organ.Unknown; } return Torso(Live((HumanBodyBones)0), Live((HumanBodyBones)10), Live((HumanBodyBones)13), Live((HumanBodyBones)14), entry, end); } Transform? Live(HumanBodyBones bone) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Transform boneTransform = animator.GetBoneTransform(bone); if (!Object.op_Implicit((Object)(object)boneTransform)) { return null; } foreach (Muscle item in (Il2CppArrayBase<Muscle>)(object)puppet.muscles) { if (item != null && (Object)(object)item.target == (Object)(object)boneTransform && Object.op_Implicit((Object)(object)item.transform)) { return item.transform; } } return boneTransform; } } internal static Organ Player(RigManager rig, HumanBodyBones bone, Vector3 entry, Vector3 end) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 if ((int)bone == 10) { return Organ.Brain; } if ((int)bone == 9) { return Organ.Neck; } if ((int)bone == 17 || (int)bone == 18 || (int)bone == 5 || (int)bone == 6 || (int)bone == 19 || (int)bone == 20) { return Organ.Extremity; } if ((int)bone != 0 && (int)bone != 7 && (int)bone != 8 && (int)bone != 54) { return Organ.SoftTissue; } return Torso(PlayerBleeding.Bone(rig, (HumanBodyBones)0), PlayerBleeding.Bone(rig, (HumanBodyBones)10), PlayerBleeding.Bone(rig, (HumanBodyBones)13), PlayerBleeding.Bone(rig, (HumanBodyBones)14), entry, end); } private static Organ Torso(Transform? hips, Transform? head, Transform? left, Transform? right, Vector3 entry, Vector3 end) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)hips) || !Object.op_Implicit((Object)(object)head) || !Object.op_Implicit((Object)(object)left) || !Object.op_Implicit((Object)(object)right)) { return Organ.Unknown; } Vector3 hips2 = NetworkEffects.N(hips.position); if (!HitBleeding.TryFrame(hips2, NetworkEffects.N(head.position), NetworkEffects.N(right.position - left.position), out var up, out var right2, out var forward, out var height)) { return Organ.Unknown; } return HitBleeding.AlongPath(HitBleeding.BodyPoint(NetworkEffects.N(entry), hips2, up, right2, forward, height), HitBleeding.BodyPoint(NetworkEffects.N(end), hips2, up, right2, forward, height)); } internal static bool Exit(Collider? collider, Vector3 entry, Vector3 direction, out Vector3 exit) { //IL_0001: 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_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) exit = default(Vector3); if (!Object.op_Implicit((Object)(object)collider) || collider.isTrigger || !collider.enabled || !((Component)collider).gameObject.activeInHierarchy) { return false; } Vector3 val = collider.ClosestPoint(entry) - entry; if (((Vector3)(ref val)).sqrMagnitude > 0.0009f) { return false; } direction = ((Vector3)(ref direction)).normalized; Bounds bounds = collider.bounds; val = ((Bounds)(ref bounds)).size; float num = Mathf.Clamp(((Vector3)(ref val)).magnitude + 0.1f, 0.1f, 6f); RaycastHit val2 = default(RaycastHit); if (!collider.Raycast(new Ray(entry + direction * num, -direction), ref val2, num)) { return false; } if (!HitBleeding.ValidExit(NetworkEffects.N(entry), NetworkEffects.N(((RaycastHit)(ref val2)).point), NetworkEffects.N(direction), NetworkEffects.N(((RaycastHit)(ref val2)).normal), num)) { return false; } exit = ((RaycastHit)(ref val2)).point; return true; } internal static Vector3? NpcExit(Muscle muscle, Vector3 entry, Vector3 direction) { //IL_0026: 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_0031: Unknown result type (might be due to invalid IL or missing references) if (muscle.colliders == null) { return null; } foreach (Collider item in (Il2CppArrayBase<Collider>)(object)muscle.colliders) { if (Exit(item, entry, direction, out var exit)) { return exit; } } return null; } internal static Vector3? PlayerExit(RigManager rig, HumanBodyBones bone, Vector3 entry, Vector3 direction) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) foreach (PlayerDamageReceiver componentsInChild in ((Component)rig).GetComponentsInChildren<PlayerDamageReceiver>()) { if (!Object.op_Implicit((Object)(object)componentsInChild) || PlayerBleeding.BodyBone(componentsInChild.bodyPart) != bone) { continue; } foreach (Collider componentsInChild2 in ((Component)componentsInChild).GetComponentsInChildren<Collider>()) { if (Exit(componentsInChild2, entry, direction, out var exit)) { return exit; } } } return null; } } internal interface ICrimsonNetwork { bool Active { get; } string Status { get; } bool CanControl(PuppetMaster puppet); void Send(EffectPacket packet, PuppetMaster? puppet); void SendPlayer(EffectPacket packet, RigManager rig); } internal static class NetworkEffects { internal static ICrimsonNetwork? Transport; private static readonly Queue<(EffectKind Kind, Vector3 Point, float At)> RecentWorld = new Queue<(EffectKind, Vector3, float)>(); internal static bool Active { get { if (Settings.Fusion != null && Settings.Fusion.Value) { return Transport?.Active ?? false; } return false; } } private static bool FirstWorld(EffectKind kind, Vector3 point) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) while (RecentWorld.Count > 0 && Time.unscaledTime - RecentWorld.Peek().At > 0.6f) { RecentWorld.Dequeue(); } if (RecentWorld.Any(delegate((EffectKind Kind, Vector3 Point, float At) e) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (e.Kind == kind) { Vector3 val = e.Point - point; return ((Vector3)(ref val)).sqrMagnitude < 0.0004f; } return false; })) { return false; } if (RecentWorld.Count >= 128) { RecentWorld.Dequeue(); } RecentWorld.Enqueue((kind, point, Time.unscaledTime)); return true; } internal static void Clear() { RecentWorld.Clear(); } internal static bool CanControl(PuppetMaster puppet) { if (Transport == null) { return true; } try { return Transport.CanControl(puppet); } catch (Exception error) { CrimsonMod.Report("Fusion authority", error); return false; } } internal static void Send(EffectPacket packet, PuppetMaster? puppet = null) { if (!Active) { return; } try { Transport.Send(packet, puppet); } catch (Exception error) { CrimsonMod.Report("Fusion send", error); } } internal static void Hit(PuppetMaster puppet, int muscle, Vector3 point, Vector3 direction, Vector3 normal, float damage, int attackType, int seed, BloodKind kind, Organ organ, Vector3? exit) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) Send(new EffectPacket { Kind = EffectKind.Hit, Muscle = (ushort)muscle, Flags = 1, Blood = kind, Organ = organ, HasExit = exit.HasValue, ExitPoint = (exit.HasValue ? N(exit.Value) : default(Vector3)), Point = N(point), Direction = N(direction), Normal = N(normal), Amount = Mathf.Clamp(damage, 0f, 500f), AttackType = attackType, Seed = seed }, puppet); } internal static void Splash(Vector3 point, Vector3 direction, Vector3 normal, float damage, int seed, BloodKind kind) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) FirstWorld(EffectKind.Splash, point); Send(new EffectPacket { Kind = EffectKind.Splash, Blood = kind, Point = N(point), Direction = N(direction), Normal = N(normal), Amount = Mathf.Clamp(damage, 0f, 500f), Seed = seed }); } internal static void Crack(PuppetMaster puppet, Vector3 point) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Send(new EffectPacket { Kind = EffectKind.Crack, Point = N(point) }, puppet); } internal static void Blast(Vector3 point, float radius) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Send(new EffectPacket { Kind = EffectKind.Blast, Point = N(point), Amount = Mathf.Clamp(radius, 0.1f, 100f) }); } internal static void LocalBlast(Vector3 point, float radius) { //IL_0001: 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_0021: Unknown result type (might be due to invalid IL or missing references) if (FirstWorld(EffectKind.Blast, point)) { CrimsonMod.Instance?.Audio.Explosion(point, radius); Blast(point, radius); } } internal static void PlayerHit(RigManager rig, HumanBodyBones bone, Vector3 point, Vector3 direction, Vector3 normal, float damage, int seed, int attackType, Organ organ, Vector3? exit) { //IL_0020: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } try { Transport.SendPlayer(new EffectPacket { Kind = EffectKind.PlayerHit, Muscle = (ushort)bone, Point = N(point), AttackType = attackType, Organ = organ, HasExit = exit.HasValue, ExitPoint = (exit.HasValue ? N(exit.Value) : default(Vector3)), Direction = N(direction), Normal = N(normal), Amount = Mathf.Clamp(damage, 0f, 500f), Seed = seed }, rig); } catch (Exception error) { CrimsonMod.Report("Fusion player blood", error); } } internal static void Apply(EffectPacket packet, PuppetMaster? puppet) { //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_021b: 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) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027e: 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_0236: 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_00ca: 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_00dc: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0114: 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) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) CrimsonMod instance = CrimsonMod.Instance; if (instance == null || !instance.Ready || !Settings.Enabled.Value) { return; } switch (packet.Kind) { case EffectKind.Hit: { if (!Object.op_Implicit((Object)(object)puppet) || puppet.muscles == null || packet.Muscle >= ((Il2CppArrayBase<Muscle>)(object)puppet.muscles).Length) { break; } Muscle val = ((Il2CppArrayBase<Muscle>)(object)puppet.muscles)[(int)packet.Muscle]; if (val == null || !Object.op_Implicit((Object)(object)val.transform) || puppet.behaviours == null) { break; } { foreach (BehaviourBase item in (Il2CppArrayBase<BehaviourBase>)(object)puppet.behaviours) { BehaviourBaseNav val2 = ((item != null) ? ((Il2CppObjectBase)item).TryCast<BehaviourBaseNav>() : null); if (((val2 != null) ? val2.health : null) != null) { Attack attack = new Attack { origin = val.transform.TransformPoint(U(packet.Point)), direction = val.transform.TransformDirection(U(packet.Direction)), normal = val.transform.TransformDirection(U(packet.Normal)), damage = packet.Amount, attackType = (AttackType)packet.AttackType }; instance.Npcs.Hit(val2.health, packet.Muscle, attack, hasBloodSurface: true, remote: true, packet.Seed, packet.Blood, packet.Organ, packet.HasExit ? new Vector3?(val.transform.TransformPoint(U(packet.ExitPoint))) : ((Vector3?)null)); break; } } break; } } case EffectKind.Splash: if (FirstWorld(EffectKind.Splash, U(packet.Point))) { if (packet.Organ != Organ.Unknown || packet.HasExit) { instance.Blood.WoundSpray(U(packet.Point), packet.HasExit ? new Vector3?(U(packet.ExitPoint)) : ((Vector3?)null), U(packet.Direction), U(packet.Normal), packet.Amount, 0, packet.Seed, packet.Blood, packet.Organ); } else { instance.Blood.Spray(U(packet.Point), U(packet.Direction), U(packet.Normal), packet.Amount, 0, packet.Seed, packet.Blood); } } break; case EffectKind.Crack: if (Settings.Breaks.Value) { instance.Audio.Crack(U(packet.Point)); } break; case EffectKind.Blast: if (FirstWorld(EffectKind.Blast, U(packet.Point))) { instance.Audio.Explosion(U(packet.Point), packet.Amount); } break; } } internal static Vector3 N(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new Vector3(v.x, v.y, v.z); } internal static Vector3 U(Vector3 v) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(v.X, v.Y, v.Z); } } internal static class NpcBlood { private static readonly Dictionary<int, (PuppetMaster Puppet, bool Known, BloodKind Kind)> Cache = new Dictionary<int, (PuppetMaster, bool, BloodKind)>(); internal static bool TryImpact(ImpactProperties impact, out BloodKind kind) { kind = BloodKind.Red; if (!Object.op_Implicit((Object)(object)impact)) { return false; } SurfaceData val = (Object.op_Implicit((Object)(object)impact.surfaceData) ? impact.surfaceData : impact._cachedSurfaceData); DataCardReference<SurfaceDataCard> surfaceDataCard = impact.SurfaceDataCard; object barcode; if (surfaceDataCard == null) { barcode = null; } else { Barcode barcode2 = ((ScannableReference)surfaceDataCard).Barcode; barcode = ((barcode2 != null) ? barcode2.ID : null); } return BloodPalette.TrySurface((string?)barcode, Object.op_Implicit((Object)(object)val) ? ((Object)val).name : null, out kind); } internal static bool Resolve(PuppetMaster puppet, Muscle muscle, Collider collider, out BloodKind kind) { if (Object.op_Implicit((Object)(object)collider) && ((Component)collider).transform.IsChildOf(((Component)puppet).transform) && TryImpact(((Component)collider).GetComponentInParent<ImpactProperties>(), out kind)) { return true; } if (muscle.colliders != null) { foreach (Collider item in (Il2CppArrayBase<Collider>)(object)muscle.colliders) { if (Object.op_Implicit((Object)(object)item) && TryImpact(((Component)item).GetComponentInParent<ImpactProperties>(), out kind)) { return true; } } } int instanceID = ((Object)puppet).GetInstanceID(); if (Cache.TryGetValue(instanceID, out (PuppetMaster, bool, BloodKind) value) && (Object)(object)value.Item1 == (Object)(object)puppet) { kind = value.Item3; return value.Item2; } bool flag = false; kind = BloodKind.Red; foreach (ImpactProperties componentsInChild in ((Component)puppet).GetComponentsInChildren<ImpactProperties>(true)) { if (TryImpact(componentsInChild, out var kind2)) { flag = true; kind = kind2; if (kind2 != BloodKind.Red) { break; } } } if (Cache.Count >= 128) { Cache.Clear(); } if (flag) { Cache[instanceID] = (puppet, true, kind); } return flag; } internal static void Reset(PuppetMaster puppet) { if (Object.op_Implicit((Object)(object)puppet)) { Cache.Remove(((Object)puppet).GetInstanceID()); } } internal static void Clear() { Cache.Clear(); } } public sealed class NpcInjuries { private sealed class Wound { internal Transform Anchor; internal Vector3 LocalPoint; internal float Started; internal float Expires; internal float NextDrip; internal float NextSmear; internal bool HasContact; internal RaycastHit Previous; internal BloodKind Kind; internal Organ Organ; internal Vector3 ExitPoint; internal bool HasExit; internal bool ExitContact; internal RaycastHit ExitPrevious; } private sealed class Fracture { internal Muscle Muscle; } private sealed class Actor { internal PuppetMaster Puppet; internal readonly List<Wound> Wounds = new List<Wound>(4); internal readonly Dictionary<int, float> Damage = new Dictionary<int, float>(); internal readonly Dictionary<int, Fracture> Fractures = new Dictionary<int, Fracture>(); internal float Touched; internal int LastFrame = -1; internal readonly Dictionary<int, Vector3> Contacts = new Dictionary<int, Vector3>(); } private readonly Dictionary<int, Actor> _actors = new Dictionary<int, Actor>(); private readonly List<int> _remove = new List<int>(); private readonly BloodSimulation _blood; private readonly SurfaceBlood _surface; private readonly AudioEffects _audio; internal readonly HashSet<IntPtr> BrokenMuscles = new HashSet<IntPtr>(); internal int Count => _actors.Count; internal int HitCount { get; private set; } internal int FractureCount { get; private set; } internal int ExitHits { get; private set; } internal Organ LastOrgan { get; private set; } internal NpcInjuries(BloodSimulation blood, SurfaceBlood surface, AudioEffects audio) { _blood = blood; _surface = surface; _audio = audio; } internal bool Hit(SubBehaviourHealth health, int index, Attack attack, bool hasBloodSurface = false, bool remote = false, int? seed = null, BloodKind? bloodKind = null, Organ? organ = null, Vector3? exitPoint = null) { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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) //IL_019c: 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_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0254: 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_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: 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_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: 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_02ce: 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_02fa: 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_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Invalid comparison between Unknown and I4 //IL_0302: 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_030b: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Invalid comparison between Unknown and I4 //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Invalid comparison between Unknown and I4 //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_037a: 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_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Expected I4, but got Unknown //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Invalid comparison between Unknown and I4 //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Invalid comparison between Unknown and I4 //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Invalid comparison between Unknown and I4 //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Invalid comparison between Unknown and I4 //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Invalid comparison between Unknown and I4 //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Invalid comparison between Unknown and I4 //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Invalid comparison between Unknown and I4 //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Invalid comparison between Unknown and I4 //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Invalid comparison between Unknown and I4 //IL_04eb: Unknown result type (might be due to invalid IL or missing references) if (!Settings.Enabled.Value || attack == null || !float.IsFinite(attack.damage) || attack.damage <= 0.1f) { return false; } BehaviourBase behaviour = ((SubBehaviourBase)health).behaviour; if (!Object.op_Implicit((Object)(object)behaviour) || !Object.op_Implicit((Object)(object)behaviour.puppetMaster)) { return false; } PuppetMaster puppetMaster = behaviour.puppetMaster; if (!remote && NetworkEffects.Active && !NetworkEffects.CanControl(puppetMaster)) { return true; } if (!((Component)puppetMaster).gameObject.activeInHierarchy || !puppetMaster.initiated || puppetMaster.muscles == null || index < 0 || index >= ((Il2CppArrayBase<Muscle>)(object)puppetMaster.muscles).Length) { return false; } Muscle val = ((Il2CppArrayBase<Muscle>)(object)puppetMaster.muscles)[index]; if (val == null || !Object.op_Implicit((Object)(object)val.transform) || val.props == null) { return false; } BloodKind kind; bool flag = NpcBlood.Resolve(puppetMaster, val, attack.collider, out kind); BloodKind kind2 = bloodKind ?? kind; if (!health.isOrganic && !hasBloodSurface && !flag) { return false; } int instanceID = ((Object)puppetMaster).GetInstanceID(); if (!_actors.TryGetValue(instanceID, out Actor value)) { if (_actors.Count >= Settings.MaxNpcs.Value) { Remove(_actors.MinBy<KeyValuePair<int, Actor>, float>((KeyValuePair<int, Actor> pair) => pair.Value.Touched).Key, restore: true); } value = new Actor { Puppet = puppetMaster }; _actors.Add(instanceID, value); } value.Touched = Time.time; Vector3 val2 = attack.origin; if (!Finite(val2) || Vector3.Distance(val2, val.transform.position) > 1f) { val2 = val.transform.position; } if (Object.op_Implicit((Object)(object)attack.collider) && ((Component)attack.collider).transform.IsChildOf(((Component)puppetMaster).transform)) { val2 = attack.collider.ClosestPoint(val2); } Vector3 val3; if (!remote) { if (value.LastFrame != Time.frameCount) { value.Contacts.Clear(); value.LastFrame = Time.frameCount; } if (value.Contacts.TryGetValue(index, out var value2)) { val3 = val2 - value2; if (((Vector3)(ref val3)).sqrMagnitude < 4E-06f) { return true; } } value.Contacts[index] = val2; } HitCount++; int seed2 = seed ?? Random.Shared.Next(); Vector3 val4; if (Finite(attack.direction)) { val3 = attack.direction; if (((Vector3)(ref val3)).sqrMagnitude > 0.001f) { val3 = attack.direction; val4 = ((Vector3)(ref val3)).normalized; goto IL_02d3; } } val4 = -val.transform.forward; goto IL_02d3; IL_0492: FractureImpact fractureImpact = FractureImpact.Other; goto IL_0495; IL_0310: Vector3 val5; Vector3 normal = (Vector3)val5; bool flag2 = (int)attack.attackType != 8 && (int)attack.attackType != 64; Vector3 val7; Vector3? val6 = (remote ? exitPoint : (((int)attack.attackType == 1) ? HitAnatomy.NpcExit(val, val2, val7) : ((Vector3?)null))); Organ organ2 = organ ?? HitAnatomy.Npc(puppetMaster, val, val2, (Vector3)(((??)val6) ?? val2)); LastOrgan = organ2; if (val6.HasValue && flag2) { ExitHits++; } if (flag2 && Settings.Blood.Value) { _blood.WoundSpray(val2, val6, val7, normal, attack.damage, instanceID, seed2, kind2, organ2); AddWound(value, val.transform, val2, kind2, organ2, val6); } if (!remote && NetworkEffects.CanControl(puppetMaster) && Settings.Breaks.Value && ((int)val.props.group == 3 || (int)val.props.group == 5 || (int)val.props.group == 4 || (int)val.props.group == 6)) { AttackType attackType = attack.attackType; if ((int)attackType <= 2) { if ((int)attackType != 1) { if ((int)attackType != 2) { goto IL_0492; } fractureImpact = FractureImpact.Blunt; } else { fractureImpact = FractureImpact.Piercing; } } else if ((int)attackType != 16) { if ((int)attackType != 32) { goto IL_0492; } fractureImpact = FractureImpact.Stabbing; } else { fractureImpact = FractureImpact.Slicing; } goto IL_0495; } goto IL_04f2; IL_0495: FractureImpact impact = fractureImpact; value.Damage.TryGetValue(index, out var value3); value3 = FractureRules.Accumulate(value3, attack.damage, impact); value.Damage[index] = value3; if (value3 >= Settings.BreakThreshold.Value && !value.Fractures.ContainsKey(index)) { Break(value, val, index, val2); } goto IL_04f2; IL_02d3: val7 = val4; if (Finite(attack.normal)) { val3 = attack.normal; if (((Vector3)(ref val3)).sqrMagnitude > 0.001f) { val3 = attack.normal; val5 = ((Vector3)(ref val3)).normalized; goto IL_0310; } } val5 = -val7; goto IL_0310; IL_04f2: if (!remote && flag2) { NetworkEffects.Hit(puppetMaster, index, val2, val7, normal, attack.damage, (int)attack.attackType, seed2, kind2, organ2, val6); } return true; } 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 static void AddWound(Actor actor, Transform anchor, Vector3 point, BloodKind kind, Organ organ, Vector3? exit) { //IL_00a1: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) Wound wound = actor.Wounds.Find((Wound w) => (Object)(object)w.Anchor == (Object)(object)anchor); if (wound == null) { if (actor.Wounds.Count >= 4) { actor.Wounds.RemoveAt(0); } wound = new Wound { Anchor = anchor }; actor.Wounds.Add(wound); } if (!(wound.Expires > Time.time) || !(HitBleeding.Profile(wound.Organ).Flow > HitBleeding.Profile(organ).Flow)) { wound.Organ = organ; wound.LocalPoint = anchor.InverseTransformPoint(point); wound.Started = Time.time; wound.Kind = kind; wound.Expires = Time.time + HitBleeding.Duration(wound.Organ, Settings.BleedSeconds.Value); wound.NextDrip = Time.time + HitBleeding.Interval(wound.Organ, Random.Range(0.05f, 0.2f), 1f); wound.HasExit = exit.HasValue; if (exit.HasValue) { wound.ExitPoint = anchor.InverseTransformPoint(exit.Value); } wound.HasContact = (wound.ExitContact = false); } } private void Break(Actor actor, Muscle muscle, int index, Vector3 point) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Fracture value = new Fracture { Muscle = muscle }; actor.Fractures.Add(index, value); BrokenMuscles.Add(((Il2CppObjectBase)muscle).Pointer); FractureCount++; _audio.Crack(point); NetworkEffects.Crack(actor.Puppet, point); } internal void Update() { //IL_0151: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0295: 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) _remove.Clear(); foreach (KeyValuePair<int, Actor> actor in _actors) { Actor value = actor.Value; if (!Object.op_Implicit((Object)(object)value.Puppet) || !((Component)value.Puppet).gameObject.activeInHierarchy || value.Puppet.hasBeenDespawned) { _remove.Add(actor.Key); continue; } if (!Settings.Breaks.Value || !NetworkEffects.CanControl(value.Puppet)) { foreach (Fracture value2 in value.Fractures.Values) { BrokenMuscles.Remove(((Il2CppObjectBase)value2.Muscle).Pointer); } value.Fractures.Clear(); value.Damage.Clear(); } for (int num = value.Wounds.Count - 1; num >= 0; num--) { Wound wound = value.Wounds[num]; if (!Object.op_Implicit((Object)(object)wound.Anchor) || Time.time >= wound.Expires || !Settings.Blood.Value) { value.Wounds.RemoveAt(num); } else { Vector3 point = wound.Anchor.TransformPoint(wound.LocalPoint); float remaining = Mathf.Clamp01((wound.Expires - Time.time) / (wound.Expires - wound.Started)); if (Time.time >= wound.NextDrip) { _blood.Drip(point, actor.Key, wound.Organ == Organ.Extremity, wound.Kind); if (wound.HasExit) { _blood.Drip(wound.Anchor.TransformPoint(wound.ExitPoint), actor.Key, wound.Organ == Organ.Extremity, wound.Kind); } wound.NextDrip = Time.time + HitBleeding.Interval(wound.Organ, Random.Range(0.2f, 0.65f), remaining); } if (Settings.Smears.Value && Time.time >= wound.NextSmear) { wound.NextSmear = Time.time + 0.065f; _blood.Smear(point, actor.Key, remaining, ref wound.Previous, ref wound.HasContact, wound.Kind); if (wound.HasExit) { _blood.Smear(wound.Anchor.TransformPoint(wound.ExitPoint), actor.Key, remaining, ref wound.ExitPrevious, ref wound.ExitContact, wound.Kind); } } else if (!Settings.Smears.Value) { wound.HasContact = (wound.ExitContact = false); } } } if (value.Wounds.Count == 0 && value.Fractures.Count == 0 && Time.time - value.Touched > 45f) { _remove.Add(actor.Key); } } foreach (int item in _remove) { Remove(item, restore: true); } } internal void Reset(PuppetMaster puppet) { NpcBlood.Reset(puppet); if (Object.op_Implicit((Object)(object)puppet)) { Remove(((Object)puppet).GetInstanceID(), restore: true); } } internal void RestoreFractures() { foreach (Actor value in _actors.Values) { value.Fractures.Clear(); value.Damage.Clear(); } BrokenMuscles.Clear(); } private void Remove(int id, bool restore) { if (!_actors.Remove(id, out Actor value)) { return; } foreach (Fracture value2 in value.Fractures.Values) { BrokenMuscles.Remove(((Il2CppObjectBase)value2.Muscle).Pointer); } } internal void Clear() { int[] array = _actors.Keys.ToArray(); foreach (int id in array) { Remove(id, restore: true); } BrokenMuscles.Clear(); NpcBlo
Mods/CrimsonFusion.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using Crimson; using Crimson.Core; using CrimsonFusion; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.PuppetMasta; using LabFusion.Entities; using LabFusion.Marrow.Extenders; 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(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(FusionBridge), "Crimson Fusion", "1.1.8", "Crimson Mod Project", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonAdditionalDependencies(new string[] { "Crimson", "LabFusion" })] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("CrimsonFusion")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.8.0")] [assembly: AssemblyInformationalVersion("1.1.8")] [assembly: AssemblyProduct("CrimsonFusion")] [assembly: AssemblyTitle("CrimsonFusion")] [assembly: AssemblyVersion("1.1.8.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace CrimsonFusion { public sealed class FusionBridge : MelonMod, ICrimsonNetwork { internal static FusionBridge? Instance; private readonly Queue<(byte Sender, EffectPacket Packet)> _incoming = new Queue<(byte, EffectPacket)>(); private readonly Dictionary<byte, PeerWindow> _peers = new Dictionary<byte, PeerWindow>(); private readonly object _gate = new object(); private bool _running; private ulong _epoch; private ulong _level; private uint _sequence; private float _nextHello; private float _tokenAt; private float _tokens = 90f; private int _sent; private int _received; private int _applied; private int _rejected; private int _overflow; bool ICrimsonNetwork.Active => _running; string ICrimsonNetwork.Status => $"{(_running ? "connected" : "waiting for Fusion/level")}; sent={_sent}, received={_received}, applied={_applied}, rejected={_rejected}, overflow={_overflow}"; public override void OnInitializeMelon() { Instance = this; ModuleMessageManager.RegisterHandler<CrimsonEffectMessage>(); NetworkEffects.Transport = (ICrimsonNetwork)(object)this; ((MelonBase)this).LoggerInstance.Msg("Crimson Fusion 1.1.8: NPC/player blood sharing enabled. Each participant needs both Crimson DLLs."); } public override void OnUpdate() { //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) int num; object obj; if (NetworkInfo.HasServer) { CrimsonMod instance = CrimsonMod.Instance; if (instance != null && instance.Ready && Settings.Enabled.Value) { num = (Settings.Fusion.Value ? 1 : 0); if (num == 0) { goto IL_0036; } obj = NetworkSceneManager.GetLevelBarcode(PlayerIDManager.LocalID); goto IL_0047; } } num = 0; goto IL_0036; IL_0036: obj = ""; goto IL_0047; IL_0047: string text = (string)obj; if (num == 0 || string.IsNullOrEmpty(text)) { StopSession(); return; } ulong num2 = EffectPacket.LevelHash(text); if (!_running || _level != num2) { StopSession(); _running = true; _level = num2; _epoch = BitConverter.ToUInt64(RandomNumberGenerator.GetBytes(8)); if (_epoch == 0L) { _epoch = 1uL; } _nextHello = 0f; _sequence = 0u; _tokens = 90f; _tokenAt = Time.unscaledTime; } if (Time.unscaledTime >= _nextHello) { SendPacket(new EffectPacket { Kind = (EffectKind)0, Entity = ushort.MaxValue }); _nextHello = Time.unscaledTime + 2f; } for (int i = 0; i < 32; i++) { (byte, EffectPacket) tuple; lock (_gate) { if (_incoming.Count == 0) { break; } tuple = _incoming.Dequeue(); } try { Receive(tuple.Item1, tuple.Item2); } catch (Exception ex) { _rejected++; CrimsonMod.Report("Fusion receive", ex); } } } private void StopSession() { if (!_running) { lock (_gate) { _incoming.Clear(); return; } } _running = false; _peers.Clear(); lock (_gate) { _incoming.Clear(); } CrimsonMod instance = CrimsonMod.Instance; if (instance != null) { instance.Npcs.RestoreFractures(); } } public override void OnDeinitializeMelon() { StopSession(); if ((object)NetworkEffects.Transport == this) { NetworkEffects.Transport = null; } Instance = null; } internal void Queue(byte sender, EffectPacket packet) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) lock (_gate) { if (_incoming.Count >= 256) { _overflow++; } else { _incoming.Enqueue((sender, packet)); } } } bool ICrimsonNetwork.CanControl(PuppetMaster puppet) { NetworkEntity val = default(NetworkEntity); if (!NetworkInfo.HasServer || !PuppetMasterExtender.Cache.TryGet(puppet, ref val)) { return true; } if (!val.IsOwner) { if (!val.HasOwner) { return NetworkInfo.IsHost; } return false; } return true; } void ICrimsonNetwork.Send(EffectPacket packet, PuppetMaster? puppet) { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Invalid comparison between Unknown and I4 //IL_0127: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00ca: Unknown result type (might be due to invalid IL or missing references) if (!_running) { return; } packet.Entity = ushort.MaxValue; NetworkEntity val = default(NetworkEntity); if (Object.op_Implicit((Object)(object)puppet) && PuppetMasterExtender.Cache.TryGet(puppet, ref val)) { if (!val.IsOwner && (val.HasOwner || !NetworkInfo.IsHost)) { return; } packet.Entity = val.ID; if ((int)packet.Kind == 1) { if (puppet.muscles == null || packet.Muscle >= ((Il2CppArrayBase<Muscle>)(object)puppet.muscles).Length) { return; } Transform transform = ((Il2CppArrayBase<Muscle>)(object)puppet.muscles)[(int)packet.Muscle].transform; packet.Point = NetworkEffects.N(transform.InverseTransformPoint(NetworkEffects.U(packet.Point))); if (((EffectPacket)(ref packet)).HasExit) { packet.ExitPoint = NetworkEffects.N(transform.InverseTransformPoint(NetworkEffects.U(packet.ExitPoint))); } packet.Direction = NetworkEffects.N(transform.InverseTransformDirection(NetworkEffects.U(packet.Direction))); packet.Normal = NetworkEffects.N(transform.InverseTransformDirection(NetworkEffects.U(packet.Normal))); } } else if ((int)packet.Kind == 1) { packet.Kind = (EffectKind)2; } SendPacket(packet); } void ICrimsonNetwork.SendPlayer(EffectPacket packet, RigManager rig) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) NetworkPlayer val = default(NetworkPlayer); if (!_running || !NetworkPlayerManager.TryGetPlayer(rig, ref val)) { return; } Transform val2 = PlayerBleeding.Bone(rig, (HumanBodyBones)packet.Muscle); if (Object.op_Implicit((Object)(object)val2)) { packet.Entity = val.PlayerID.SmallID; packet.Point = NetworkEffects.N(val2.InverseTransformPoint(NetworkEffects.U(packet.Point))); if (((EffectPacket)(ref packet)).HasExit) { packet.ExitPoint = NetworkEffects.N(val2.InverseTransformPoint(NetworkEffects.U(packet.ExitPoint))); } packet.Direction = NetworkEffects.N(val2.InverseTransformDirection(NetworkEffects.U(packet.Direction))); packet.Normal = NetworkEffects.N(val2.InverseTransformDirection(NetworkEffects.U(packet.Normal))); SendPacket(packet); } } private void SendPacket(EffectPacket packet) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; _tokens = Math.Min(90f, _tokens + Math.Max(0f, unscaledTime - _tokenAt) * 60f); _tokenAt = unscaledTime; if ((int)packet.Kind != 0) { if (_tokens < 1f) { _overflow++; return; } _tokens -= 1f; } packet.Epoch = _epoch; packet.Level = _level; packet.Sequence = ++_sequence; if (!((EffectPacket)(ref packet)).Valid()) { _rejected++; return; } MessageRelay.RelayModule<CrimsonEffectMessage, EffectData>(new EffectData { Bytes = ((EffectPacket)(ref packet)).Encode() }, CommonMessageRoutes.ReliableToOtherClients); _sent++; } private void Receive(byte sender, EffectPacket p) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00be: 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_00c5: Invalid comparison between Unknown and I4 //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: 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_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_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0190: 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_01b7: 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) _received++; if (sender == PlayerIDManager.LocalSmallID || p.Level != _level) { _rejected++; return; } PlayerID playerID = PlayerIDManager.GetPlayerID(sender); if (playerID == null || !NetworkSceneManager.InCurrentLevel(playerID)) { _rejected++; return; } if (!_peers.TryGetValue(sender, out PeerWindow value)) { if (_peers.Count >= 254) { _rejected++; return; } value = new PeerWindow(); _peers.Add(sender, value); } if (!value.Accept(p, Time.unscaledTimeAsDouble)) { _rejected++; } else { if ((int)p.Kind == 0) { return; } if ((int)p.Kind == 5) { NetworkPlayer val = default(NetworkPlayer); if (!NetworkPlayerManager.TryGetPlayer((byte)p.Entity, ref val) || !val.HasRig || !NetworkSceneManager.InCurrentLevel(val.PlayerID)) { _rejected++; return; } RigManager rigManager = val.RigRefs.RigManager; Transform val2 = PlayerBleeding.Bone(rigManager, (HumanBodyBones)p.Muscle); if (!Object.op_Implicit((Object)(object)val2)) { _rejected++; return; } CrimsonMod.Instance.Players.Apply(rigManager, (HumanBodyBones)p.Muscle, val2.TransformPoint(NetworkEffects.U(p.Point)), val2.TransformDirection(NetworkEffects.U(p.Direction)), val2.TransformDirection(NetworkEffects.U(p.Normal)), p.Amount, true, p.Seed, (int)sender, (AttackType)p.AttackType, (Organ?)((EffectPacket)(ref p)).Organ, ((EffectPacket)(ref p)).HasExit ? new Vector3?(val2.TransformPoint(NetworkEffects.U(p.ExitPoint))) : ((Vector3?)null)); _applied++; return; } PuppetMaster val3 = null; if (p.Entity != ushort.MaxValue) { NetworkEntityReference val4 = new NetworkEntityReference(p.Entity); NetworkEntity val5 = default(NetworkEntity); if (!((NetworkEntityReference)(ref val4)).TryGetEntity(ref val5) || val5.IsDestroyed) { _rejected++; return; } if ((val5.HasOwner ? val5.OwnerID.SmallID : 0) != sender) { _rejected++; return; } val3 = ((EntityComponentExtender<PuppetMaster>)(object)val5.GetExtender<PuppetMasterExtender>())?.Component; if (!Object.op_Implicit((Object)(object)val3)) { _rejected++; return; } } NetworkEffects.Apply(p, val3); _applied++; } } } public sealed class EffectData : INetSerializable { public byte[] Bytes = new byte[92]; public int? GetSize() { return 92; } public void Serialize(INetSerializer serializer) { for (int i = 0; i < 92; i++) { serializer.SerializeValue(ref Bytes[i]); } } } public sealed class CrimsonEffectMessage : ModuleMessageHandler { protected override bool OnPreRelayMessage(ReceivedMessage received) { EffectPacket val = default(EffectPacket); return EffectPacket.TryDecode((ReadOnlySpan<byte>)((ReceivedMessage)(ref received)).Bytes, ref val); } protected override void OnHandleMessage(ReceivedMessage received) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) EffectPacket packet = default(EffectPacket); if (((ReceivedMessage)(ref received)).Sender.HasValue && EffectPacket.TryDecode((ReadOnlySpan<byte>)((ReceivedMessage)(ref received)).Bytes, ref packet)) { FusionBridge.Instance?.Queue(((ReceivedMessage)(ref received)).Sender.Value, packet); } } } }