using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BloodLab.Blood;
using BloodLab.Configuration;
using BloodLab.Core;
using BloodLab.Droplet;
using BloodLab.Effects;
using BloodLab.Stain;
using BloodLab.Utilities;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.PuppetMasta;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(BloodLabMod), "BloodLab", "0.1.0", "leonfwfw", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BloodLab")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BloodLab")]
[assembly: AssemblyTitle("BloodLab")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BloodLab.Utilities
{
public static class SurfaceUtils
{
public static Quaternion AlignToNormal(Vector3 normal)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_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_0040: 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_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: 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)
if (((Vector3)(ref normal)).sqrMagnitude < 0.0001f)
{
normal = Vector3.up;
}
((Vector3)(ref normal)).Normalize();
Vector3 val = ((Mathf.Abs(Vector3.Dot(normal, Vector3.up)) > 0.95f) ? Vector3.forward : Vector3.up);
Quaternion val2 = Quaternion.LookRotation(-normal, val);
float num = Random.Range(0f, 360f);
return val2 * Quaternion.Euler(0f, 0f, num);
}
public static Vector3 SafeOffset(Vector3 point, Vector3 normal, float distance = 0.01f)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: 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_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
return point + ((Vector3)(ref normal)).normalized * distance;
}
}
}
namespace BloodLab.Stain
{
[RegisterTypeInIl2Cpp]
public class BloodStain : MonoBehaviour
{
private static Mesh _sharedQuadMesh;
private static Shader _cachedShader;
private static bool _shaderResolved;
private MeshRenderer _renderer;
private MaterialPropertyBlock _propertyBlock;
private float _timer;
private float _lifetime;
private float _currentSize;
public Vector3 WorldPosition => ((Component)this).transform.position;
public BloodStain(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Expected O, but got Unknown
EnsureSharedMesh();
MeshFilter val = ((Component)this).GetComponent<MeshFilter>();
if ((Object)(object)val == (Object)null)
{
val = ((Component)this).gameObject.AddComponent<MeshFilter>();
}
val.sharedMesh = _sharedQuadMesh;
_renderer = ((Component)this).GetComponent<MeshRenderer>();
if ((Object)(object)_renderer == (Object)null)
{
_renderer = ((Component)this).gameObject.AddComponent<MeshRenderer>();
}
((Renderer)_renderer).shadowCastingMode = (ShadowCastingMode)0;
((Renderer)_renderer).receiveShadows = false;
Shader val2 = ResolveWorkingShader();
if ((Object)(object)val2 != (Object)null)
{
((Renderer)_renderer).sharedMaterial = new Material(val2)
{
hideFlags = (HideFlags)61
};
}
_propertyBlock = new MaterialPropertyBlock();
}
public void PlaceOnGround(Vector3 worldPosition, Vector3 groundNormal, Texture2D texture, float startSize)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
((Component)this).transform.SetParent((Transform)null, false);
((Component)this).transform.position = SurfaceUtils.SafeOffset(worldPosition, groundNormal, 0.006f);
((Component)this).transform.rotation = SurfaceUtils.AlignToNormal(groundNormal);
_currentSize = startSize;
((Component)this).transform.localScale = new Vector3(_currentSize, _currentSize, 1f);
if ((Object)(object)texture != (Object)null && (Object)(object)_renderer != (Object)null && (Object)(object)((Renderer)_renderer).sharedMaterial != (Object)null)
{
_propertyBlock.Clear();
((Renderer)_renderer).GetPropertyBlock(_propertyBlock);
_propertyBlock.SetTexture("_MainTex", (Texture)(object)texture);
((Renderer)_renderer).SetPropertyBlock(_propertyBlock);
}
_timer = 0f;
_lifetime = BloodLabPreferences.SplatLifetime.Value * 3f;
}
public void Grow(float amount, float maxSize)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
_currentSize = Mathf.Min(_currentSize + amount, maxSize);
((Component)this).transform.localScale = new Vector3(_currentSize, _currentSize, 1f);
_timer = 0f;
}
private void Update()
{
if ((Object)(object)this == (Object)null)
{
return;
}
try
{
_timer += Time.deltaTime;
if (_timer >= _lifetime)
{
BloodEffectManager.ReleaseStain(this);
}
}
catch
{
}
}
private static Shader ResolveWorkingShader()
{
if (_shaderResolved)
{
return _cachedShader;
}
_shaderResolved = true;
string[] array = new string[4] { "Sprites/Default", "Unlit/Transparent", "Unlit/Texture", "UI/Default" };
string[] array2 = array;
foreach (string text in array2)
{
Shader val = Shader.Find(text);
if ((Object)(object)val != (Object)null)
{
_cachedShader = val;
return _cachedShader;
}
}
Renderer val2 = Object.FindObjectOfType<Renderer>();
if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sharedMaterial != (Object)null && (Object)(object)val2.sharedMaterial.shader != (Object)null)
{
_cachedShader = val2.sharedMaterial.shader;
return _cachedShader;
}
_shaderResolved = false;
return null;
}
private static void EnsureSharedMesh()
{
//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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_0050: 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_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: 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_00e8: 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_00fe: 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)
if (!((Object)(object)_sharedQuadMesh != (Object)null))
{
_sharedQuadMesh = new Mesh
{
name = "BloodLab_StainQuadMesh",
hideFlags = (HideFlags)61
};
_sharedQuadMesh.vertices = Il2CppStructArray<Vector3>.op_Implicit((Vector3[])(object)new Vector3[4]
{
new Vector3(-0.5f, -0.5f, 0f),
new Vector3(0.5f, -0.5f, 0f),
new Vector3(0.5f, 0.5f, 0f),
new Vector3(-0.5f, 0.5f, 0f)
});
_sharedQuadMesh.uv = Il2CppStructArray<Vector2>.op_Implicit((Vector2[])(object)new Vector2[4]
{
new Vector2(0f, 0f),
new Vector2(1f, 0f),
new Vector2(1f, 1f),
new Vector2(0f, 1f)
});
_sharedQuadMesh.triangles = Il2CppStructArray<int>.op_Implicit(new int[6] { 0, 2, 1, 0, 3, 2 });
_sharedQuadMesh.RecalculateNormals();
_sharedQuadMesh.RecalculateBounds();
}
}
}
}
namespace BloodLab.Effects
{
public enum ImpactSource
{
Projectile,
Melee
}
public struct ImpactData
{
public Vector3 Position;
public Vector3 Normal;
public Vector3 Direction;
public Collider HitCollider;
public GameObject HitObject;
public bool IsLivingEntity;
public float Intensity;
public ImpactSource Source;
}
public static class ImpactHooks
{
[HarmonyPatch(typeof(Projectile), "Awake")]
public static class ProjectileAwakePatch
{
public static void Postfix(Projectile __instance)
{
try
{
if ((Object)(object)__instance == (Object)null || __instance.onCollision == null)
{
return;
}
((UnityEvent<Collider, Vector3, Vector3>)(object)__instance.onCollision).AddListener(UnityAction<Collider, Vector3, Vector3>.op_Implicit((Action<Collider, Vector3, Vector3>)delegate(Collider hitCollider, Vector3 worldPoint, Vector3 normal)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: 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_0054: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!((Object)(object)hitCollider == (Object)null))
{
Vector3 direction = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).transform.forward : (-normal));
ImpactData data = new ImpactData
{
Position = worldPoint,
Normal = normal,
Direction = direction,
HitCollider = hitCollider,
HitObject = ((Component)hitCollider).gameObject,
IsLivingEntity = IsLivingTarget(hitCollider),
Intensity = 1f,
Source = ImpactSource.Projectile
};
BloodEffectManager.HandleImpact(data);
}
}
catch (Exception ex2)
{
MelonLogger.Error("[BloodLab] cant process projectile impact: " + ex2);
}
}));
}
catch (Exception ex)
{
MelonLogger.Error("[BloodLab] couldnt install hook on Projectile.Awake: " + ex);
}
}
}
[HarmonyPatch(typeof(SubBehaviourHealth), "TakeDamage")]
public static class TakeDamagePatch
{
public static void Postfix(SubBehaviourHealth __instance, int m, Attack attack)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: 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_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: 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)
try
{
Collider collider = attack.collider;
if (!((Object)(object)collider == (Object)null))
{
ResolveMeleeHitPoint(attack.origin, collider, out var point, out var normal);
Vector3 val = point - attack.origin;
Vector3 val2;
if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f))
{
val2 = -normal;
}
else
{
val = point - attack.origin;
val2 = ((Vector3)(ref val)).normalized;
}
Vector3 direction = val2;
ImpactData data = new ImpactData
{
Position = point,
Normal = normal,
Direction = direction,
HitCollider = collider,
HitObject = ((Component)collider).gameObject,
IsLivingEntity = true,
Intensity = Mathf.Clamp01((float)m / 25f),
Source = ImpactSource.Melee
};
BloodEffectManager.HandleImpact(data);
}
}
catch (Exception ex)
{
MelonLogger.Error("[BloodLab] melee damage failed to process lol: " + ex);
}
}
}
private static void ResolveMeleeHitPoint(Vector3 origin, Collider col, out Vector3 point, out Vector3 normal)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: 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_0010: 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_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: 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_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)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_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_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
Bounds bounds = col.bounds;
Vector3 center = ((Bounds)(ref bounds)).center;
Vector3 val = center - origin;
RaycastHit val2 = default(RaycastHit);
if (((Vector3)(ref val)).sqrMagnitude > 0.0001f && Physics.Raycast(origin, ((Vector3)(ref val)).normalized, ref val2, ((Vector3)(ref val)).magnitude + 1f) && (Object)(object)((RaycastHit)(ref val2)).collider == (Object)(object)col)
{
point = ((RaycastHit)(ref val2)).point;
normal = ((RaycastHit)(ref val2)).normal;
return;
}
point = col.ClosestPoint(origin);
Vector3 val3 = point - origin;
Vector3 val4;
if (!(((Vector3)(ref val3)).sqrMagnitude > 0.0001f))
{
val4 = ((Component)col).transform.up;
}
else
{
val3 = point - origin;
val4 = ((Vector3)(ref val3)).normalized;
}
normal = val4;
}
private static bool IsLivingTarget(Collider hitCollider)
{
AIBrain componentInParent = ((Component)hitCollider).GetComponentInParent<AIBrain>();
return (Object)(object)componentInParent != (Object)null && !componentInParent.isDead;
}
}
}
namespace BloodLab.Droplet
{
[RegisterTypeInIl2Cpp]
public class BloodDroplet : MonoBehaviour
{
private static Mesh _sharedQuadMesh;
private static Shader _cachedShader;
private static bool _shaderResolved;
private Rigidbody _rb;
private SphereCollider _collider;
private MeshRenderer _renderer;
private MaterialPropertyBlock _propertyBlock;
private float _timer;
private float _lifetime;
private bool _hasLanded;
public BloodDroplet(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Expected O, but got Unknown
EnsureSharedMesh();
MeshFilter val = ((Component)this).GetComponent<MeshFilter>();
if ((Object)(object)val == (Object)null)
{
val = ((Component)this).gameObject.AddComponent<MeshFilter>();
}
val.sharedMesh = _sharedQuadMesh;
_renderer = ((Component)this).GetComponent<MeshRenderer>();
if ((Object)(object)_renderer == (Object)null)
{
_renderer = ((Component)this).gameObject.AddComponent<MeshRenderer>();
}
((Renderer)_renderer).shadowCastingMode = (ShadowCastingMode)0;
((Renderer)_renderer).receiveShadows = false;
Shader val2 = ResolveWorkingShader();
if ((Object)(object)val2 != (Object)null)
{
((Renderer)_renderer).sharedMaterial = new Material(val2)
{
hideFlags = (HideFlags)61
};
}
_propertyBlock = new MaterialPropertyBlock();
_collider = ((Component)this).GetComponent<SphereCollider>();
if ((Object)(object)_collider == (Object)null)
{
_collider = ((Component)this).gameObject.AddComponent<SphereCollider>();
}
_collider.radius = 0.03f;
((Collider)_collider).isTrigger = false;
_rb = ((Component)this).GetComponent<Rigidbody>();
if ((Object)(object)_rb == (Object)null)
{
_rb = ((Component)this).gameObject.AddComponent<Rigidbody>();
}
_rb.useGravity = true;
_rb.mass = 0.001f;
_rb.drag = 0.3f;
_rb.collisionDetectionMode = (CollisionDetectionMode)3;
}
public void SetTexture(Texture2D texture)
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)texture == (Object)null) && !((Object)(object)_renderer == (Object)null) && !((Object)(object)((Renderer)_renderer).sharedMaterial == (Object)null))
{
_propertyBlock.Clear();
((Renderer)_renderer).GetPropertyBlock(_propertyBlock);
_propertyBlock.SetTexture("_MainTex", (Texture)(object)texture);
_propertyBlock.SetColor("_Color", Color.white);
((Renderer)_renderer).SetPropertyBlock(_propertyBlock);
}
}
public void Launch(Vector3 position, Vector3 direction, float speed, Transform ignoreRoot)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: 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_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: 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_0140: 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)
((Component)this).transform.SetParent((Transform)null, true);
((Component)this).transform.position = position + Vector3.up * 0.03f;
if ((Object)(object)Camera.main != (Object)null)
{
Vector3 val = ((Component)Camera.main).transform.position - ((Component)this).transform.position;
Vector3 normalized = ((Vector3)(ref val)).normalized;
((Component)this).transform.rotation = Quaternion.LookRotation(normalized);
}
float value = BloodLabPreferences.DropletVisualScale.Value;
((Component)this).transform.localScale = Vector3.one * value;
((Collider)_collider).enabled = true;
Il2CppReferenceArray<Collider> val2 = Physics.OverlapSphere(((Component)this).transform.position, 0.18f);
foreach (Collider item in (Il2CppArrayBase<Collider>)(object)val2)
{
if (!((Object)(object)item == (Object)null))
{
Rigidbody attachedRigidbody = item.attachedRigidbody;
if ((Object)(object)attachedRigidbody != (Object)null && !attachedRigidbody.isKinematic)
{
Physics.IgnoreCollision((Collider)(object)_collider, item, true);
}
}
}
_rb.velocity = ((Vector3)(ref direction)).normalized * speed;
_timer = 0f;
_hasLanded = false;
_lifetime = BloodLabPreferences.DropletLifetime.Value;
}
private void Update()
{
if (!((Object)(object)this == (Object)null) && !_hasLanded)
{
_timer += Time.deltaTime;
if (_timer >= _lifetime)
{
BloodEffectManager.ReleaseDroplet(this);
}
}
}
private void OnCollisionEnter(Collision collision)
{
//IL_0074: 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_007d: 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_0082: 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_009a: 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_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: 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)
if ((Object)(object)this == (Object)null || _hasLanded || collision == null)
{
return;
}
Collider collider = collision.collider;
if ((Object)(object)collider == (Object)null)
{
return;
}
if (IsCharacterCollider(collider))
{
Physics.IgnoreCollision((Collider)(object)_collider, collider, true);
return;
}
_hasLanded = true;
Vector3 val;
ContactPoint contact;
if (collision.contactCount <= 0)
{
val = ((Component)this).transform.position;
}
else
{
contact = collision.GetContact(0);
val = ((ContactPoint)(ref contact)).point;
}
Vector3 groundPosition = val;
Vector3 val2;
if (collision.contactCount <= 0)
{
val2 = Vector3.up;
}
else
{
contact = collision.GetContact(0);
val2 = ((ContactPoint)(ref contact)).normal;
}
Vector3 groundNormal = val2;
BloodEffectManager.HandleDropletLanded(groundPosition, groundNormal);
BloodEffectManager.ReleaseDroplet(this);
}
private static bool IsCharacterCollider(Collider col)
{
if ((Object)(object)((Component)col).GetComponentInParent<AIBrain>() != (Object)null)
{
return true;
}
int num = LayerMask.NameToLayer("EnemyColliders");
if (num >= 0 && ((Component)col).gameObject.layer == num)
{
return true;
}
Rigidbody attachedRigidbody = col.attachedRigidbody;
if ((Object)(object)attachedRigidbody != (Object)null && !attachedRigidbody.isKinematic)
{
return true;
}
return false;
}
private static Shader ResolveWorkingShader()
{
if (_shaderResolved)
{
return _cachedShader;
}
_shaderResolved = true;
string[] array = new string[4] { "Sprites/Default", "Unlit/Transparent", "Unlit/Texture", "UI/Default" };
string[] array2 = array;
foreach (string text in array2)
{
Shader val = Shader.Find(text);
if ((Object)(object)val != (Object)null)
{
_cachedShader = val;
return _cachedShader;
}
}
Renderer val2 = Object.FindObjectOfType<Renderer>();
if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sharedMaterial != (Object)null && (Object)(object)val2.sharedMaterial.shader != (Object)null)
{
_cachedShader = val2.sharedMaterial.shader;
return _cachedShader;
}
_shaderResolved = false;
return null;
}
private static void EnsureSharedMesh()
{
//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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_0050: 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_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: 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_00e8: 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_00fe: 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)
if (!((Object)(object)_sharedQuadMesh != (Object)null))
{
_sharedQuadMesh = new Mesh
{
name = "BloodLab_DropletQuadMesh",
hideFlags = (HideFlags)61
};
_sharedQuadMesh.vertices = Il2CppStructArray<Vector3>.op_Implicit((Vector3[])(object)new Vector3[4]
{
new Vector3(-0.5f, -0.5f, 0f),
new Vector3(0.5f, -0.5f, 0f),
new Vector3(0.5f, 0.5f, 0f),
new Vector3(-0.5f, 0.5f, 0f)
});
_sharedQuadMesh.uv = Il2CppStructArray<Vector2>.op_Implicit((Vector2[])(object)new Vector2[4]
{
new Vector2(0f, 0f),
new Vector2(1f, 0f),
new Vector2(1f, 1f),
new Vector2(0f, 1f)
});
_sharedQuadMesh.triangles = Il2CppStructArray<int>.op_Implicit(new int[6] { 0, 2, 1, 0, 3, 2 });
_sharedQuadMesh.RecalculateNormals();
_sharedQuadMesh.RecalculateBounds();
}
}
}
public static class DropletManager
{
public static void HandleBleed(Vector3 woundWorldPosition, Vector3 woundNormal, float intensity, Transform woundRoot)
{
//IL_004f: 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_005e: 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_006d: 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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: 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)
if (BloodLabPreferences.EnableDripping.Value)
{
int value = BloodLabPreferences.DropletsPerHit.Value;
int num = Mathf.Clamp(Mathf.RoundToInt((float)value * Mathf.Clamp(intensity, 0.5f, 2f)), 1, 40);
for (int i = 0; i < num; i++)
{
BloodDroplet dropletFromPool = BloodEffectManager.GetDropletFromPool();
Vector3 val = Vector3.down * 1.2f + Random.insideUnitSphere * 0.8f;
Vector3 normalized = ((Vector3)(ref val)).normalized;
float speed = Random.Range(0.6f, 2.2f);
dropletFromPool.Launch(woundWorldPosition, normalized, speed, woundRoot);
}
MelonLogger.Msg($"[BloodLab] {num} droplets launched from wound");
}
}
}
}
namespace BloodLab.Core
{
public class BloodLabMod : MelonMod
{
private Harmony _harmony;
public override void OnInitializeMelon()
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
try
{
if (!ClassInjector.IsTypeRegisteredInIl2Cpp<BloodDecal>())
{
ClassInjector.RegisterTypeInIl2Cpp<BloodDecal>();
}
if (!ClassInjector.IsTypeRegisteredInIl2Cpp<BloodStain>())
{
ClassInjector.RegisterTypeInIl2Cpp<BloodStain>();
}
if (!ClassInjector.IsTypeRegisteredInIl2Cpp<BloodDroplet>())
{
ClassInjector.RegisterTypeInIl2Cpp<BloodDroplet>();
}
MelonLogger.Msg("[BloodLab] classes registered");
BloodLabPreferences.Initialize();
BloodTextureLibrary.Initialize();
BloodEffectManager.Initialize();
BloodLabBoneMenu.Setup();
_harmony = new Harmony("com.bloodlab.mod");
_harmony.PatchAll();
MelonLogger.Msg("[BloodLab] initialized");
}
catch (Exception ex)
{
MelonLogger.Error("[BloodLab] critical error when yo shi was installing " + ex);
}
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
try
{
BloodTextureLibrary.Reload();
}
catch (Exception ex)
{
MelonLogger.Error("[BloodLab] cant reload texture " + ex);
}
}
}
}
namespace BloodLab.Configuration
{
public static class BloodLabBoneMenu
{
public static void Setup()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Page root = Page.Root.CreatePage("BloodLab", Color.red, 0, true);
SetupGeneralPage(root);
SetupSplatPage(root);
SetupPoolPage(root);
}
private static void SetupGeneralPage(Page root)
{
//IL_0007: 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_0054: Unknown result type (might be due to invalid IL or missing references)
Page val = root.CreatePage("General", Color.white, 0, true);
val.CreateBool("Physical Droplets", Color.white, BloodLabPreferences.EnableDripping.Value, (Action<bool>)delegate(bool value)
{
BloodLabPreferences.EnableDripping.Value = value;
BloodLabPreferences.Save();
});
val.CreateBool("Impact Particles", Color.white, BloodLabPreferences.EnableParticles.Value, (Action<bool>)delegate(bool value)
{
BloodLabPreferences.EnableParticles.Value = value;
BloodLabPreferences.Save();
});
CreateAdjustableFloat(val, "Overall Intensity", BloodLabPreferences.Intensity, 0.1f, 0.1f, 3f);
CreateAdjustableInt(val, "Droplets Per Hit", BloodLabPreferences.DropletsPerHit, 2, 1, 30);
CreateAdjustableFloat(val, "Droplet Visual Size", BloodLabPreferences.DropletVisualScale, 0.01f, 0.02f, 0.3f);
}
private static void SetupSplatPage(Page root)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
Page page = root.CreatePage("Wall/Floor Splats", Color.white, 0, true);
CreateAdjustableInt(page, "Max Splats", BloodLabPreferences.MaxSplats, 10, 10, 500);
CreateAdjustableFloat(page, "Min Splat Size", BloodLabPreferences.MinSplatSize, 0.02f, 0.02f, 1f);
CreateAdjustableFloat(page, "Max Splat Size", BloodLabPreferences.MaxSplatSize, 0.02f, 0.02f, 1f);
}
private static void SetupPoolPage(Page root)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
Page page = root.CreatePage("Blood Pools", Color.white, 0, true);
CreateAdjustableInt(page, "Max Pools", BloodLabPreferences.MaxStains, 5, 1, 150);
CreateAdjustableFloat(page, "Max Pool Size", BloodLabPreferences.StainMaxSize, 0.05f, 0.1f, 2f);
CreateAdjustableFloat(page, "Growth Per Droplet", BloodLabPreferences.StainGrowthPerDroplet, 0.01f, 0.005f, 0.2f);
CreateAdjustableFloat(page, "Merge Radius", BloodLabPreferences.StainMergeRadius, 0.05f, 0.05f, 1.5f);
}
private static void CreateAdjustableFloat(Page page, string label, MelonPreferences_Entry<float> entry, float step, float min, float max)
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
FunctionElement display = page.CreateFunction($"{label}: {entry.Value:0.00}", Color.white, (Action)delegate
{
});
page.CreateFunction("- " + label, Color.yellow, (Action)delegate
{
entry.Value = Mathf.Clamp(entry.Value - step, min, max);
BloodLabPreferences.Save();
((Element)display).ElementName = $"{label}: {entry.Value:0.00}";
});
page.CreateFunction("+ " + label, Color.green, (Action)delegate
{
entry.Value = Mathf.Clamp(entry.Value + step, min, max);
BloodLabPreferences.Save();
((Element)display).ElementName = $"{label}: {entry.Value:0.00}";
});
}
private static void CreateAdjustableInt(Page page, string label, MelonPreferences_Entry<int> entry, int step, int min, int max)
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
FunctionElement display = page.CreateFunction($"{label}: {entry.Value}", Color.white, (Action)delegate
{
});
page.CreateFunction("- " + label, Color.yellow, (Action)delegate
{
entry.Value = Mathf.Clamp(entry.Value - step, min, max);
BloodLabPreferences.Save();
((Element)display).ElementName = $"{label}: {entry.Value}";
});
page.CreateFunction("+ " + label, Color.green, (Action)delegate
{
entry.Value = Mathf.Clamp(entry.Value + step, min, max);
BloodLabPreferences.Save();
((Element)display).ElementName = $"{label}: {entry.Value}";
});
}
}
public static class BloodLabPreferences
{
private static MelonPreferences_Category _category;
public static MelonPreferences_Entry<int> MaxSplats;
public static MelonPreferences_Entry<int> MaxDroplets;
public static MelonPreferences_Entry<int> MaxStains;
public static MelonPreferences_Entry<int> DropletsPerHit;
public static MelonPreferences_Entry<float> DropletVisualScale;
public static MelonPreferences_Entry<float> SplatLifetime;
public static MelonPreferences_Entry<float> DropletLifetime;
public static MelonPreferences_Entry<float> MinSplatSize;
public static MelonPreferences_Entry<float> MaxSplatSize;
public static MelonPreferences_Entry<float> StainMaxSize;
public static MelonPreferences_Entry<float> StainGrowthPerDroplet;
public static MelonPreferences_Entry<float> StainMergeRadius;
public static MelonPreferences_Entry<float> Intensity;
public static MelonPreferences_Entry<bool> EnableDripping;
public static MelonPreferences_Entry<bool> EnableParticles;
public static void Initialize()
{
_category = MelonPreferences.CreateCategory("BloodLab");
MaxSplats = _category.CreateEntry<int>("MaxSplats", 120, (string)null, "max number of splats", false, false, (ValueValidator)null, (string)null);
MaxDroplets = _category.CreateEntry<int>("MaxDroplets", 100, (string)null, "max number of droplets", false, false, (ValueValidator)null, (string)null);
MaxStains = _category.CreateEntry<int>("MaxStains", 40, (string)null, "max number of pools.", false, false, (ValueValidator)null, (string)null);
DropletsPerHit = _category.CreateEntry<int>("DropletsPerHit", 10, (string)null, "how many droplets spawn on wounds", false, false, (ValueValidator)null, (string)null);
DropletVisualScale = _category.CreateEntry<float>("DropletVisualScale", 0.05f, (string)null, "size of each droplet", false, false, (ValueValidator)null, (string)null);
SplatLifetime = _category.CreateEntry<float>("SplatLifetimeSeconds", 45f, (string)null, "time until a splat disappears", false, false, (ValueValidator)null, (string)null);
DropletLifetime = _category.CreateEntry<float>("DropletLifetimeSeconds", 12f, (string)null, "time until a droplet is recycled if it never lands", false, false, (ValueValidator)null, (string)null);
MinSplatSize = _category.CreateEntry<float>("MinSplatSize", 0.05f, (string)null, "min size of a splat.", false, false, (ValueValidator)null, (string)null);
MaxSplatSize = _category.CreateEntry<float>("MaxSplatSize", 0.35f, (string)null, "max size of a splat.", false, false, (ValueValidator)null, (string)null);
StainMaxSize = _category.CreateEntry<float>("StainMaxSize", 0.6f, (string)null, "max size a pool can grow to", false, false, (ValueValidator)null, (string)null);
StainGrowthPerDroplet = _category.CreateEntry<float>("StainGrowthPerDroplet", 0.03f, (string)null, "how much a pool grow every time a droplet lands in it", false, false, (ValueValidator)null, (string)null);
StainMergeRadius = _category.CreateEntry<float>("StainMergeRadius", 0.35f, (string)null, "how close a droplet gotta land to a pool to grow it instead of creating a new one", false, false, (ValueValidator)null, (string)null);
Intensity = _category.CreateEntry<float>("Intensity", 1f, (string)null, "blood intensity multiplier", false, false, (ValueValidator)null, (string)null);
EnableDripping = _category.CreateEntry<bool>("EnableDripping", true, (string)null, "toggle droplets", false, false, (ValueValidator)null, (string)null);
EnableParticles = _category.CreateEntry<bool>("EnableParticles", true, (string)null, "toggle impact particles", false, false, (ValueValidator)null, (string)null);
MelonLogger.Msg("[BloodLab] Preferences loaded.");
}
public static void Save()
{
MelonPreferences_Category category = _category;
if (category != null)
{
category.SaveToFile(false);
}
}
}
}
namespace BloodLab.Blood
{
[RegisterTypeInIl2Cpp]
public class BloodDecal : MonoBehaviour
{
private static Mesh _sharedQuadMesh;
private static Shader _cachedShader;
private static bool _shaderResolved;
private MeshRenderer _renderer;
private MaterialPropertyBlock _propertyBlock;
private float _timer;
private float _lifetime;
public BloodDecal(IntPtr ptr)
: base(ptr)
{
}
private void Awake()
{
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Expected O, but got Unknown
//IL_0093: 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_00a6: Expected O, but got Unknown
EnsureSharedMesh();
MeshFilter val = ((Component)this).GetComponent<MeshFilter>();
if ((Object)(object)val == (Object)null)
{
val = ((Component)this).gameObject.AddComponent<MeshFilter>();
}
val.sharedMesh = _sharedQuadMesh;
_renderer = ((Component)this).GetComponent<MeshRenderer>();
if ((Object)(object)_renderer == (Object)null)
{
_renderer = ((Component)this).gameObject.AddComponent<MeshRenderer>();
}
((Renderer)_renderer).shadowCastingMode = (ShadowCastingMode)0;
((Renderer)_renderer).receiveShadows = false;
Shader val2 = ResolveWorkingShader();
if ((Object)(object)val2 != (Object)null)
{
((Renderer)_renderer).sharedMaterial = new Material(val2)
{
hideFlags = (HideFlags)61
};
}
_propertyBlock = new MaterialPropertyBlock();
}
public void Setup(Vector3 position, Vector3 normal, Texture2D texture, float size)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: 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)
((Component)this).transform.position = SurfaceUtils.SafeOffset(position, normal, 0.008f);
((Component)this).transform.rotation = SurfaceUtils.AlignToNormal(normal);
((Component)this).transform.localScale = new Vector3(size, size, 1f);
if ((Object)(object)texture != (Object)null && (Object)(object)_renderer != (Object)null && (Object)(object)((Renderer)_renderer).sharedMaterial != (Object)null)
{
_propertyBlock.Clear();
((Renderer)_renderer).GetPropertyBlock(_propertyBlock);
_propertyBlock.SetTexture("_MainTex", (Texture)(object)texture);
((Renderer)_renderer).SetPropertyBlock(_propertyBlock);
}
_timer = 0f;
_lifetime = BloodLabPreferences.SplatLifetime.Value;
}
private void Update()
{
_timer += Time.deltaTime;
if (_timer >= _lifetime)
{
BloodEffectManager.ReleaseDecal(this);
}
}
private static Shader ResolveWorkingShader()
{
if (_shaderResolved)
{
return _cachedShader;
}
_shaderResolved = true;
string[] array = new string[4] { "Sprites/Default", "Unlit/Transparent", "Unlit/Texture", "UI/Default" };
string[] array2 = array;
foreach (string text in array2)
{
Shader val = Shader.Find(text);
if ((Object)(object)val != (Object)null)
{
_cachedShader = val;
MelonLogger.Msg("[BloodLab] using shader '" + text + "' for dem decals boy");
return _cachedShader;
}
}
Renderer val2 = Object.FindObjectOfType<Renderer>();
if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sharedMaterial != (Object)null && (Object)(object)val2.sharedMaterial.shader != (Object)null)
{
_cachedShader = val2.sharedMaterial.shader;
MelonLogger.Msg("[BloodLab] using '" + ((Object)_cachedShader).name + "' from an object in scene");
return _cachedShader;
}
MelonLogger.Warning("[BloodLab] no usable shader found, lookin for anotha one");
_shaderResolved = false;
return null;
}
private static void EnsureSharedMesh()
{
//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_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_0050: 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_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: 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_00e8: 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_00fe: 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)
if (!((Object)(object)_sharedQuadMesh != (Object)null))
{
_sharedQuadMesh = new Mesh
{
name = "BloodLab_QuadMesh",
hideFlags = (HideFlags)61
};
_sharedQuadMesh.vertices = Il2CppStructArray<Vector3>.op_Implicit((Vector3[])(object)new Vector3[4]
{
new Vector3(-0.5f, -0.5f, 0f),
new Vector3(0.5f, -0.5f, 0f),
new Vector3(0.5f, 0.5f, 0f),
new Vector3(-0.5f, 0.5f, 0f)
});
_sharedQuadMesh.uv = Il2CppStructArray<Vector2>.op_Implicit((Vector2[])(object)new Vector2[4]
{
new Vector2(0f, 0f),
new Vector2(1f, 0f),
new Vector2(1f, 1f),
new Vector2(0f, 1f)
});
_sharedQuadMesh.triangles = Il2CppStructArray<int>.op_Implicit(new int[6] { 0, 2, 1, 0, 3, 2 });
_sharedQuadMesh.RecalculateNormals();
_sharedQuadMesh.RecalculateBounds();
}
}
}
public static class BloodEffectManager
{
private static GameObject _root;
private static BloodEffectPool<BloodDecal> _groundSplatPool;
private static BloodEffectPool<BloodStain> _stainPool;
private static BloodEffectPool<BloodDroplet> _dropletPool;
private static readonly List<BloodStain> _activeStains = new List<BloodStain>();
public static void Initialize()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
_root = new GameObject("BloodLab_Runtime");
Object.DontDestroyOnLoad((Object)(object)_root);
_groundSplatPool = new BloodEffectPool<BloodDecal>(CreateGroundSplatInstance, BloodLabPreferences.MaxSplats.Value, _root.transform);
_stainPool = new BloodEffectPool<BloodStain>(CreateStainInstance, BloodLabPreferences.MaxStains.Value, _root.transform);
_dropletPool = new BloodEffectPool<BloodDroplet>(CreateDropletInstance, BloodLabPreferences.MaxDroplets.Value, _root.transform);
}
public static void HandleImpact(ImpactData data)
{
//IL_0059: 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_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
float intensity = data.Intensity * BloodLabPreferences.Intensity.Value;
if (data.IsLivingEntity)
{
Transform woundRoot = (((Object)(object)data.HitCollider != (Object)null) ? ((Component)data.HitCollider).transform.root : null);
DropletManager.HandleBleed(data.Position, data.Normal, intensity, woundRoot);
}
else
{
SpawnGroundSplat(data.Position, data.Normal, intensity, small: false);
}
}
public static void SpawnGroundSplat(Vector3 position, Vector3 normal, float intensity, bool small)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
Texture2D randomTexture = BloodTextureLibrary.GetRandomTexture(BloodTextureCategory.Blood);
if (!((Object)(object)randomTexture == (Object)null))
{
float value = BloodLabPreferences.MinSplatSize.Value;
float value2 = BloodLabPreferences.MaxSplatSize.Value;
float num = Random.Range(value, value2) * Mathf.Clamp01(intensity + 0.2f);
float size = (small ? (num * 0.6f) : num);
BloodDecal bloodDecal = _groundSplatPool.Get();
bloodDecal.Setup(position, normal, randomTexture, size);
}
}
public static void ReleaseDecal(BloodDecal decal)
{
_groundSplatPool.Release(decal);
}
public static void HandleDropletLanded(Vector3 groundPosition, Vector3 groundNormal)
{
//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_005a: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
float value = BloodLabPreferences.StainMergeRadius.Value;
float value2 = BloodLabPreferences.StainGrowthPerDroplet.Value;
float value3 = BloodLabPreferences.StainMaxSize.Value;
BloodStain bloodStain = null;
float num = value * value;
foreach (BloodStain activeStain in _activeStains)
{
if (!((Object)(object)activeStain == (Object)null))
{
Vector3 val = activeStain.WorldPosition - groundPosition;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
if (sqrMagnitude <= num)
{
num = sqrMagnitude;
bloodStain = activeStain;
}
}
}
if ((Object)(object)bloodStain != (Object)null)
{
bloodStain.Grow(value2, value3);
return;
}
Texture2D randomTexture = BloodTextureLibrary.GetRandomTexture(BloodTextureCategory.Stain);
if ((Object)(object)randomTexture == (Object)null)
{
MelonLogger.Warning("[BloodLab] No texture loaded in the 'Stain' category.");
return;
}
BloodStain bloodStain2 = _stainPool.Get();
bloodStain2.PlaceOnGround(groundPosition, groundNormal, randomTexture, value2);
_activeStains.Add(bloodStain2);
}
public static void ReleaseStain(BloodStain stain)
{
if ((Object)(object)stain == (Object)null)
{
return;
}
try
{
_activeStains.Remove(stain);
((Component)stain).transform.SetParent(_root.transform, false);
_stainPool.Release(stain);
}
catch
{
}
}
public static BloodDroplet GetDropletFromPool()
{
BloodDroplet bloodDroplet = _dropletPool.Get();
Texture2D randomTexture = BloodTextureLibrary.GetRandomTexture(BloodTextureCategory.Droplet);
bloodDroplet.SetTexture(randomTexture);
return bloodDroplet;
}
public static void ReleaseDroplet(BloodDroplet droplet)
{
_dropletPool.Release(droplet);
}
private static BloodDecal CreateGroundSplatInstance()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
GameObject val = new GameObject("BloodLab_GroundSplat");
val.AddComponent<MeshFilter>();
val.AddComponent<MeshRenderer>();
Component val2 = val.AddComponent(Il2CppType.Of<BloodDecal>());
return ((Il2CppObjectBase)val2).TryCast<BloodDecal>();
}
private static BloodStain CreateStainInstance()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
GameObject val = new GameObject("BloodLab_Pool");
val.AddComponent<MeshFilter>();
val.AddComponent<MeshRenderer>();
Component val2 = val.AddComponent(Il2CppType.Of<BloodStain>());
return ((Il2CppObjectBase)val2).TryCast<BloodStain>();
}
private static BloodDroplet CreateDropletInstance()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
GameObject val = new GameObject("BloodLab_Droplet");
val.AddComponent<MeshFilter>();
val.AddComponent<MeshRenderer>();
Component val2 = val.AddComponent(Il2CppType.Of<BloodDroplet>());
return ((Il2CppObjectBase)val2).TryCast<BloodDroplet>();
}
}
public class BloodEffectPool<T> where T : Component
{
private readonly Stack<T> _available = new Stack<T>();
private readonly List<T> _all = new List<T>();
private readonly Func<T> _factory;
private readonly int _maxSize;
private readonly Transform _root;
public int ActiveCount => _all.Count - _available.Count;
public BloodEffectPool(Func<T> factory, int maxSize, Transform root)
{
_factory = factory;
_maxSize = maxSize;
_root = root;
}
public T Get()
{
T val;
if (_available.Count > 0)
{
val = _available.Pop();
}
else if (_all.Count < _maxSize)
{
val = _factory();
((Component)val).transform.SetParent(_root, false);
_all.Add(val);
}
else
{
val = _all[0];
_all.RemoveAt(0);
_all.Add(val);
}
((Component)val).gameObject.SetActive(true);
return val;
}
public void Release(T instance)
{
if (!((Object)(object)instance == (Object)null))
{
((Component)instance).gameObject.SetActive(false);
if (!_available.Contains(instance))
{
_available.Push(instance);
}
}
}
}
public enum BloodTextureCategory
{
Blood,
Droplet,
Stain
}
public static class BloodTextureLibrary
{
private static readonly string[] SupportedExtensions = new string[3] { ".png", ".jpg", ".jpeg" };
private static readonly Dictionary<BloodTextureCategory, string> FolderNames = new Dictionary<BloodTextureCategory, string>
{
{
BloodTextureCategory.Blood,
"Blood"
},
{
BloodTextureCategory.Droplet,
"Droplet"
},
{
BloodTextureCategory.Stain,
"Stain"
}
};
private static readonly Dictionary<BloodTextureCategory, List<Texture2D>> _texturesByCategory = new Dictionary<BloodTextureCategory, List<Texture2D>>();
public static void Initialize()
{
string text = Path.Combine(MelonEnvironment.UserDataDirectory, "BLOODLAB");
foreach (BloodTextureCategory key in FolderNames.Keys)
{
_texturesByCategory[key] = new List<Texture2D>();
}
Reload();
}
public static void Reload()
{
foreach (BloodTextureCategory key in FolderNames.Keys)
{
ReloadCategory(key);
}
}
private static void ReloadCategory(BloodTextureCategory category)
{
string text = Path.Combine(MelonEnvironment.UserDataDirectory, "BLOODLAB", FolderNames[category]);
if (!_texturesByCategory.TryGetValue(category, out var value))
{
value = new List<Texture2D>();
_texturesByCategory[category] = value;
}
foreach (Texture2D item in value)
{
if ((Object)(object)item != (Object)null)
{
Object.Destroy((Object)(object)item);
}
}
value.Clear();
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
MelonLogger.Warning("[BloodLab] textures folder made in '" + text + "'. put your images there boy");
return;
}
string[] files = Directory.GetFiles(text);
string[] array = files;
foreach (string path in array)
{
string value2 = Path.GetExtension(path).ToLowerInvariant();
if (Array.IndexOf(SupportedExtensions, value2) >= 0)
{
Texture2D val = LoadTexture(path);
if ((Object)(object)val != (Object)null)
{
((Object)val).name = Path.GetFileNameWithoutExtension(path);
value.Add(val);
}
}
}
MelonLogger.Msg($"[BloodLab] {value.Count} textures loaded to '{category}' from '{text}'.");
}
private static Texture2D LoadTexture(string path)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Expected O, but got Unknown
try
{
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
Il2CppStructArray<byte> val2 = Il2CppStructArray<byte>.op_Implicit(array);
if (!ImageConversion.LoadImage(val, val2))
{
MelonLogger.Warning("[BloodLab] we cant decode '" + path + "'");
Object.Destroy((Object)(object)val);
return null;
}
((Texture)val).wrapMode = (TextureWrapMode)1;
((Object)val).hideFlags = (HideFlags)61;
return val;
}
catch (Exception value)
{
MelonLogger.Error($"[BloodLab] texture failed to load '{path}': {value}");
return null;
}
}
public static Texture2D GetRandomTexture(BloodTextureCategory category)
{
if (!_texturesByCategory.TryGetValue(category, out var value) || value.Count == 0)
{
return null;
}
return value[Random.Range(0, value.Count)];
}
}
}